本文分享了一个电话黑名单的小项目,下面是具体的实现:

1.添加黑名单。 
2.判断如果是黑名单,就对其拦截。

添加黑名单:

往数据库里面添加黑名单,手机号码,用的是ContentProvider进行添加的(当然,这里是完全没有必要用这个的)

第一步: 
新建一个MyContentProvider继承自ContentProvider,并重写其中的方法:

package com.wind.safecall.contentprovider;import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;/*** Created by zhangcong on 2017/4/8.*/public class MyContentProvider extends ContentProvider {private MyOpenHelper myOpenHelper;private String DB_name="blackname";//数据库名private String Table_name="blacknametable";//数据表名private SQLiteDatabase sqLiteDatabase;private static UriMatcher uriMatcher;public static  final String AUTHORITY="blacknum";public static final  Uri uri =Uri.parse("content://blacknum/path_simon");// 注册该内容提供者匹配的uristatic {uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);//Creates the root node of the URI tree.uriMatcher.addURI(AUTHORITY,"path_simon",1);// 代表当前表中的所有的记录,第三个参数必须为正数uriMatcher.addURI(AUTHORITY,"path_simon/1",2);// 代表当前表中的某条特定的记录,记录id便是#处得数字}//数据表列名映射private static  final  String blacknum="blacknum";private static final String _id = "id";@Overridepublic boolean onCreate() {try {myOpenHelper=new MyOpenHelper(getContext(),DB_name,null,1);}catch (Exception e){return  false;}return true;}@Nullable@Overridepublic Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {Cursor cursor = null;sqLiteDatabase = myOpenHelper.getReadableDatabase();int code = uriMatcher.match(uri);//addURI()传的第三个参数switch (code) {case 1:cursor = sqLiteDatabase.query(Table_name, projection, selection,selectionArgs, null, null, sortOrder);break;case 2:// 从uri中解析出IDlong id = ContentUris.parseId(uri);selection = (selection == null || "".equals(selection.trim())) ? _id+ "=" + id: selection + " and " + _id + "=" + id;cursor = sqLiteDatabase.query(Table_name, projection, selection,selectionArgs, null, null, sortOrder);break;default:throw new IllegalArgumentException("参数错误");}return cursor;}@Nullable@Overridepublic String getType(@NonNull Uri uri) {return null;}@Nullable@Overridepublic Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {sqLiteDatabase=myOpenHelper.getWritableDatabase();sqLiteDatabase = myOpenHelper.getWritableDatabase();int code = uriMatcher.match(uri);//前面addURI传的第三个参数switch (code) {case 1:sqLiteDatabase.insert(Table_name, blacknum, values);break;case 2:long id = sqLiteDatabase.insert(Table_name, blacknum, values);// withAppendId将id添加到uri的最后ContentUris.withAppendedId(uri, id);break;default:throw new IllegalArgumentException("异常参数");}return uri;}@Overridepublic int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {return 0;}@Overridepublic int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {return 0;}private class MyOpenHelper extends SQLiteOpenHelper{public MyOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);}@Overridepublic void onCreate(SQLiteDatabase db) {/*** 官方解释* Called when the database is created for the first time. This is where the* creation of tables and the initial population of the tables should happen.** @param db The database.*/String sql = " create table if not exists " + Table_name+ "(blacknum  varchar(20),id INTEGER)";db.execSQL(sql);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142

第二步:在你的监听事件下执行这个方法:

 private void insertData(String blacknum) {ContentValues contentValues=new ContentValues();contentValues.put("blacknum",blacknum);//与数据库字段对应,第二个参数是你添加的给名单Uri uri=getContentResolver().insert(MyContentProvider.uri,contentValues);Utils.showToast(uri.toString(),MainActivity.this);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

第三步:查询你所添加的黑名单: 
这里分了两个步骤: 
查询黑名单和显示黑名单:

查询黑名单

private void queryBlackNum() {String array[]={"blacknum"};Cursor cursor=getContentResolver().query(MyContentProvider.uri,array,null,null,null);int blacknumindex=cursor.getColumnIndex("blacknum");Log.i(">>>",blacknumindex+"");cursor.moveToFirst();ArrayList<String> list=new ArrayList<>();while (!cursor.isAfterLast()){String blacknum=cursor.getString(blacknumindex);list.add(blacknum);cursor.moveToNext();Log.i(">>>",">>>>");Log.i("Simon",list.toString());}Intent intent=new Intent(MainActivity.this,BlackNumActivity.class);intent.putStringArrayListExtra("list", list);
//        Bundle bundle=new Bundle();
//        bundle.putSerializable("list", (Serializable) list);
//        intent.putExtras(bundle);startActivity(intent);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

在另一个Activity显示黑名单:

package com.wind.safecall.activity;import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;import com.wind.safecall.R;import java.util.ArrayList;
import java.util.List;/*** Created by zhangcong on 2017/4/10.*/public class BlackNumActivity extends Activity{private TextView activitytitle;private TextView back;private StringBuffer sb;private ListView listview;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_black_num);activitytitle= (TextView) findViewById(R.id.tv_activity_toolbar_center);activitytitle.setText("黑名单");listview= (ListView) findViewById(R.id.lv_black_num);back= (TextView) findViewById(R.id.tv_back);back.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {finish();}});showBlackNum();}private void showBlackNum() {ArrayList<String> list = this.getIntent().getStringArrayListExtra("list");Log.i(">>>>>", list.toString());if (list != null) {listview.setAdapter(new ArrayAdapter<>(BlackNumActivity.this, R.layout.item_black_num, R.id.tv_black_num, list));}}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

