二:通信卫士
1. 本地的号码归属地查询
将一张包含号码和归属地关系的数据库表拷贝到sd卡上,然后从sd卡上读取这张表上的对应关系,显示到界面上
public static void copyFile(InputStream is, File file) throws Exception{
byte[] buffer = new byte[1024];
int len = 0;
FileOutputStream fos = new FileOutputStream(file);
while((len = is.read(buffer))!=-1){
fos.write(buffer, 0, len);
}
fos.flush();
fos.close();
is.close();
}
// 1.打开数据库
String address = number;
SQLiteDatabase db = SQLiteDatabase.openDatabase("/sdcard/address.db",
null, SQLiteDatabase.OPEN_READONLY);
// select city from address_tb where _id = (select outkey from numinfo
// where mobileprefix='1356666')
2. 在android下的sqlite数据库必须创建一个表 android_metadata,里面有一个叫Local的字段
3. 拿到assert目录下的文件输入流,然后拷贝到sd卡上
File file = new File(Environment.getExternalStorageDirectory(),"address.db");
InputStream is = getContext().getAssets().open("naddress.db"); FileCopyUtil.copyFile(is, file);
4.判断是否是手机号码的正则表达式:
number.matches("^1[3458]\\d{9}$")
5.号码归属地的tv中如果没有输入内容,tv的抖动效果:
if(TextUtils.isEmpty(number)){
Animation shake = AnimationUtils.loadAnimation(this, R.anim.shake);
et_number_query.startAnimation(shake);
Toast.makeText(this, "请输入电话号码", 0).show();
return ;
6.界面上显示来电号码的归属地:
通过系统服务telephonymanager()可以知道手机的状态,是否有电话到来
定制系统可以通过修改phone代码来实现,我们可以使用toast来实现
7.自定义归属地显示的界面
8.归属地提示框的风格(金属灰,苹果绿)
弹出一个
alertdialog对话框,让用户选择,通过sp来持久化用户所选择的数据
9.更改归属地的位置和风格
10.来电短信黑名单拦截
内部实现原理:创建数据库—
>数据库的增删改查
短信拦截:
//处理一下短信黑名单的逻辑
if(dao.find(sender)){
abortBroadcast();// 终止黑名单号码发送过来的短信
}
if(body.contains("fapiao")){
Logger.i(
TAG, "FAPAIO 垃圾短信");
abortBroadcast();// 终止黑名单号码发送过来的短信
}
电话拦截:
if(dao.find(incomingNumber)){//
incomingnumber 是黑名单号码
//挂断电话
try {
Method method = Class.forName("android.os.ServiceManager").getMethod("getService", String.
class);
IBinder binder = (IBinder)method.invoke(
null,
new Object[]{
TELEPHONY_SERVICE});
ITelephony telephony = ITelephony.Stub.asInterface(binder);
telephony.endCall();
//呼叫记录的产生是一个异步的操作
//注册一个内容观察者 观察电话呼叫记录的信息是否发生了改变
getContentResolver().registerContentObserver(CallLog.Calls.
CONTENT_URI,
true,
new MyObserver(
new Handler(), incomingNumber));
return;
}
catch (Exception e) {
e.printStackTrace();
}
}
11.setForeground(true); 让这个后台的服务 像一个前台
activity一样运行,不会轻易被杀死
12.创建表的时候不要忘记指定主键
primary key
13.上下文菜单更改删除黑名单:
// 1. 给
listview注册上下文菜单
registerForContextMenu(lv);
// 2.得到菜单的布局填充器
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.
call_sms_item_menu, menu);
// 3.上下文菜单的点击事件
@Override
public
boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
// 当前上下文菜单在
listview中对应的条目的位置
final
int position = (
int) info.id;
String number = (String) lv.getItemAtPosition(position);
switch (item.getItemId()) {
case R.id.
menu_update:
showDialog(number, position, 0);
return
true;
case R.id.
menu_delete:
// 删除数据库内容
dao.delete(number);
// 更新
listview里面显示的数据
adapter.remove(number);
// 通知数据适配器更新数据
adapter.notifyDataSetChanged();
return
true;
}
return
true;
}
14.内容观察者删除黑名单号码呼叫记录
注册一个内容观察者来观察电话呼叫记录信息是否发生了改变
15.获取联系人信息需要增加权限,呼叫记录的产生是一个异步操作
16.来电响一声的拦截:
对时间进行一个判断,如果符合响一声号码,则通过内容提高者来获得来电响一声
的记录,然后通过
notification来设置点击事件,将这样的号码加入到黑名单
17.短信的备份和还原
操作短信需要通过内容提供者来实现,通过
xml的序列化器来序列化这些短信内容
XmlSerializer serializer = Xml.
newSerializer();
FileOutputStream fos =
new FileOutputStream(file);
serializer.setOutput(fos, "utf-8");
serializer.startDocument("utf-8",
true);
serializer.startTag(
null, "smsbackup");
pd.setMax(total);
serializer.attribute(
null, "total",total +"");
需要增加读写短信的权限,还原短信需要一个pullparser:
XmlPullParser parser = Xml.
newPullParser();
FileInputStream fis =
new FileInputStream(file);
parser.setInput(fis, "utf-8");
备份:Cursor cursor = context.getContentResolver().query(Uri.parse("content://sms/"), null, null, null, null);
还原:context.getContentResolver().insert(Uri.parse("content://sms/"), values);
在短信的备份和还原过程加入progressbar,可以提高用户的体验
18.创建一个文件对象:
File file = new File(Environment.getExternalStorageDirectory(),"smsbackup.xml");
本文出自 “蒲公英的梦想” 博客,转载请与作者联系!