06: 电话拨号
使用系统自带意图对象完成:
Intent intent=new Intent();
intent.setAction("android.intent.action.Call");
intent.setData(Uri.parse("tel:"+i));
startActivity(Intent);
权限:
<uses-permission android:name="android.permission.CALL_PHONE"/>
08:短信发送
使用系统类
SmsManager manager = SmsManager.getDefault();
manager.sendTextMessage(phonenumber, null, content, null, null);
权限:
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>//发送短信
09: 布局技术
LinearLayout(线性布局),RelativeLayout(相对布局),TableLayout(表格布局),FrameLayout(帧布局)
10:单元测试
得到单元测试框架:
<manifest>
<application>
<activity/>
<uses-library android:name="android.test.runner"/>
</application>
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.xiaoqiang" />
</manifest>
11: 文件操作
使用上下文获取文件输入输出对象---(Context可在继承了Activity的类中使用getApplicationContext()方法获取);
Context context=getApplicationContext();
FileOutputStream outStream=context.openFileOutput(filename, Context.MODE_PRIVATE);//第二个参数为操作模式
outStream.write(content.getBytes());
outStream.close();
14:保存文件到SD卡:操作时候需要获取SD的状态,使用Environment.getExternalStorageState();
File file=new File(new File("/mnt/sdcard"),filename); //new File("/mnt/sdcard")可使用Environment.getExternalStorageDirectory();获取
FileOutputStream outStream=new FileOutputStream(file);
outStream.write(new String("ss").getBytes());
outStream.close();
权限:
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /><!--创建与删除文件-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!--写入数据-->
15:pull操作XML
得到pull解析器
XmlPullParser P=XmlPullParserFactory.newInstance().newPullParser(); //或者使用android.util.Xml.newPullParser();
P.setInput(inputStream,"UTF-8");
得到xml序列化器
XmlSerializer ser=Xml.newSerializer();
ser.setOutput(outputStream,"UTF-8")
16: SharedPreferences(偏好参数保存)
保存:
SharedPreferences preferences=getApplicationContext().getSharedPreferences("filename", Context.MODE_PRIVATE);
android.content.SharedPreferences.Editor editor=preferences.edit();
editor.putString("name","xiaoqiang");
editor.putString("sex","male");
editor.commit();
读取:
public Map<String, String> getPreferences() {
Map<String, String> params=new HashMap<String, String>();
SharedPreferences preferences = getApplicationContext()
.getSharedPreferences("filename", Context.MODE_PRIVATE);
params.put("name",preferences.getString("name", "")); //getString 的第二参数表示不存在该参数时返回默认值
return params;
}
17: SQLite数据库
基础:
支持数据类型:NULL,INTEGER,REAL(浮点),TEXT,BLOB(二进制数据对象)
可以把任意数据类型保存到任意字段中,如TEXT文本写入到integer字段中,如声明20个字符,可以保存超过20个字符 ::主键除(Integer)
CREATE TABLE person (persionid integer primary key autoincrement,name varchar(20))
分页技术: select * from Table limit 5 offset 3或者select * from Table limit 3,5
获取自增加的ID值:SELECT last_insert_rowid()
使用:
1、新建DBOpenHelpter类extends SQLiteOpenHelper类
package com.xiaoqiang.service;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBOpenHelpter extends SQLiteOpenHelper {
public DBOpenHelpter(Context context) {
// content 上下文
// name 数据名字
// CursorFactory 游标
// version 数据库版本号
super(context, "xiaoqiang.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
// 数据库第一次被创建的时候调用
String sql = "CREATE TABLE person(persionid integer primary key autoincrement,name varchar(20))";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {
// 数据库文件的版本号发生改变时调用
// String sql = "ALTER TABLE person RENAME COLUMN persionid to personid"; //修改表结构
// db.execSQL(sql);
}
}
2、创建业务类实现增删改查
package com.xiaoqiang.service;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.xiaoqiang.domain.Person;
public class PersonService {
private DBOpenHelpter deDbOpenHelpter;
public PersonService(Context context) {
this.deDbOpenHelpter = new DBOpenHelpter(context);
}
public void save(Person person) {
// 拥有缓存特点
SQLiteDatabase db = deDbOpenHelpter.getWritableDatabase();
db.execSQL("insert into person(name,phone) values(?,?)", new Object[] {
person.getName(), person.getPhone() });
}
public void delete(Integer id) {
SQLiteDatabase db = deDbOpenHelpter.getWritableDatabase();
db.execSQL("delete from person where persionid=?", new Object[] { id });
}
public void update(Person person) {
SQLiteDatabase db = deDbOpenHelpter.getWritableDatabase();
db.execSQL(
"update person set name=?,phone=? where persionid=?",
new Object[] { person.getName(), person.getPhone(),
person.getId() });
}
public Person find(Integer id) {
SQLiteDatabase db = deDbOpenHelpter.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from person where persionid=?",
new String[] { id.toString() });
if (cursor.moveToFirst()) {
int personid = cursor.getInt(cursor.getColumnIndex("persionid"));
String personname = cursor.getString(cursor.getColumnIndex("name"));
String personphone = cursor.getString(cursor
.getColumnIndex("phone"));
return new Person(personid, personname, personphone);
}
cursor.close();
return null;
}
public List<Person> getScrollData(int offset, int maxResult) {
List<Person> persons = new ArrayList<Person>();
SQLiteDatabase db = deDbOpenHelpter.getReadableDatabase();
Cursor cursor = db.rawQuery(
"select * from person order by persionid asc limit ?,?",
new String[] { String.valueOf(offset),
String.valueOf(maxResult) });
while (cursor.moveToNext()) {// 移到下一条记录
int personid = cursor.getInt(cursor.getColumnIndex("persionid"));
String personname = cursor.getString(cursor.getColumnIndex("name"));
String personphone = cursor.getString(cursor
.getColumnIndex("phone"));
persons.add(new Person(personid, personname, personphone));
}
cursor.close();
return persons;
}
public long getcount() {
SQLiteDatabase db = deDbOpenHelpter.getReadableDatabase();
Cursor cursor = db.rawQuery("select count(*) from person", null);
cursor.moveToFirst();
long result = cursor.getLong(0);
cursor.close();
return result;
}
}
3、创建数据抽象类(bean)
package com.xiaoqiang.domain;
public class Person {
private Integer id;
private String name;
private String phone;
public Person() {
}
public Person(String name, String phone) {
this.name = name;
this.phone = phone;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", phone=" + phone + "]";
}
public Person(Integer id, String name, String phone) {
this.id = id;
this.name = name;
this.phone = phone;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
4、测试类
package com.xiaoqiang.test;
import java.util.List;
import android.test.AndroidTestCase;
import android.util.Log;
import com.xiaoqiang.domain.Person;
import com.xiaoqiang.service.DBOpenHelpter;
import com.xiaoqiang.service.PersonService;
public class PersonServiceTest extends AndroidTestCase {
public void testCreateDB() throws Exception {
DBOpenHelpter dbOpenHelpter = new DBOpenHelpter(getContext());
dbOpenHelpter.getReadableDatabase();
}
public void testSave() throws Exception {
PersonService service = new PersonService(this.getContext());
for (int i = 0; i < 20; i++) {
service.save(new Person("xiaoqiang" + i, "123"));
}
}
public void testFind() {
PersonService service = new PersonService(this.getContext());
Person person = service.find(1);
Log.i("aaa", person.toString());
}
public void testupdate() {
PersonService service = new PersonService(this.getContext());
Person person = service.find(1);
person.setName("niexiaoqiang");
person.setPhone("18684033128");
service.update(person);
person = service.find(1);
Log.i("aaa", person.toString());
}
public void testcount() {
PersonService service = new PersonService(this.getContext());
long result = service.getcount();
Log.i("aaa", result + "");
}
public void testdelete() {
PersonService service = new PersonService(this.getContext());
service.delete(4);
Log.i("aaa", service.getcount() + "");
}
public void testScrollData() {
PersonService service = new PersonService(this.getContext());
List<Person> persons = service.getScrollData(0, 5);
for (Person person : persons) {
Log.i("aaa", person.toString() + "");
}
}
}
18: 事务
模拟转账
public void paymoney(Integer payid, Integer paymoney, Integer getid) {
SQLiteDatabase db = deDbOpenHelpter.getReadableDatabase();
String paysql = "update person set money=money-? where persionid=?";
String getsql = "update person set money=money+? where persionid=?";
db.beginTransaction();
try {
db.execSQL(paysql, new Object[] { paymoney, payid });
db.execSQL(getsql, new Object[] { paymoney, getid });
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
19: listview
界面显示:
1、listview中每行数据的Item界面
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" >
<TextView android:layout_width="100dp" android:layout_height="wrap_content" android:textSize="30sp" android:id="@+id/name" />
<TextView android:layout_width="150dp" android:layout_height="wrap_content" android:textSize="30sp" android:id="@+id/phone" />
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="30sp" android:id="@+id/money"/>
</LinearLayout>
2、主界面
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" >
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView android:id="@+id/name" android:layout_width="100dp"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="name" />
<TextView android:id="@+id/phone" android:layout_width="150dp"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="phone" />
<TextView android:id="@+id/money" android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="30sp"
android:text="money" />
</LinearLayout>
<ListView android:id="@+id/listView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
加载控件
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
personservice = new PersonService(this);
listView = (ListView) this.findViewById(R.id.listView);
listView.setOnItemClickListener(new ItemClickListener());
show3();//加载数据
//show();//加载数据
}
//定义ITEM点击事件监听器
private final class ItemClickListener implements OnItemClickListener {
@Override
// 1,当前点击条目所在的listview,2、当前点击的条目的view对象,3、当前点击条目在集合中德索引值,4、item在listview中德排列ID
public void onItemClick(AdapterView<?> parent, View view,
int personsIndex, long itemWithListviewID) {
ListView lView = (ListView) parent;
Person person = (Person) lView.getItemAtPosition(personsIndex);
Toast.makeText(getApplicationContext(), person.getId().toString(),
1).show();
}
}
//使用自定义设配器加载数据
private void show3() {
List<Person> persons = personservice.getScrollData(0, 10);
PersonAdapter adapter = new PersonAdapter(this, persons,
R.layout.data_item);
listView.setAdapter(adapter);
}
// 使用系统SimpleAdapter加载数据
private void show() {
List<Person> persons = personservice.getScrollData(0, 10);
List<HashMap<String, Object>> data = new ArrayList<HashMap<String, Object>>();
for (Person person : persons) {
HashMap<String, Object> item = new HashMap<String, Object>();
item.put("name", person.getName());
item.put("id", person.getId());
item.put("phone", person.getPhone());
item.put("money", person.getMoney());
data.add(item);
}
// 适配器
SimpleAdapter adapter = new SimpleAdapter(this, data,
R.layout.data_item, new String[] { "name", "phone", "money" },
new int[] { R.id.name, R.id.phone, R.id.money });
listView.setAdapter(adapter);
}
3、自定义适配器
package com.xiaoqiang.adapter;
import java.util.List;
import com.xiaoqiang.db.R;
import com.xiaoqiang.domain.Person;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class PersonAdapter extends BaseAdapter {
private List<Person> persons;
private int resource;
private LayoutInflater inflater; //安卓自带服务
public PersonAdapter(Context context, List<Person> persons, int resource) {
this.persons = persons;
this.resource = resource;
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return persons.size();
}
@Override
public Object getItem(int position) {
return persons.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convetView, ViewGroup parent) {
TextView nameview = null;
TextView phoneview = null;
TextView moneyview = null;
if (convetView == null) { //判断convetView是否为空,代表是否为第一次加载
convetView = inflater.inflate(resource, null);
nameview = (TextView) convetView.findViewById(R.id.name);
phoneview = (TextView) convetView.findViewById(R.id.phone);
moneyview = (TextView) convetView.findViewById(R.id.money);
ViewCache viewCache = new ViewCache();
viewCache.nameview = nameview;
viewCache.phoneview = phoneview;
viewCache.moneyview = moneyview;
convetView.setTag(viewCache);
} else {
ViewCache cache = (ViewCache) convetView.getTag();
nameview = cache.nameview;
phoneview = cache.phoneview;
moneyview = cache.moneyview;
}
Person person = persons.get(position);
nameview.setText(person.getName());
phoneview.setText(person.getPhone());
moneyview.setText(person.getMoney().toString());
return convetView;
}
private final class ViewCache {
public TextView nameview;
public TextView phoneview;
public TextView moneyview;
}
}
20、内容提供者(Content provider):对外共享数据,其他应用可以通过内容提供者访问程序数据
Tag:创建后需要在清单文件中列出,好处:统一数据访问方式
Tag:需要在应用的包或者子包中生命组建
创建内容提供者
package com.xiaoqiang.db;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import com.xiaoqiang.service.DBOpenHelpter;
public class PersonProvider extends ContentProvider {
private DBOpenHelpter dbOpenHelpter;
private static final UriMatcher MATHCER = new UriMatcher(-1);
static {
MATHCER.addURI("com.xiaoqiang.personprovider", "person", 1);
MATHCER.addURI("com.xiaoqiang.personprovider", "person/#", 2); // #代表数字
}
@Override
public boolean onCreate() {
dbOpenHelpter = new DBOpenHelpter(this.getContext());
return true;
}
@Override
public int delete(Uri uri, String selection, String[] selectionarg) {
SQLiteDatabase db = dbOpenHelpter.getWritableDatabase();
int num = 0;
// 判断url是否为合法路径
switch (MATHCER.match(uri)) {
case 1:
num = db.delete("person", selection, selectionarg);
break;
case 2:
long rowid = ContentUris.parseId(uri);
String where = "persionid=" + rowid;
if (selection != null && "".equals(selection.trim())) {
where += " and " + selection;
}
num = db.delete("person", where, selectionarg);
break;
default:
throw new IllegalAccessError("this is unknown url");
}
return num;
}
@Override
public String getType(Uri uri) {
switch (MATHCER.match(uri)) {
case 1:
return "vnd.android.cursor.dir/person";//规定vnd.android.cursor.dir
case 2:
return "vnd.android.cursor.item/person";//规定vnd.android.cursor.item
default:
throw new IllegalAccessError("this is unknown url");
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = dbOpenHelpter.getWritableDatabase();
// 判断url是否为合法路径
switch (MATHCER.match(uri)) {
case 1:
long rowid = db.insert("person", "name", values);
// Uri insetUri=ContentUris.withAppendedId(uri, rowid);
Uri insetUri = Uri
.parse("content://com.xiaoqiang.personprovider/person/"
+ rowid);
return insetUri;
default:
throw new IllegalAccessError("this is unknown url");
}
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String orderBy) {
SQLiteDatabase db = dbOpenHelpter.getReadableDatabase();
// 判断url是否为合法路径
switch (MATHCER.match(uri)) {
case 1:
return db.query("person", projection, selection, selectionArgs,
null, null, orderBy);
case 2:
long rowid = ContentUris.parseId(uri);
String where = "persionid=" + rowid;
if (selection != null && "".equals(selection.trim())) {
where += " and " + selection;
}
return db.query("person", projection, where, selectionArgs, null,
null, orderBy);
default:
throw new IllegalAccessError("this is unknown url");
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionarg) {
SQLiteDatabase db = dbOpenHelpter.getWritableDatabase();
int num = 0;
// 判断url是否为合法路径
switch (MATHCER.match(uri)) {
case 1:
num = db.update("person", values, selection, selectionarg);
break;
case 2:
long rowid = ContentUris.parseId(uri);
String where = "persionid=" + rowid;
if (selection != null && "".equals(selection.trim())) {
where += " and " + selection;
}
num = db.update("person", values, where, selectionarg);
break;
default:
throw new IllegalAccessError("this is unknown url");
}
return num;
}
}
使用内容提供者
package com.xiaoqiang.db.test;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.test.AndroidTestCase;
import android.util.Log;
public class AccessContentproviderTest extends AndroidTestCase {
public void testInsert() throws Exception {
Uri uri = Uri.parse("content://com.xiaoqiang.personprovider/person");
ContentResolver contentResolver = this.getContext()
.getContentResolver();
ContentValues values = new ContentValues();
values.put("name", "xiaoqiang123");
values.put("phone", "183439834");
values.put("money", "183000000");
contentResolver.insert(uri, values);
}
public void testDelete() throws Exception {
Uri uri = Uri.parse("content://com.xiaoqiang.personprovider/person/20");
ContentResolver contentResolver = this.getContext()
.getContentResolver();
contentResolver.delete(uri, null, null);
}
public void testUpdate() throws Exception {
Uri uri = Uri.parse("content://com.xiaoqiang.personprovider/person/2");
ContentResolver contentResolver = this.getContext()
.getContentResolver();
ContentValues values = new ContentValues();
values.put("name", "aaa");
contentResolver.update(uri, values, null, null);
}
public void testquray() throws Exception {
Uri uri = Uri.parse("content://com.xiaoqiang.personprovider/person");
ContentResolver contentResolver = this.getContext()
.getContentResolver();
Cursor cursor = contentResolver.query(uri, null, null, null, null);
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex("name"));
Log.i("aaa", name);
}
}
}
21、监听内容提供者中的数据变化
场景:A应用更新了内容提供者的数据,B应用需要马上知道
1、在内容提供者数据变化方法内新增:
如在insert中新增:this.getContext().getContentResolver().notifyChange(uri, null); //发出数据变化通知
2、 在应用中注册数据变化监听器 (在应该程序主界面【创建(onCreate)】方法中注册)
Uri uri = Uri.parse("content://com.xiaoqiang.personprovider/person");
this.getContentResolver().registerContentObserver(uri, true,
new PersonContentOberver(new Handler()));// 第三个参数为监听对象
3、创建监听对象类
private class PersonContentOberver extends ContentObserver {
@Override
// 该刚发只能知道发生了改变,不知道具体内容
public void onChange(boolean selfChange) {
// select * from person order by persionid desc limit 1
Uri uri = Uri
.parse("content://com.xiaoqiang.personprovider/person");
Cursor cursor = getContentResolver().query(uri, null, null, null,
"persionid desc limit 1");
if (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex("name"));
Log.i("aaa", name);
}
}
public PersonContentOberver(Handler handler) {
super(handler);
}
}
22、访问通讯录和添加联系人
通讯录内容提供者uri:ContactsProvider2或者com.android.contacts 读写权限:android.permission.READ_CONTACTS,android.permission.WRITE_CONTACTS
呼叫记录内容提供者uri:CallLogProvider 读写权限:android.permission.READ_CONTACTS,android.permission.WRITE_CONTACTS
使用测试方法向手机中添加和查找联系人:
package com.xiaoqiang.test;
import java.util.ArrayList;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.test.AndroidTestCase;
import android.util.Log;
public class ContactsTest extends AndroidTestCase {
public void testGetContacts() throws Exception {
Uri uri = Uri.parse("content://com.android.contacts/contacts");
ContentResolver resolver = getContext().getContentResolver();
Cursor cursor = resolver.query(uri, new String[] { "_id" }, null, null,
null);
while (cursor.moveToNext()) {
int contactid = cursor.getInt(0);
StringBuilder sb = new StringBuilder("contactid=");
sb.append(contactid);
uri = Uri.parse("content://com.android.contacts/contacts/"
+ contactid + "/data");
Cursor datacursor = resolver.query(uri, new String[] { "mimetype",
"data1", "data2" }, null, null, null);
while (datacursor.moveToNext()) {
String data = datacursor.getString(datacursor
.getColumnIndex("data1"));
String type = datacursor.getString(datacursor
.getColumnIndex("mimetype"));
if ("vnd.android.cursor.item/name".equals(type)) {
sb.append(",name=" + data);
} else if ("vnd.android.cursor.item/email_v2".equals(type)) {
sb.append(",email=" + data);
} else if ("vnd.android.cursor.item/phone_v2".equals(type)) {
sb.append(",phone=" + data);
}
}
Log.i("aaa", sb.toString());
}
}
/**
* @function 测试根据号码获取联系人姓名
* @throws Exception
*/
public void testGetContactsNamebyNumber() throws Exception {
String number = "18684033128";
Uri uri = Uri
.parse("content://com.android.contacts/data/phones/filter/"
+ number);
ContentResolver resolver = getContext().getContentResolver();
Cursor cursor = resolver.query(uri, new String[] { "display_name" },
null, null, null);
if (cursor.moveToFirst()) {
String name = cursor.getString(0);
Log.i("aaa", name);
}
}
/**
* @fuction 添加联系人
* @throws Exception
*/
public void testAddContact() throws Exception {
Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
ContentResolver resolver = getContext().getContentResolver();
ContentValues values = new ContentValues();
long contactid = ContentUris.parseId(resolver.insert(uri, values));
// 添加姓名
Uri datauri = Uri.parse("content://com.android.contacts/data");
values.put("raw_contact_id", contactid);
values.put("mimetype", "vnd.android.cursor.item/name");
values.put("data2", "xiaoqiang1");
resolver.insert(datauri, values);
// 添加电话
values.clear();
values.put("raw_contact_id", contactid);
values.put("mimetype", "vnd.android.cursor.item/phone_v2");
values.put("data1", "110");
values.put("data2", "2");
resolver.insert(datauri, values);
// 添加email
values.clear();
values.put("raw_contact_id", contactid);
values.put("mimetype", "vnd.android.cursor.item/email_v2");
values.put("data1", "[email protected]");
values.put("data2", "2");
resolver.insert(datauri, values);
}
/**
* @fuction 添加联系人 在同一个事务中完成联系人的添加
* @throws Exception
*/
public void testAddContact2() throws Exception {
Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
ContentResolver resolver = getContext().getContentResolver();
ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();
ContentProviderOperation op1 = ContentProviderOperation.newInsert(uri)
.withValue("account_name", null).build();
operations.add(op1);
Uri datauri = Uri.parse("content://com.android.contacts/data");
ContentProviderOperation op2 = ContentProviderOperation
.newInsert(datauri).withValueBackReference("raw_contact_id", 0)
.withValue("mimetype", "vnd.android.cursor.item/name")
.withValue("data2", "xiaoqiang2").build();// 0为执行第0操作对象(插入)后返回的ID值
operations.add(op2);
ContentProviderOperation op3 = ContentProviderOperation
.newInsert(datauri).withValueBackReference("raw_contact_id", 0)
.withValue("mimetype", "vnd.android.cursor.item/phone_v2")
.withValue("data1", "119").withValue("data2", "2").build();// 0为执行第0操作对象(插入)后返回的ID值
operations.add(op3);
ContentProviderOperation op4 = ContentProviderOperation
.newInsert(datauri).withValueBackReference("raw_contact_id", 0)
.withValue("mimetype", "vnd.android.cursor.item/email_v2")
.withValue("data1", "[email protected]").withValue("data2", "2")
.build();// 0为执行第0操作对象(插入)后返回的ID值
operations.add(op4);
resolver.applyBatch("com.android.contacts", operations);
}
}
23、网络通信
1、获取web应用中的图片信息
URL url = new URL("path");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if (conn.getResponseCode() == 200) {
InputStream in = conn.getInputStream();
byte[] data=read(in);
Bitmap bitmap=BitmapFactory.decodeByteArray(data, 0, data.length);
imageview.setImageBitmap(bitmap);
}
private static byte[] read(InputStream in) throws Exception {
ByteArrayOutputStream out=new ByteArrayOutputStream();
byte[] buffer=new byte[1024];
int len=0;
while((len=in.read(buffer))!=-1)
{
out.write(buffer,0,len);
}
in.close();
return out.toByteArray();
}
2、24-27视频资料,j2ee 未做笔记
3、28-32视频资料,文件上传下载 未学习
33、为应用添加多个Activity与参数传递
1、激活activity的方法
1)、激活activity
private void openActivy(View v) {
Intent intent = new Intent();
intent.setClass(this, OtherActivity.class); //显示意图
startActivity(intent);
}
2)、激活activity
private void openActivy(View v) {
Intent intent = new Intent();
intent.setClassName(this, "com.xiaoqiang.mulactivity.OtherActivity");
startActivity(intent);
}
3)、激活activity
private void openActivy(View v) {
Intent intent = new Intent();
intent.setComponent(new ComponentName(this, OtherActivity.class));
startActivity(intent);
}
4)、激活activity (跨应用激活组件)
private void openActivy(View v) {
Intent intent = new Intent();
intent.setClassName("com.xiaoqiang.mulactivity", "com.xiaoqiang.mulactivity.OtherActivity")
startActivity(intent);
}
2、参数传递
1、单参数传递
private void openActivy(View v) {
Intent intent = new Intent();
intent.setClassName("com.xiaoqiang.mulactivity", "com.xiaoqiang.mulactivity")
intent.putExtra("xiaoqiang","aaa");
startActivity(intent);
}
其他ativitity中获取
Intent intent =getIntent();
intent.getStringExtra("xiaoqiang");
2、使用Bundle类设置参数
private void openActivy(View v) {
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putString("xiaoqiang", "aaa");
bundle.putInt("xiaoqiang1", 1);
intent.putExtras(bundle);
startActivity(intent);
}
其他ativitity中获取
Intent intent = getIntent();
Bundle bundle=intent.getExtras();
String key1=bundle.getString("xiaoqiang");
int key2=bundle.getInt(("xiaoqiang1"));
3、activity关闭时候传递回参数
private void openActivy(View v) {
Intent intent = new Intent();
intent.setComponent(new ComponentName(this, OtherActivity.class));
startActivityForResult(intent, 200); //200为请求码,用于区分结果数据
}
@Override//当有结果数据返回时调用
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
System.out.println(requestCode); // 来自请求码
System.out.println(resultCode); // 来自返回码
System.out.println(data.getStringExtra("result"));
super.onActivityResult(requestCode, resultCode, data);
}
其他ativity
Intent data = new Intent();
data.putExtra("result", "xiaoqiang");
setResult(30, data);
34、Activity的启动模式
1、清单文件中修改activity启动模式,standard,singleTop,singleTask,singleInstance
<activity
android:name="com.xiaoqiang.mulactivity.MainActivity"
android:label="@string/app_name"
android:launchMode="standard" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
注:standard 每一次激活都创建一个新的实例
singleTop 如果该activity实例在栈顶,那么将不再创建实例
singleTask 在应用中只启动一个,并且当打开这个后会关闭在这个activity实例栈上面的所有实例
singleInstance 在系统中只打开一个实例
34:、Intent意图(高级)
1、激活的组件包括。activity ,服务,广播接收者
2、显示意图和隐式意图
1、
2、隐式意图:没有明确指定组件名称 根据三个参数(动作,类别,数据(URL类型))来匹配
1、例一:
1、清单文件中为activity添加过滤器
<activity android:name=".OtherActivity" android:label="xiaoqiang">
<intent-filter>
<action android:name="com.xiaoqiang.xiaoqiang"/>
<category android:name="com.xiaoqiang.leibie"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
2、隐式激活activity实例
private void openActivy(View v) {
Intent intent = new Intent();
intent.setAction("com.xiaoqiang.xiaoqiang");
intent.addCategory("com.xiaoqiang.leibie");
startActivity(intent);//默认会添加类别"android.intent.category.DEFAULT"
}
2、例二: 只要intent中的动作和类别都出现在意图过滤器中就能与之匹配
1、清单文件中为activity添加过滤器
<activity android:name=".OtherActivity" android:label="xiaoqiang">
<intent-filter>
<action android:name="com.xiaoqiang.xiaoqiang"/>
<action android:name="com.xiaoqiang.da"/>
<category android:name="com.xiaoqiang.leibie"/>
<category android:name="com.xiaoqiang.aaaa"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
2、隐式激活activity实例
private void openActivy(View v) {
Intent intent = new Intent();
intent.setAction("com.xiaoqiang.xiaoqiang");
intent.addCategory("com.xiaoqiang.leibie");
startActivity(intent);//默认会添加类别"android.intent.category.DEFAULT"
}
3、例三: 匹配数据
1、清单文件中为activity添加过滤器
<activity android:name=".OtherActivity" android:label="xiaoqiang">
<intent-filter>
<action android:name="com.xiaoqiang.xiaoqiang"/>
<category android:name="com.xiaoqiang.leibie"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="xiaoqiang" android:host="www.xiaoqiang.com"/>
</intent-filter>
</activity>
2、隐式激活activity实例
private void openActivy(View v) {
Intent intent = new Intent();
intent.setAction("com.xiaoqiang.xiaoqiang");
intent.addCategory("com.xiaoqiang.leibie");
intent.setData(Uri.parse("xiaoqiang://www.xiaoqiang.com"));
startActivity(intent);// 默认会添加类别"android.intent.category.DEFAULT"
}
4、例四: 匹配数据和类型
1、清单文件中为activity添加过滤器
<activity android:name=".OtherActivity" android:label="xiaoqiang">
<intent-filter>
<action android:name="com.xiaoqiang.xiaoqiang"/>
<category android:name="com.xiaoqiang.leibie"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="xiaoqiang" android:host="www.xiaoqiang.com"/>
<data android:mimeType="image/*"/>
</intent-filter>
</activity>
2、隐式激活activity实例
private void openActivy(View v) {
Intent intent = new Intent();
intent.setAction("com.xiaoqiang.xiaoqiang");
intent.addCategory("com.xiaoqiang.leibie");
intent.setDataAndType((Uri.parse("xiaoqiang://www.xiaoqiang.com")),"image/type");
/*不能使用下面的方法设置数据和类型,因为setType会清空data商检局
intent.setData(Uri.parse("xiaoqiang://www.xiaoqiang.com"));
intent.setType("image/type");
*/
startActivity(intent);// 默认会添加类别"android.intent.category.DEFAULT"
}
35、activity的生命周期
1、生命周期方法
onCreate(Bundle savedInstanceState)
onStart();
onRestart();
onResume();
onPause();
onStop();
onDestroy();
2、非生命周期方法 ,处理突发事件方法,如内存不足,直接按home键,屏幕方向被改变的时候也会被摧毁,并且重新创建
1、onSaveInstanceState(); //摧毁之前保存一些需要数据
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putString("xiaoqiang", "摧毁之前的数据保存");
super.onSaveInstanceState(outState);
}
1、onRestoreInstanceState(); //重新创建后可以获取budndle对象中的值
@Override
protected void onRestoreInstanceState(Bundle saveInstanceState) {
name=saveInstanceState.getString("xiaoqiang", "摧毁之前的数据保存");
super.onRestoreInstanceState(outState);
}
3、当屏幕方向发生改变或者键盘显示/隐藏时候都会摧毁当前activity,如果不希望重新创建则配置如下
<activity android:name=".OtherActivity"
android:configChanges="keyboardHidden|orientation"
android:label="xiaoqiang">
4、应用的响应性
操作比较复杂时最后在子线程中完成
37、广播接收者(采用广播接收者实现短信接收)
1、清单文件中添加
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<service android:name=".SMSBroadcastReceiver" >
<!-- 定义广播 -->
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</service>
</application>
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.INTERNET" />
2、接收短信
package com.xiaoqiang.smsLinsener;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.sql.Date;
import java.text.SimpleDateFormat;
import android.R.bool;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.telephony.SmsMessage;
public class SMSBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Object[] pdus = (Object[]) intent.getExtras().get("pdus");
for (Object p : pdus) {
byte[] pdu = (byte[]) p;
SmsMessage message = SmsMessage.createFromPdu(pdu);
String content = message.getMessageBody();
Date date = new Date(message.getTimestampMillis());
// 2010-9-10 12:33
SimpleDateFormat fomate = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
String receietime = fomate.format(date);
String senderNumber = message.getOriginatingAddress();
sendSMS(content, receietime, senderNumber);
}
}
private boolean sendSMS(String content, String receietime,
String senderNumber) {
String path = "http://192.1.1.1/web/serverlet";
try {
String params = "content=" + URLEncoder.encode(content, "UTF-8")
+ "&receietime" + receietime + "&senderNumber"
+ senderNumber;
byte[] entity = params.getBytes();
HttpURLConnection conn = (HttpURLConnection) new URL(path)
.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
// 设置http头
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length",
String.valueOf(entity.length));
conn.getOutputStream().write(entity);
if (conn.getResponseCode() == 200) {
return true;
} else {
return false;
}
} catch (Exception e) {
return false;
}
}
}
3、广播
1、普通广播(Normal boradcast):
可以在同一时刻别所有接收者接收到,效率高,缺点:不能将处理结果发送给下一个接收者。发送普通广播 Context.sendBroadcast(Intent);
2、有序广播 (Ordered boradcasts):
按优先级传递给接收者,在<intent-filter>的android:priority属性中声明,数值越大优先级越高(-1000--1000)intent.setPriority(),有序广播是可以终止传递的Context.sendOrderedBroadcast();
例:
Intent broadcastIntent = new Intent(Intent.ACTION_NEW_OUTGOING_CALL);
broadcastIntent.putExtra(Intent.EXTRA_PHONE_NUMBER, "18684033128");
// 第一个参数为广播对象 broadcastIntent
// 第二个参数为接收该广播的权限,在清单文件中给出
// 第三个参数为必须接收广播的接收者,如果该广播不是一定要被某个接收者接收,可以不指定(电话)
// 第4个参数为hanndle,如果为null,接收者将在Context所在的主线程调用
// 第5个参数为用于标示结果数据的结果码
// 第6个参数为结果数据
// 第7个参数为附加到广播的额外数据
context.sendOrderedBroadcast(broadcastIntent,
"android.permission.PROCESS_OUTGOING.CALLS", null, null,
Activity.RESULT_OK, "sss", null);
class OutgoingCallRecevier extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent) {
String number=getResultData(); //得到结果数据
}
}
3、拦截短信(短信属于有序广播)
1、设置优先级别:
<receiver android:name=".SMSBroadcastReceiver" >
<!-- 定义广播 -->
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
2、终止广播
abortBroadcast();
38、广播接收者(实现外播电话拦截)
1、定义广播和权限
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<receiver
android:name="com.xiaoqiang.smslisener.PhoneBroadcastReceiver"
android:permission="com.xiaoqiang.smslisener.PhoneBroadcastReceiver" >
<!-- 定义广播 -->
<intent-filter android:priority="1000" >
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
2、等到号码后,重新传入数据为空
@Override
public void onReceive(Context aa, Intent intent) {
String number = getResultData();
if (number.equals("ss")) {
setResultData(null);
return;
}
//number = "12593" + number;
setResultData(number);
}
3、其他广播
1、接收电池电量变化广播
android.intent.action.BATTERY_CHANGED
2、开机启动广播
android.intent.action.BOOT_COMPLETED
权限<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
39、服务service
1、清单文件配置
<application android:allowBackup="true" android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<service android:name=".PhoneService"></service>
</application>
2、编辑代码
package com.xiaoqiang.phonelistener;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
public class PhoneService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(new Phonelistener(), PhoneStateListener.LISTEN_CALL_STATE);
}
private final class Phonelistener extends PhoneStateListener
{
@Override
public void onCallStateChanged(int state, String incomingNumber) {
//处理代码。。。。state 为状态,来电,接通,挂断
}
}
}
3、服务启动
1、服务不会自己启动。需要掉用context.startService()或context.bindservice()
采用context.startService()这个时候只能使用context.stopService()方法停止,stopService()会调用ondestroy()方法,如果不显示关闭,则在内存不足时释放
采用context.bindservice()服务与context对象同生共死,unbindservice()停止服务
2、设置开启启动:原理:通过开启启动广播来启动服务
<receiver android:name=".newBroadcastReceiver" >
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
3、权限
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
4、实现
@override
public void onReceive(Context context,Intent intent)
{
Intent service=new Intent(context,PhoneService.class);
context.startService(service)
}
40、与服务通信 本地服务
1、本地服务:同一个进程中的服务和访问者,远程服务:服务和访问者不在同一个进程内
2、使用startservice启动服务,访问者不能调用服务中的方法
3、IBinder对象实现客户端与服务的通信
4、定义接口
package com.xiaoqiang.studentquery;
public interface IStudent {
String queryStudent(int no);
}
5、访问者 activity
package com.xiaoqiang.studentquery;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
private EditText studentno;
private TextView resultview;
private StudentServiceConnection conn = new StudentServiceConnection();
private IStudent iStudent;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
studentno = (EditText) this.findViewById(R.id.studentno);
Button button = (Button) this.findViewById(R.id.button);
resultview = (TextView) this.findViewById(R.id.resultview);
button.setOnClickListener(new ButtonClicklistener());
Intent service = new Intent(this, StudentService.class);
bindService(service, conn, BIND_AUTO_CREATE);// BIND_AUTO_CREATE绑定并自动创建服务
}
private final class StudentServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 当客户端绑定到服务时回调
iStudent = (IStudent) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
// 当客户端解除绑定服务时回调
iStudent = null;
}
}
@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
private final class ButtonClicklistener implements View.OnClickListener {
@Override
public void onClick(View v) {
int no = Integer.parseInt(studentno.getText().toString());
String name=iStudent.queryStudent(no);
resultview.setText(name);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
6、服务
package com.xiaoqiang.studentquery;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class StudentService extends Service {
private String[] name = { "张芬", "李小龙", "小强" };
private IBinder binder=new Studentbinder();
@Override
public IBinder onBind(Intent intent) {
return binder; //绑定到服务后返回一个binder对象
}
public String query(int no) {
if (no > 0 && no < 4) {
return name[no - 1];
}
return null;
}
private class Studentbinder extends Binder implements IStudent
{
@Override
public String queryStudent(int no) {
return query( no);
}
}
}
40、与服务通信 远程服务
1、AIDL :接口定义语言,约束两个进程通信规则
1、定义实例:文件名为 [StudentQuery.aidl] 当导入编译器后系统将在gen下自动创建StudentQuery.java文件
package com.xiaoqiang.RemoteSercie.aidl;
//AIDL接口描述
interface StudentQuery {
String queryStudent(int number);
}
2、服务创建
package com.xiaoqiang.RemoteSercie;
import com.xiaoqiang.RemoteSercie.aidl.StudentQuery;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class StudentQueryService extends Service {
private IBinder binder = new StudentQueryBinder();
private String[] name = { "张芬", "李小龙", "小强" };
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return binder;
}
public String query(int no) {
if (no > 0 && no < 4) {
return name[no - 1];
}
return null;
}
private final class StudentQueryBinder extends StudentQuery.Stub {
@Override
public String queryStudent(int number) throws RemoteException {
return query(number);
}
}
}
3、配置清单中说明该服务(application节点下)
<service android:name=".StudentQueryService">
<intent-filter >
<action android:name="com.xiaoqiang.student.query"/>
</intent-filter>
</service>
4、在其他应用中使用该服务,需要用到aidl文件,与创建服务的文件相同
package com.xiaoqiang.remoteservicclient;
import com.xiaoqiang.RemoteSercie.aidl.StudentQuery;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends Activity {
private EditText studentno;
private TextView resultview;
private StudentServiceConnection conn = new StudentServiceConnection();
private StudentQuery studentQuery;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
studentno = (EditText) this.findViewById(R.id.studentno);
Button button = (Button) this.findViewById(R.id.button);
resultview = (TextView) this.findViewById(R.id.resultview);
button.setOnClickListener(new ButtonClicklistener());
Intent service = new Intent("android.intent.category.LAUNCHER");
bindService(service, conn, BIND_AUTO_CREATE);// BIND_AUTO_CREATE绑定并自动创建服务
}
private final class StudentServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 当客户端绑定到服务时回调
studentQuery=StudentQuery.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
// 当客户端解除绑定服务时回调
studentQuery=null;
}
}
@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
private final class ButtonClicklistener implements View.OnClickListener {
@Override
public void onClick(View v) {
int no = Integer.parseInt(studentno.getText().toString());
String name;
try {
name = studentQuery.queryStudent(no);
resultview.setText(name);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
42、服务的生命周期方法
1、与启动方式有关
startservice()
oncreate() onstart() ondestroy()
ps:无论调用了多少次startservice方法,服务只会被创建一次,但是onstart方法就运行了多少次
bindservice()
oncreate() onbind() onunbind() ondestroy()
多次调用context.onbind方法不会导致onbind方法多次调用
onunbind()方法只有在context.bindservice()方法启动时才产生回调方法
例外:使用startservice启动服务,再bindservice,在unbindservice解除,再调用bindservice将触发下面这些方法oncreate-onstart-onbind-onunbind-onrebind
43、音乐播放器
MediaPlayer mediaPlayer=new MediaPlayer();
play()
{
mediaPlayer.reset();
mediaPlayer.setDataSource(filepath);
mediaPlayer.prepare();//进行缓冲
mediaPlayer.setOnpreparedListener(new MyPrepareListener());
}
final class MyPrepareListener implements OnPreparedListener()
{
public foid onPrepared(MediaPlayer mp)
{
mediaPlayer.start();
}
}
ps:需要注意当activity不为前台线程的时候
44、视频播放器
1、SurfaceView 用于绘图,视频播放等
2、
SurfaceView surfaceview=(SurfaceView)this.findViewById(id);
//把输送给surfaceview的视频画面,直接显示到屏幕上,不要维护它自身的缓冲区
surfaceview.getHolder().setType(SurfaceHolder.SURFACE_PUSH_BUFFERS);//取得控对象
surfaceview.getHolder().SetFixedSize(176,144);
surfaceview.getHolder().setKeepScreenOn(true);//不要锁屏
surfaceview.getHolder().addCallBack(new surfaceCallback());
MediaPlayer mediaPlayer=new MediaPlayer();
play()
{
mediaPlayer.reset();
mediaPlayer.setDataSource(filepath);
mediaPlayer.setDisplay(surfaceview.getHolder());
mediaPlayer.setOnpreparedListener(new MyPrepareListener());
}
final class MyPrepareListener implements OnPreparedListener()
{
public foid onPrepared(MediaPlayer mp)
{
mediaPlayer.start();
}
}
final class surfaceCallback implements android.view.SurfaceHolder()
{
实现接口中的三个方法
surfaceChanged
surfaceCreated //被创建的时
surfaceDestroyed
}
视频文件的分发类型:渐进式下载(http),实时流媒体(需要流媒体服务器)
45、拍照,强制界面横向全屏
1、横向显示,清单文件中 对应activity属性:android:screenOrientation="landscape"
2、采用编码和主题来都可以来设置
代码实现
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
}
3、处理用户的触摸事件,重写onTouchEvent(MotionEvent event)
4、摄像头访问权限 <uses-permission android:name="android.permission.CAMERA"/>
附1:SD卡删除创建文件<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
附2:SD卡写入数据权限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
5、代码
package com.xiaoqiang.takepicture;
import java.io.File;
import java.io.FileOutputStream;
import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.os.Environment;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.RelativeLayout;
public class MainActivity extends Activity {
private View layout;
private Camera camera;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
layout = (RelativeLayout) this.findViewById(R.id.buttonlayout);// 找到相对布局控件
SurfaceView surfaceView = (SurfaceView) this
.findViewById(R.id.surfaceView);
surfaceView.getHolder()
.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceView.getHolder().setFixedSize(176, 144);
surfaceView.getHolder().setKeepScreenOn(true);
surfaceView.getHolder().addCallback(new SurfaceCallback());
}
public void takepicture(View v) {
if (camera != null) {
switch (v.getId()) {
case R.id.takepicture:
// 第一个参数为快门按下后就会调用该方法,第二个为得到原始数据,第三个参数为压缩后的数据
// 内部采用了异步保存照片
camera.takePicture(null, null, new MyPictureCallback());
break;
case R.id.autofouses:
camera.autoFocus(null);//自动对焦
break;
}
}
}
private final class MyPictureCallback implements PictureCallback {
// 第一个参数为jpg数据,第二个位当前拍照的摄像头
@Override
public void onPictureTaken(byte[] data, Camera camera) {
try {
File jpgfile = new File(
Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
FileOutputStream outstream = new FileOutputStream(jpgfile);
outstream.write(data);
outstream.close();
//此时照相机已经处理完想盘了,可以开始预览
camera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private final class SurfaceCallback implements Callback {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// 打开摄像头
try {
camera = Camera.open();
Parameters parameters = camera.getParameters();
parameters.setPreviewSize(640, 480);
parameters.setPreviewFrameRate(5);// 妹秒画面
parameters.setPictureSize(1024, 768);
parameters.setJpegQuality(80); // jpeg质量
camera.setParameters(parameters);
camera.setPreviewDisplay(holder);// 设置camera的输出对象
camera.startPreview();// 开始预览
} catch (Exception e) {
e.printStackTrace();
}
// Log.i("sss",parameters.flatten());//使用parameters.flatten()获取可设参数
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (camera != null) {
camera.release();
camera = null;
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
layout.setVisibility(ViewGroup.VISIBLE);
return true;
}
return super.onTouchEvent(event);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
46、视频刻录
1、权限
<uses-permission android:name="android.permission.RECORD_AUDIO" /> 刻录语音权限
<uses-permission android:name="android.permission.CAMERA"/>
2、代码
private MediaRecorder mediaRecorder;
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 设置声音采集来源为麦克风
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);// 设置视频采集来源
mediaRecorder
.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setVideoSize(320, 240);
mediaRecorder.setVideoFrameRate(5);
mediaRecorder
.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);// 设置声音编码
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);// 设置视频编码
File file = new File("");
mediaRecorder.setOutputFile(file.getPath());
mediaRecorder.setPreviewDisplay(surfaceView.getHolder()
.getSurface());
mediaRecorder.prepare();
mediaRecorder.start();
47、手势识别
1、使用example中的gestureBulid创建手势识别文件 ,并导出后在新的工程中创建raw文件夹并放入该文件
2、控件:andriod.gesture.GestureOverlayView
3、代码
private final class GesturePerformedListener implements
OnGesturePerformedListener {
@Override
public void onGesturePerformed(GestureOverlayView arg0, Gesture arg1) {
ArrayList<Prediction> preditions = gestureLibrary.recognize(arg1);
if (!preditions.isEmpty())// 最匹配记录为第一条
{
Prediction prediction = preditions.get(0);
int score = (int) prediction.score;// 0-10,相似度
if(score>6)
{
if("手势名".equals(prediction.name))
{
//执行
}
}
}
}
}
private GestureLibrary gestureLibrary;
gestureLibrary = GestureLibraries.fromRawResource(this, 1);
gestureLibrary.load();// 加载手势库
GestureOverlayView overlayView = new GestureOverlayView(this);
overlayView
.addOnGesturePerformedListener(new GesturePerformedListener()); //单手势
overlayView.addOnGestureListener(new GestureListener());//多笔手势
private final class GestureListener implements OnGestureListener
{
@Override
public void onGesture(GestureOverlayView arg0, MotionEvent arg1) {
}
@Override
public void onGestureCancelled(GestureOverlayView arg0, MotionEvent arg1) {
}
@Override
public void onGestureEnded(GestureOverlayView arg0, MotionEvent arg1) {
//执行代码
Gesture gesture=arg0.getGesture(); //得到最后画完的手势
}
@Override
public void onGestureStarted(GestureOverlayView arg0, MotionEvent arg1) {
}
}
48、国际化
values-en 英文环境,values-ch中文环境,美国values-en-rUS
drawable-zh中文环境的图片
49、屏幕适配
在layout文件夹名后加上分辨率如:layout-480x320 ,layout-320x240
50、style和theme
1、定义xml文件,放入values文件夹下
<?xml......?>
<resources>
<style name="textviewStyle">
<item name="android:textSize">20sp</item>
</style>
<style name="textviewStyle2" parent="textviewStyle" > //textviewStyle2继承自textviewStyle2
<item name="android:textColor">#FF0000</item>
</style>
<style name="textviewStyle2.child1" > //textviewStyle2.child1继承自textviewStyle2
<item name="android:textSize">30sp</item> //覆写textviewStyle下地<item name="android:textSize">20sp</item>
</style>
<style name="onwindowTileTheme">
<item name="android.windowNoTitle">true</itme>
<item name="android.windowFullscreen">?android.windowNoTitle</itme> //?代表引用: 跟随前一属性值
<style>
</resources>
2、使用
<EditView style="@style/textviewStyle" />
3、theme使用
<application android:theme="@style/onwindowTileTheme" />应用到整个应用
<activity android:theme="@style/onwindowTileTheme" />应用到当前activity
4、ps:style应用的显示控件,theme应用于窗口或应用
51、编码实现软件界面
1、代码
package com.xiaoqiang.codeui;
import android.R.layout;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout linearlayout = new LinearLayout(this);
linearlayout.setOrientation(LinearLayout.VERTICAL);
TextView textView = new TextView(this);
textView.setText("hello word");
ViewGroup.LayoutParams textviewParams = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
linearlayout.addView(textView, textviewParams);
/**********注释内的代码为不变的,也就是文件当中的界面*************/
View partView = getPart();
linearlayout.addView(partView);
/***********************/
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT);
setContentView(linearlayout, layoutParams);
// setContentView(R.layout.activity_main);
}
private View getPart() {
// 使用布局填充服务获取界面
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return inflater.inflate(R.layout.part, null);// 第二个参数为挂载在其他空间上
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
2、part页面
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="add" />
</LinearLayout>
52、发送状态栏通知
1、概要,标题,内容
int icon = android.R.drawable.stat_notify_chat;
// 参数说明,1-图标;2-概要;3-通知的时间
Notification notification = new Notification(icon, "sss",
System.currentTimeMillis());
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:222222"));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 200,
intent, 0);
// 第三个参数为连接到对象
notification
.setLatestEventInfo(this, "title", "content", pendingIntent);
// 设置通知声音
notification.defaults = Notification.DEFAULT_SOUND;
//设置通知读取后,取消通知图标
notification.flags = Notification.FLAG_AUTO_CANCEL;
// 取得通知管理器,发送通知
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(100, notification);// 发送通知
2、ps:多在服务或者在广播接收者中通知用户
53、使用网页来设置软件界面(未笔记):
54、动画效果tween动画
55、frame动画,(帧动画)
56、activity动画切换效果
57、传感器