到这里,黑名单就添加完成。

接下来就是对其进行拦截了: 
拦截黑名单来电:

第一步:新建一个BlackNumService继承自Service,在这里面判断是不是黑名单,是的话对其拦截: 
这里需要补充一点的是:由于我们是直接拦截的来电,相当于是跨进程间的通信,这个时候aidl就登场了,好在Android有这些接口: 
因为下面的代码会调用这些接口,所以我们提交准备好:

1.在根目录新建一个android.telephony的包,在里面新建一个aidl文件,命名为NeighboringCellInfo; 
里面的内容为:

// NeighboringCellInfo.aidl
package android.telephony;// Declare any non-default types here with import statementsparcelable NeighboringCellInfo;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2.在根目录下新建一个com.android.internal.telephony的包,在里面新建一个aidl文件,命名为ITelephony;里面的内容为:

package com.android.internal.telephony;
interface ITelephony{boolean endCall();void answerRingingCall();
}
  • 1
  • 2
  • 3
  • 4
  • 5

这里的包名和文件名一定要一致,通过包名识别来电的,再进行通信的

package com.wind.safecall.service;import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;import com.android.internal.telephony.ITelephony;
import com.wind.safecall.contentprovider.MyContentProvider;import org.w3c.dom.ls.LSInput;import java.lang.reflect.Method;
import java.util.ArrayList;/*** Created by zhangcong on 2017/4/10.*/public class BlackNumService extends Service {private TelephonyManager tm;private MyPhoneStateListener listener;private NotificationManager nm;@Overridepublic void onCreate() {super.onCreate();tm= (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);listener=new MyPhoneStateListener();tm.listen(listener,PhoneStateListener.LISTEN_CALL_STATE);// nm= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);}private final class MyPhoneStateListener extends PhoneStateListener{//private long startTime = 0;@Overridepublic void onCallStateChanged(int state, String incomingNumber) {// TODO Auto-generated method stubsuper.onCallStateChanged(state, incomingNumber);switch (state) {case TelephonyManager.CALL_STATE_RINGING:String array[]={"blacknum"};Cursor cursor=getContentResolver().query(MyContentProvider.uri,array,null,null,null);int blacknumindex=cursor.getColumnIndex("blacknum");Log.i(">>>",blacknumindex+"");cursor.moveToFirst();ArrayList<String> list=new ArrayList<>();while (!cursor.isAfterLast()){String blacknum=cursor.getString(blacknumindex);list.add(blacknum);cursor.moveToNext();Log.i(">>>",">>>>");Log.i("Simon",list.toString());}if (list!=null&&list.contains(incomingNumber)){endCall();return;}//判断来电黑名单是否开启
//                    boolean isblackstart = sp.getBoolean("isblacknumber", false);
//                    if(isblackstart){//                        boolean isBlackNumber = blackNumberDao.isBlackNumber(incomingNumber);
//                        if(isBlackNumber){//
//                        }//startTime = System.currentTimeMillis();break;case TelephonyManager.CALL_STATE_OFFHOOK:break;case TelephonyManager.CALL_STATE_IDLE:break;default:break;}}}//挂断电话private void endCall(){try {Class<?> clazz = Class.forName("android.os.ServiceManager");Method method = clazz.getMethod("getService", String.class);IBinder ibinder = (IBinder) method.invoke(null, Context.TELEPHONY_SERVICE);ITelephony iTelephony = ITelephony.Stub.asInterface(ibinder);iTelephony.endCall();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}@Nullable@Overridepublic IBinder onBind(Intent intent) {return null;}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110

第二步:在广播中或者应用中开启服务:

1.在应用中开启服务:

 /*启动服务*/private void stService() {Intent intent=new Intent(MainActivity.this, BlackNumService.class);startService(intent);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

你可以在mainactivity中的oncreate方法中调用这个方法,只要这个进程不被杀死,这个服务也就一致存在,这是startService的性质。

2.在开机广播中开启服务:有些手机是接收不到广播的:

需要新建一个BootCompletedReceiver继承自BroadcastReceiver:

package com.wind.safecall.broadcastreceiver;import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;import com.wind.safecall.service.BlackNumService;/*** Created by zhangcong on 2017/4/10.*/public class BootCompletedReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent){Log.i(">>>>>>>>","已经开机");Intent intent1=new Intent(context, BlackNumService.class);context.startService(intent1);}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

这样,整个流程就结束了,最后贴出所有的权限和注册:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.wind.safecall"><uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><uses-permission android:name="android.permission.RECEIVE_SMS"/><uses-permission android:name="android.permission.READ_PHONE_STATE"/><!--添加可以向外拨打电话的权限  --><uses-permission android:name="android.permission.CALL_PHONE"></uses-permission><permission android:name="blacknum.permission"android:protectionLevel="normal"/><application
        android:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"><!-- 开机广播 --><receiver android:name=".broadcastreceiver.BootCompletedReceiver"><intent-filter ><action android:name="android.intent.action.BOOT_COMPLETED"/><category android:name="android.intent.category.HOME" /></intent-filter></receiver><service android:name=".service.BlackNumService"/><provider
            android:authorities="blacknum"android:name=".contentprovider.MyContentProvider"android:permission="blacknum.permission"/><activity
            android:name=".activity.MainActivity"android:screenOrientation="portrait"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><activity android:name=".activity.PhoneCallActivity"android:screenOrientation="portrait"/><activity android:name=".activity.BlackNumActivity"android:screenOrientation="portrait"/></application></manifest>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

Android项目之电话黑名单相关推荐

  1. android 自动挂断,android项目实现电话自动挂断的功能

    private void endCall() { try { /* * 1.得到字节码文件 * 2.得到对应的方法getService * 4.执行这个方法 * 以上是反射过程 * 5.拷贝aidl文 ...

  2. Android项目:手机安全卫士(13)—— 通讯卫士之电话拦截与挂断

    Android项目:手机安全卫士(13)-- 通讯卫士之电话拦截与挂断 1 介绍 上一节我们讲了黑名单数据的存储等 CRUD 操作,今天,就到了它们发挥作用的时候了,通讯卫士功法终于要练成了.我们实现 ...

  3. Android项目:手机安全卫士(12)—— 通讯卫士之电话短信黑名单设置与拦截

    版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] Android项目:手机安全卫士(12)-- 通讯卫士之电话.短信黑名单设置与拦截 1 介绍 今天进入新的功能开发了:通讯卫士, ...

  4. Android项目实战--手机卫士

    Android项目实战--手机卫士--结束 很久都没有来更新博客了,之前一直忙着工作的事,接触到了一些以前从来没有接触过的东西,真的挺有挑战性的,但也有很多的无奈,但也学习到了很多东西,我会慢慢的写到 ...

  5. 开发android项目实战,Android 项目实战:手机安全卫士开发案例解析

    Android 项目实战:手机安全卫士开发案例解析 作 者:王家林,王家俊,王家虎 出版时间:2013 丛编项:移动互联应用开发系列 内容简介 本书通过对一款手机安全卫士开发案例的详细解析,讲解了一个 ...

  6. 学习笔记之《Android项目实战——手机安全卫士》

    [Android项目实战-手机安全卫士] 目标:快速积累开发经验,具备中级Android工程师能力. 如遇到难以理解的逻辑或功能,可以先将程序打断点观察程序的执行逻辑. 第一章项目简介:欢迎界面.主界 ...

  7. 我的Android进阶之旅------Android项目目录结构分析

    此文章来自"博客园"博主,仅在此借鉴,学习 1.HelloWorld项目的目录结构 1.1.src文件夹 1.2.gen文件夹 1.3.Android 2.1文件夹 1.4.ass ...

  8. Android项目目录结构分析

    此文章来自"博客园"博主,仅在此借鉴,学习 1.HelloWorld项目的目录结构 1.1.src文件夹 1.2.gen文件夹 1.3.Android 2.1文件夹 1.4.ass ...

  9. Android项目的目录结构

    引言 本篇将通过HelloWorld项目来介绍Android项目的目录结构.本文的主要主题如下: 1.HelloWorld项目的目录结构 1.1.src文件夹 1.2.gen文件夹 1.3.Andro ...

  10. Android学习3—电话拨号器

    本测试主要实现了一个Android的拨打电话的功能 一:界面预览 由图中可以看出,这个Activity需要3个控件:TextView.EditText.Button 其实实现一个功能要经过几个步骤: ...

最新文章

  1. 《强化学习周刊》第2期:多智能体强化学习(MARL)赋能“AI智能时代”
  2. socket传输过程
  3. 独立于三大FPGA平台采用modelsim仿真
  4. KPCR:CPU控制区(Processor Control Region)
  5. 删除 CentOS Stream 8 开机多余引导项及等待时间
  6. 当我们在谈论内存时,我们在谈论什么
  7. selenium3 + python - page_source页面源码
  8. (pytorch-深度学习系列)pytorch实现线性回归
  9. 【mysql基础知识】查询当前时间之前5分钟内的数据
  10. ntp如何确认与服务器偏差_CDH集群时钟偏差问题
  11. CentOS安装jdk
  12. mfc通过com控制AutoCAD导出jpg文件
  13. 蓝桥杯新增web应用开发科目—送给想要参赛的小伙伴们一份备赛指南
  14. Python Pyside2新手应用淘宝客API接口简单获取淘宝客大额推广优惠券的实现
  15. 默认浏览器怎么更改为别的浏览器,这2个方法很简单
  16. Share:win10的日语输入法切换快捷键
  17. python怎么变大字体_pycharm字体放大缩小设置
  18. ESP8266+红外模块制作万能网路遥控器
  19. python彩色蟒蛇绘制方向_python绘制蟒蛇,绘制五彩蟒蛇
  20. 概率论中常见的几种分布

热门文章

  1. ASP.NET MVC- UrlHelper的用法
  2. 2021年压力焊工作业考试题库
  3. Android PDF 的 读取 与 生成
  4. 超详细大学生申请软件著作权登记模板及教程
  5. 第一个JAVA实战项目!
  6. Visio画图:用Visio画流程图(初级)
  7. SM2算法第十篇:数字证书及CA的扫盲介绍
  8. 遗传算法python实现
  9. 学习WPF绝佳的去处……WPF教程,WPF入门教程,WPF视频教程
  10. Pure Pursuit纯跟踪算法的Matlab算法实现