实现的功能:
- sim卡的绑定
- 读取联系人
技术点:
- sim卡绑定
- 获取开机广播
- 读取联系人
- SimpleAdapter的使用
- Activity间数据传递
sim卡绑定
思路:
- 创建一个TelephonyManager对象
TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
- 调用getSimSerialNumber()即可得到sim卡的序列号
String number = manager.getSimSerialNumber();
然后将number添加到SharedPreferences中,获取权限:READ_PHONE_STATE
获取开机广播
我们要在程序每次开机的时候做一次判定,把SharedPreferences中存储的sim卡数据和当前sim卡数据进行对比,如果不同则发送报警短信
- 获取开机广播
创建一个类,继承自BroadCastReceiver
把这个类注册到清单列表中,并加入如下代码:
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
重写onReceive方法:
把SharedPreferences中存储的sim卡数据和当前sim卡数据进行对比,如果不同则发送报警短信
要获取权限:READ_BOOT_COMPLETE
读取联系人
这个功能需要使用的是内容提供者技术
- 创建一个ContentResolver对象
ContentResolver resolver = context.getContentResolver(); - 通过查询安卓系统源代码,我们了解到:
1)通过content://com.android.contacts/raw_contacts
可以获取到contact_id 即每个联系人的ID值
2)通过content://com.android.contacts/data
数据库中有contact_id mimetype data1三列
所以,我们可以通过上表中的contact_id来获取下表中的数据
具体实现代码:
private static final String URI_ID = "content://com.android.contacts/raw_contacts";
private static final String URI_DATA="content://com.android.contacts/data";
private static final String MIMETYPE_NAME="vnd.android.cursor.item/name";
private static final String MIMETYPE_PHONE="vnd.android.cursor.item/phone_v2";
List<Map<String,String>> data = new ArrayList<Map<String,String>>();
//获取一个内容解析器
ContentResolver resolver = context.getContentResolver();
//查询用户的通讯录信息
Uri uriId = Uri.parse(URI_ID);
Uri uriData = Uri.parse(URI_DATA);
Cursor cursorId = resolver.query(uriId,new String[]{"contact_id"},null,null,null);
while(cursorId.moveToNext())
{
String id = cursorId.getString(0);
if(id != null)
{
Cursor cursorData = resolver.query(uriData,new String[]{"data1","mimetype"},"contact_id=?",new String[]{id},null);
Map<String,String> map = new HashMap<String,String>();
while(cursorData.moveToNext())
{
String mimetype = cursorData.getString(1);
if(MIMETYPE_NAME.equals(mimetype))
{
map.put("name",cursorData.getString(0));
}
if(MIMETYPE_PHONE.equals(mimetype))
{
map.put("phone",cursorData.getString(0));
}
}
data.add(map);
cursorData.close();
}
}
cursorId.close();
return data;
}
获取权限:READ_CONTACT
SimpleAdapter的使用
难点在于两个:
1.看着有些凌乱的数据类型
List<Map<String,*>>
分析:
1)其实它是一个List集合
2)它的元素有点特殊,是一个Map集合
2.坑爹的构造函数参数
new SimpleAdapter(ContectActivity.this,data,R.layout.contect_item,
new String[]{"name","phone"},new int[]{R.id.tv_contact_item_name,R.id.tv_contact_item_phone});
好吧,已经看哭了……
逐个分析:
- 第一个参数:Context context 上下文
- 第二个参数:传入的就是那个很凌乱的数据类型
- 第三个参数:R.layout.*, 传入的是你自定义好的单个条目布局
- 第四个参数: 第二个参数的Map元素中的Key
- 第五个参数:第三个参数的布局中指定控件的id,这个和第四个参数要一一对应,如代码所示:
- name —->R.id.tv_contact_item_name
- phone—->R.id.tv_contact_item_phone
Activity间数据的传递:
(1) 从1–>2跳转,从1–>2传递数据
在1.class中:
Intent intent = new Intent(this,2.class)
intent.putExtras(“key”,value);
在2.class中:
Intent intent = getIntent();
intent.getSerializableExtra(“key”); 即可获取到1里面传来的数据
(2)从2–>1跳转,从2–>1传递数据
—第一步—
在1.class中:
Intent intent = new Intent(this,2.class);
startActivityForResult(intent, 0); //其中数字0为请求码,一会儿会用到
—第二步—
在2.class中:
Intent intent = new Intent();
intent.putExtra(“key”,value);
setResult(0,intent); //其中数字0为返回码,一会儿会用到
—第三步—
在1.class中:
重写父类方法:onActivityResult
/*
*requestCode 为请求码
*resultCode 为返回码
*data为2.class传回来的Intent
*/
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(data != null)
{
XXX value = data.getXXXExtra("key");
}
}
未完成的技术点:
- 两种序列化对象方法的使用
加油,晚安!