这周做了一个来电知了的项目,具体需求如下:

1.可以设置黑名单号码,拒接电话和短信

2.来电归属地查询

在生活中我们用到这些东西的时候感觉挺简单,但是让我们实现这些功能时,还是非常麻烦的。下面是我在做这个项目时的实现过程。

<一>设计首页,显示黑名单号码,并能进行黑名单添加和删除及其归属地查询功能。具体代码如下:

main.xml:主界面的布局文件




1.  <?xml version="1.0" encoding="utf-8"?> 
2.  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
3.  android:orientation="vertical" 
4.  android:layout_width="fill_parent" 
5.  android:layout_height="fill_parent" 
6.  android:background="#8A2BE2"> 
7.  <TextView 
8.  android:layout_height="wrap_content" 
9.  android:layout_width="fill_parent" 
10.  android:text="黑名单号码" 
11.  android:id="@+id/tv_blacknumber" 
12.  android:gravity="center" 
13.  android:textColor="#ff0000" 
14.  android:textSize="25px"/> 
15.  <ListView 
16.  android:layout_width="fill_parent" 
17.  android:layout_height="wrap_content" 
18.  android:id="@android:id/list" 
19.  android:cacheColorHint="#00000000" 
20.  android:layout_weight="1"/> 
21.  <TextView 
22.  android:id="@android:id/empty" 
23.  android:layout_width="fill_parent" 
24.  android:layout_height="fill_parent" 
25.  android:text="无黑名单号码,请添加!" 
26.  android:gravity="center" 
27.  android:textColor="#00CD00" 
28.  android:textSize="25px" 
29.  android:layout_weight="1"/> 
30.  <LinearLayout android:id="@+id/ll_bottom" 
31.  android:orientation="horizontal" 
32.  android:layout_width="fill_parent" 
33.  android:layout_height="wrap_content" 
34.  android:background="@drawable/buttonbackground"> 
35.  <Button android:id="@+id/btn_add" 
36.  android:layout_width="wrap_content" 
37.  android:layout_height="fill_parent" 
38.  android:layout_weight="1" 
39.  android:background="@drawable/button_selector" 
40.  android:text="添 加"/> 
41.  <Button android:id="@+id/btn_search" 
42.  android:layout_width="wrap_content" 
43.  android:layout_height="fill_parent" 
44.  android:layout_weight="1" 
45.  android:background="@drawable/button_selector" 
46.  android:text="归属地查询"/> 
47.  <Button android:id="@+id/btn_delete" 
48.  android:layout_width="wrap_content" 
49.  android:layout_height="fill_parent" 
50.  android:layout_weight="1" 
51.  android:background="@drawable/button_selector" 
52.  android:text="删 除"/> 
53.  <CheckBox android:id="@+id/cb_select_all" 
54.  android:layout_width="wrap_content" 
55.  android:layout_height="fill_parent" 
56.  android:layout_weight="1" 
57.  android:text="全 选"/> 
58.  </LinearLayout> 
59.  </LinearLayout>


这里我为BUTTON按键设置了一个背景色。代码如下:

button_selector.xml:


1 <?xml version="1.0" encoding="utf-8"?>
 2 <selector
 3     xmlns:android="http://schemas.android.com/apk/res/android">
 4     <item android:state_pressed="true" > <!-- 被按下的情况下 -->
 5         <shape>
 6             <!-- 渐变 -->
 7             <gradient
 8                 android:startColor="#99FFFF"
 9                 android:endColor="#33FF00"
10                 android:type="linear"
11                 android:angle="270"/>
12             <!-- 描边 -->
13             <stroke
14                 android:width="2dp"
15                 android:color="#CCCC00"
16                 android:dashWidth="5dp" 
17                 android:dashGap="3dp" />
18             <!-- 圆角 -->
19             <corners
20                 android:radius="5dp"/>
21             <!-- 内边距 -->
22             <padding
23                 android:left="5dp"
24                 android:top="5dp"
25                 android:right="5dp"
26                 android:bottom="5dp" />
27         </shape>
28     </item>
29     
30     <item android:state_focused="true" > <!-- 获得焦点的情况下 -->
31         <shape>
32             <gradient
33                 android:startColor="#FF0099"
34                 android:endColor="#FF0033"
35                 android:angle="270" />
36             <stroke
37                 android:width="2dp"
38                 android:color="#00FFFF" />
39             <corners
40                 android:radius="4dp" />
41           
42             <padding
43                 android:left="5dp"
44                 android:top="5dp"
45                 android:right="5dp"
46                 android:bottom="5dp" />  
47         </shape>
48     </item>
49     
50        <item>       <!-- 一般情况下 -->
51         <shape>
52             <solid android:color="#FFFACD"/>
53             <stroke
54                 android:width="4dp"
55                 android:color="#00FFFF" />
56             <corners 
57                 android:topRightRadius="5dp"
58                 android:bottomLeftRadius="5dp"
59                 android:topLeftRadius="5dp"
60                 android:bottomRightRadius="5dp"/>
61             <padding
62                 android:left="5dp"
63                 android:top="5dp"
64                 android:right="5dp"
65                 android:bottom="5dp" />
66         </shape>
67     </item>  
68 </selector>


ListView的设计:

blacknumber_list_item.xml:




    1.  <?xml version="1.0" encoding="utf-8"?> 
    2.  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    3.  android:orientation="horizontal" 
    4.  android:layout_width="fill_parent" 
    5.  android:layout_height="fill_parent"> 
    6.  <TextView android:id="@+id/tv_item_number" 
    7.  android:layout_width="wrap_content" 
    8.  android:layout_height="40dip" 
    9.  android:gravity="center" 
    10.  android:textSize="20sp" 
    11.  android:textColor="@drawable/itemcolor" 
    12.  android:layout_weight="1" 
    13.  android:layout_marginRight="6dip" /> 
    14.  <CheckBox 
    15.  android:id="@+id/cb_item_delete" 
    16.  android:layout_width="wrap_content" 
    17.  android:layout_height="40dip" 
    18.  android:layout_weight="1" 
    19.  android:focusable="false" 
    20.  android:checked="false" 
    21.  android:clickable="false" 
    22.  android:layout_alignParentRight="true" 
    23.  android:layout_marginLeft="2dip"/> 
    24.  </RelativeLayout>


    下面就是主界面的java代码:

    TelPhoneMangerActivity:


    1 package cn.yj3g.TelPhoneMangerActivity;
      2 
      3 import java.util.ArrayList;
      4 import java.util.HashMap;
      5 import java.util.List;
      6 import java.util.Map;
      7 import cn.yj3g.TelPhoneMangerDb.TelphoneMangerDBHelper;
      8 import cn.yj3g.TelphonemangerService.AddressService;
      9 import cn.yj3g.dao.TelphoneDao;
     10 import cn.yj3g.entity.TableContanst;
     11 import cn.yj3g.entity.Telphone;
     12 import android.app.AlertDialog;
     13 import android.app.ListActivity;
     14 import android.app.ProgressDialog;
     15 import android.content.Context;
     16 import android.content.DialogInterface;
     17 import android.content.Intent;
     18 import android.os.Bundle;
     19 import android.util.Log;
     20 import android.view.LayoutInflater;
     21 import android.view.View;
     22 import android.view.ViewGroup;
     23 import android.view.View.OnClickListener;
     24 import android.widget.Button;
     25 import android.widget.CheckBox;
     26 import android.widget.EditText;
     27 import android.widget.ListView;
     28 import android.widget.SimpleAdapter;
     29 import android.widget.TextView;
     30 import android.widget.Toast;
     31 
     32 public class TelPhoneMangerActivity extends ListActivity implements
     33         OnClickListener {
     34     private TelphoneDao dao;
     35     private TextView backNumberText;
     36     private ListView listView;
     37     private Button addButton;
     38     private Button searchButton;
     39     private Button deleteButton;
     40     private CheckBox selectAllCheckBox;
     41     private EditText numberEditText;
     42     private HashMap<String, Boolean> checkBoxStatus;
     43     private List<String> selectIds;
     44     private AddressService addressService;
     45     private ProgressDialog progressDialog;
     46     private static final String ACTION = "cn.yj3g.TelphonemangerService.TelphoneMangerListenterService";
     47 
     48     @Override
     49     public void onCreate(Bundle savedInstanceState) {
     50         super.onCreate(savedInstanceState);
     51         setContentView(R.layout.main);
     52         dao = new TelphoneDao(new TelphoneMangerDBHelper(this));
     53         addressService = new AddressService(this);
     54         listView = getListView();
     55         regist();
     56 
     57         // 数据库的拷贝事件
     58         if (!addressService.dbIsexit()) {
     59             new Thread(new DBcopyThread()).start();
     60             progressDialog = ProgressDialog.show(this, "初始化", "数据正在初始化,请稍等...",
     61                     true);
     62         }
     63 
     64         // 找到各个按键
     65         addButton = (Button) findViewById(R.id.btn_add);
     66         searchButton = (Button) findViewById(R.id.btn_search);
     67         deleteButton = (Button) findViewById(R.id.btn_delete);
     68         selectAllCheckBox = (CheckBox) findViewById(R.id.cb_select_all);
     69         backNumberText = (TextView) findViewById(android.R.id.empty);
     70         // 为按键设置监听
     71         addButton.setOnClickListener(this);
     72         searchButton.setOnClickListener(this);
     73         deleteButton.setOnClickListener(this);
     74         selectAllCheckBox.setOnClickListener(this);
     75         backNumberText.setOnClickListener(this);
     76         //
     77         showListView();
     78     }
     79 
     80     /**
     81      * 注册来电黑名单拦截
     82      */
     83     private void regist() {
     84         startService(new Intent(ACTION));
     85     }
     86 
     87     /**
     88      * 拷贝数据库线程,为了避免程序无响应。
     89      */
     90     private class DBcopyThread implements Runnable {
     91         @Override
     92         public void run() {
     93             try {
     94                 addressService.copyDB();
     95                 progressDialog.dismiss();
     96             } catch (Exception e) {
     97                 e.printStackTrace();
     98             }
     99         }
    100     }
    101 
    102     /**
    103      * 显示黑名单号码
    104      */
    105     private void showListView() {
    106         List<Map<String, Object>> data = dao.getAllTelphone();
    107         if (data.size() != 0) {
    108             backNumberText.setClickable(false);
    109         } else
    110             backNumberText.setClickable(true);
    111         String[] from = { TableContanst.NumberColumns.NUMBER, };
    112         int[] to = { R.id.tv_item_number };
    113         SimpleAdapter adapter = new TelphoneAdpter(this, data,
    114                 R.layout.blacknumber_list_item, from, to);
    115         listView.setAdapter(adapter);
    116     }
    117 
    118     /**
    119      * 监听事件处理
    120      */
    121     @Override
    122     public void onClick(View v) {
    123         if (v == addButton || v == backNumberText) {
    124             addTelphoneMethod();
    125         } else if (v == deleteButton) {
    126             deleteSeleteData();
    127             selectAllCheckBox.setChecked(false);
    128         } else if (v == searchButton) {
    129             Intent intent = new Intent();
    130             intent.setClass(TelPhoneMangerActivity.this, SearchActivity.class);
    131             startActivity(intent);
    132         } else if (v == selectAllCheckBox) {
    133             checkOrcancelAllbox(selectAllCheckBox.isChecked());
    134         }
    135     }
    136 
    137     /**
    138      * 提示信息
    139      */
    140     protected void showToast(String string) {
    141         Toast.makeText(this, string, Toast.LENGTH_SHORT).show();
    142     }
    143 
    144     /**
    145      * 添加黑名单号码
    146      */
    147     private void addTelphoneMethod() {
    148         LayoutInflater inflater = (LayoutInflater) this
    149                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    150         final View view = inflater.inflate(R.layout.dialog, null);
    151         new AlertDialog.Builder(this)
    152                 .setTitle("黑名单添加")
    153                 .setView(view)
    154                 .setPositiveButton("添加", new DialogInterface.OnClickListener() {
    155                     @Override
    156                     public void onClick(DialogInterface dialog, int which) {
    157                         numberEditText = (EditText) view
    158                                 .findViewById(R.id.et_number);
    159                         String number = numberEditText.getText().toString();
    160                         if (number.trim().length() == 0) {
    161                             TelPhoneMangerActivity.this.showToast("请输入拦截号码!");
    162                         } else if (dao.findTelphone(number).getCount() != 0) {
    163                             TelPhoneMangerActivity.this
    164                                     .showToast("输入号码已存在,无需增加!");
    165                         } else {
    166                             Telphone telphone = new Telphone(number);
    167                             long id = dao.addTelphone(telphone);
    168                             if (id < 0) {
    169                                 TelPhoneMangerActivity.this.showToast("添加失败!");
    170                             } else {
    171                                 TelPhoneMangerActivity.this.showToast("添加成功!");
    172                                 showListView();
    173                             }
    174                         }
    175                     }
    176                 })
    177                 .setNegativeButton("取消", new DialogInterface.OnClickListener() {
    178                     @Override
    179                     public void onClick(DialogInterface dialog, int which) {
    180                         dialog.cancel();
    181                     }
    182                 }).show();
    183     }
    184 
    185     /**
    186      * 黑名单号码删除
    187      */
    188     private void deleteSeleteData() {
    189         AlertDialog.Builder builder = new AlertDialog.Builder(this);
    190         builder.setTitle("黑名单删除")
    191                 .setMessage("确定删除所选号码?")
    192                 .setCancelable(false)
    193                 .setPositiveButton("确定", new DialogInterface.OnClickListener() {
    194                     public void onClick(DialogInterface dialog, int id) {
    195                         int count = 0;
    196                         if (selectIds.size() <= 0) {
    197                             Toast.makeText(TelPhoneMangerActivity.this,
    198                                     "无选中记录,请选择!", Toast.LENGTH_LONG).show();
    199                         } else {
    200                             // Log.v("TAG", "selectIds=" + selectIds.size());
    201                             for (int i = 0; i < selectIds.size(); i++) {
    202                                 String deleteNumber = selectIds.get(i);
    203                                 dao.deleteTelphoneById(deleteNumber);
    204                                 count++;
    205                             }
    206                             showListView();
    207                             if (count > 0) {
    208                                 Toast.makeText(TelPhoneMangerActivity.this,
    209                                         "删除成功!", Toast.LENGTH_LONG).show();
    210                             } else
    211                                 Toast.makeText(TelPhoneMangerActivity.this,
    212                                         "删除失败!", Toast.LENGTH_LONG).show();
    213                         }
    214                     }
    215                 })
    216                 .setNegativeButton("取消", new DialogInterface.OnClickListener() {
    217                     public void onClick(DialogInterface dialog, int id) {
    218                         dialog.cancel();
    219                     }
    220                 });
    221         AlertDialog alert = builder.create();
    222         alert.show();
    223     }
    224 
    225     /**
    226      * 点击ListView条目存储被点击的条目
    227      */
    228     @Override
    229     protected void onListItemClick(ListView l, View view, int position, long id) {
    230         CheckBox box = (CheckBox) view.findViewById(R.id.cb_item_delete);
    231         TextView idView = (TextView) view.findViewById(R.id.tv_item_number);
    232         String deleteNumber = idView.getText().toString();
    233         box.toggle(); // 改变checkbox的选中状态
    234         if (box.isChecked()) {
    235             selectIds.add(deleteNumber);
    236             checkBoxStatus.put(deleteNumber, true);
    237         } else {
    238             selectIds.remove(deleteNumber);
    239             checkBoxStatus.put(deleteNumber, false);
    240         }
    241     }
    242 
    243     /**
    244      * 全选or取消全选
    245      */
    246     private void checkOrcancelAllbox(boolean checked) {
    247         int itemCount = listView.getCount();
    248         selectIds.clear();
    249         checkBoxStatus.clear();
    250         for (int i = 0; i < itemCount; i++) {
    251             View view = listView.getChildAt(i);
    252             Map<String, Object> data = (Map<String, Object>) listView
    253                     .getItemAtPosition(i);
    254             String number = data.get(TableContanst.NumberColumns.NUMBER)
    255                     .toString();
    256             if (view != null) {
    257                 CheckBox cb = (CheckBox) view.findViewById(R.id.cb_item_delete);
    258                 cb.setChecked(checked);
    259             }
    260             checkBoxStatus.put(number, checked);
    261             if (checked) {
    262                 selectIds.add(number);
    263             }
    264         }
    265     }
    266 
    267     /**
    268      * 自定义SimpleAdapter显示ListView数据
    269      */
    270     private class TelphoneAdpter extends SimpleAdapter {
    271         public TelphoneAdpter(Context context,
    272                 List<? extends Map<String, ?>> data, int resource,
    273                 String[] from, int[] to) {
    274             super(context, data, resource, from, to);
    275             selectIds = new ArrayList<String>();
    276             checkBoxStatus = new HashMap<String, Boolean>();
    277         }
    278 
    279         @Override
    280         public View getView(int position, View convertView, ViewGroup parent) {
    281             View view = super.getView(position, convertView, parent);
    282             CheckBox box = (CheckBox) view.findViewById(R.id.cb_item_delete);
    283             TextView idView = (TextView) view.findViewById(R.id.tv_item_number);
    284             String number = idView.getText().toString();
    285             if (checkBoxStatus.containsKey(number)) {
    286                 box.setChecked(checkBoxStatus.get(number));
    287             } else {
    288                 box.setChecked(selectAllCheckBox.isChecked());
    289             }
    290             return view;
    291         }
    292     }
    293 }


    以上就把主界面显示出来,运行效果如下:


    Android 12 来电权限 安卓来电通_数据库


    Android 12 来电权限 安卓来电通_android_02


    Android 12 来电权限 安卓来电通_数据库_03


    Android 12 来电权限 安卓来电通_数据库_04

    <二>由于要对黑名单进行增删查操作,多归属地要进行查操作,所以我们需要创建一个数据库帮助类,还有就是要将数据库拷到应用文件目录下。下面就将实现代码附在下面,大家自己琢磨吧。

    TelphoneMangerDBHelper:




    1. package

    2. import
    3. import
    4. import
    5. import
    6. import
    7. import
    8. /**
    9. *
    10. *创建一个数据库帮助类
    11. *
    12. */
    13. public class TelphoneMangerDBHelper extends
    14. private static final
    15. public static final
    16. public static final int

    17. public
    18. int
    19. super(context, name, factory, version);
    20. }

    21. public
    22. this(context, DB_NAME, null, VERSION);
    23. }

    24. /**
    25. * 创建数据库
    26. */
    27. public void
    28. Log.v(TAG, "onCreate");
    29. db.execSQL("create table "
    30. + TableContanst.BLACK_NUMBER_TABLE
    31. + "(_id Integer primary key AUTOINCREMENT,"
    32. + "number char,"
    33. + "modify_time DATETIME)");
    34. }
    35. @Override
    36. public void onUpgrade(SQLiteDatabase db, int oldVersion, int
    37. Log.v(TAG, "onUpgrade");
    38. }

    39. }


    TelphoneDao:


    1 package cn.yj3g.dao;
     2 
     3 import java.util.ArrayList;
     4 import java.util.HashMap;
     5 import java.util.List;
     6 import java.util.Map;
     7 
     8 import android.content.ContentValues;
     9 import android.database.Cursor;
    10 import cn.yj3g.TelPhoneMangerDb.TelphoneMangerDBHelper;
    11 import cn.yj3g.entity.TableContanst;
    12 import cn.yj3g.entity.Telphone;
    13 
    14 public class TelphoneDao {
    15     private TelphoneMangerDBHelper dbHelper;
    16 
    17     public TelphoneDao(TelphoneMangerDBHelper dbHelper) {
    18         this.dbHelper = dbHelper;
    19     }
    20 
    21     /**
    22      * 添加一个Telphone对象数据到数据库表
    23      */
    24     public long addTelphone(Telphone phone) {
    25 
    26         ContentValues values = new ContentValues();
    27         values.put(TableContanst.NumberColumns.NUMBER, phone.getNumber());
    28         return dbHelper.getWritableDatabase().insert(
    29                 TableContanst.BLACK_NUMBER_TABLE, null, values);
    30 
    31     }
    32 
    33     /**
    34      * 删除一个number所对应的数据库表Telphone的记录
    35      */
    36     public int deleteTelphoneById(String number) {
    37         return dbHelper.getWritableDatabase().delete(
    38                 TableContanst.BLACK_NUMBER_TABLE,
    39                 TableContanst.NumberColumns.NUMBER + "=?",
    40                 new String[] { number + "" });
    41     }
    42     
    43     /**
    44      *  查询所有的记录
    45      */
    46     public List<Map<String, Object>> getAllTelphone() { 
    47         List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
    48         Cursor cursor = dbHelper.getWritableDatabase().query(
    49                 TableContanst.BLACK_NUMBER_TABLE, null, null, null, null, null,
    50                 "_id desc");
    51         while (cursor.moveToNext()) {
    52             Map<String, Object> map = new HashMap<String, Object>(8);
    53             String number = cursor.getString(cursor
    54                     .getColumnIndex(TableContanst.NumberColumns.NUMBER));
    55             map.put(TableContanst.NumberColumns.NUMBER, number);
    56             data.add(map);
    57         }
    58         cursor.close();
    59         return data;
    60     }
    61     /**
    62      * 黑名单号码查询
    63      */
    64     public Cursor findTelphone(String number) {
    65         Cursor cursor = dbHelper.getWritableDatabase().query(
    66                 TableContanst.BLACK_NUMBER_TABLE, null, "number=?",
    67                 new String[] { number }, null, null, null, null);
    68         return cursor;
    69     }
    70 
    71     public void closeDB() {
    72         dbHelper.close();
    73     }
    74 }


    AddressService:




    1. package

    2. import
    3. import
    4. import
    5. import

    6. import
    7. import
    8. import
    9. import

    10. /**
    11. * 定义一个归属地服务的类,为以后的归属地查询等提供方法。
    12. */
    13. public class
    14. private

    15. public
    16. this.context = context;
    17. }

    18. /**
    19. * 判断当前databases目录下有无phoneAddres.db
    20. */
    21. public boolean
    22. return
    23. }

    24. /**
    25. * 将phoneAddres.db拷贝到datebases目录下
    26. */
    27. public void copyDB() throws
    28. new
    29. // 找到data目录下的databases文件夹
    30. if
    31. databases.mkdirs();
    32. }
    33. new
    34. new
    35. this.getClass().getClassLoader()
    36. // 得到phoneAddress.db
    37. byte[] bs = new byte[1024];
    38. int
    39. while
    40. fos.write(bs, 0, length);
    41. }
    42. fos.flush();
    43. is.close();
    44. }

    45. /**
    46. * 获得来电的归属地 手机的正则表达式为:^1[358]\d{9}$
    47. */
    48. public
    49. null;
    50. File file = context.getDatabasePath(TableContanst.ADDRESS_DB_NAME);
    51. SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(),
    52. null, SQLiteDatabase.OPEN_READONLY);
    53. if
    54. if (Pattern.compile("^1[358]\\d{9}$").matcher(number).matches()) {// 手机来电匹配

    55. Cursor cursor = db
    56. .rawQuery(
    57. "select p.name as province,c.name as city from address as a "
    58. + "inner join city as c on a.cityid=c._id "
    59. + "inner join province as p on c.provinceid=p._id "
    60. + "where a.mobileprefix=?",
    61. new
    62. address = getAddressInfo(cursor);
    63. else {// 座机电话匹配
    64. Cursor cursor = null;
    65. null;
    66. null;
    67. switch
    68. case 12: // 4位区号+8位电话号码

    69. cursor = db
    70. .rawQuery(
    71. "select p.name as province,c.name as city from city c "
    72. + "inner join province p on c.provinceid=p._id "
    73. + "where c.areacode=? "
    74. + "order by c._id asc limit 1",
    75. new
    76. address = getAddressInfo(cursor);
    77. break;
    78. case 11:// 4位区号+8位电话号码 或者 3位区号+8位电话号码

    79. subNumber3 = number.substring(0, 3);
    80. cursor = db
    81. .rawQuery(
    82. "select p.name as province,c.name as city from city c "
    83. + "inner join province p on c.provinceid=p._id "
    84. + "where c.areacode in(?,?) "
    85. + "order by c._id asc limit 1",
    86. new
    87. address = getAddressInfo(cursor);
    88. break;
    89. case 10:// 3位区号+7位电话号码

    90. cursor = db
    91. .rawQuery(
    92. "select p.name as province,c.name as city from city c "
    93. + "inner join province p on c.provinceid=p._id "
    94. + "where c.areacode=? "
    95. + "order by c._id asc limit 1",
    96. new
    97. address = getAddressInfo(cursor);
    98. break;
    99. case
    100. case 7:// 本地号码

    101. break;
    102. case
    103. if
    104. address = "模拟器";
    105. else
    106. cursor = db
    107. .rawQuery(
    108. "select p.name as province,c.name as city from city c "
    109. + "inner join province p on c.provinceid=p._id "
    110. + "where c.areacode=? "
    111. + "order by c._id asc limit 1",
    112. new
    113. address = getAddressInfo(cursor);
    114. }
    115. break;
    116. case
    117. cursor = db
    118. .rawQuery(
    119. "select p.name as province,c.name as city from city c "
    120. + "inner join province p on c.provinceid=p._id "
    121. + "where c.areacode=? "
    122. + "order by c._id asc limit 1",
    123. new
    124. address = getAddressInfo(cursor);
    125. break;
    126. default:
    127. break;
    128. }
    129. }
    130. db.close();
    131. }
    132. return
    133. }

    134. /**
    135. * 根据查询所得游标得到来电的具体归属地并返回
    136. */
    137. private
    138. if
    139. String province = cursor.getString(0);
    140. String city = cursor.getString(1);
    141. if
    142. return
    143. else
    144. return
    145. }
    146. cursor.close();
    147. return
    148. }

    149. /**
    150. * 得到来电的类型
    151. */
    152. public
    153. if
    154. return
    155. else if
    156. .matches()) {
    157. return
    158. else if
    159. .matches()) {
    160. return
    161. else if
    162. return
    163. else if
    164. return
    165. else
    166. return
    167. }

    168. /**
    169. * 根据查询输入框输入的号码找到响应的归属地区号
    170. */
    171. public
    172. null;
    173. File file = context.getDatabasePath(TableContanst.ADDRESS_DB_NAME);
    174. SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(),
    175. null, SQLiteDatabase.OPEN_READONLY);
    176. if
    177. if (Pattern.compile("^1[358]\\d{9}$").matcher(number).matches()) {// 手机来电匹配

    178. Cursor cursor = db
    179. .rawQuery(
    180. "select c.areacode as areacode from city as c "
    181. + "inner join address a on a.cityid=c._id "
    182. + "where a.mobileprefix=? order by c._id asc limit 1",
    183. new
    184. areacode = getAreacodeInfo(cursor);
    185. else
    186. if
    187. Cursor cursor = db
    188. .rawQuery(
    189. "select c.name as name from city as c "
    190. + "where c.areacode =? order by c._id asc limit 1",
    191. new
    192. areacode = getAreacodeInfo2(cursor, number);

    193. else if
    194. String subNumber4 = number.substring(0, 4);
    195. Cursor cursor = db
    196. .rawQuery(
    197. "select c.name as name from city as c "
    198. + "where c.areacode =? order by c._id asc limit 1",
    199. new
    200. areacode = getAreacodeInfo2(cursor, subNumber4);
    201. }
    202. }
    203. }
    204. db.close();
    205. return
    206. }

    207. /**
    208. * 根据查询所得游标得到查询手机号码的归属地
    209. */
    210. private
    211. if
    212. return
    213. }
    214. cursor.close();
    215. return
    216. }

    217. /**
    218. * 根据查询所得游标得到查询固话号码的归属地
    219. */
    220. private
    221. if
    222. return
    223. else
    224. cursor.close();
    225. return

    226. }
    227. }


    <三>设置黑名单拦截和短信拦截以及归属地查询功能。具体代码如下:

    TelphoneMangerListenterService:


    1 package cn.yj3g.TelphonemangerService;
      2 
      3 import java.lang.reflect.Method;
      4 import android.app.Service;
      5 import android.content.Context;
      6 import android.content.Intent;
      7 import android.database.Cursor;
      8 import android.graphics.PixelFormat;
      9 import android.net.Uri;
     10 import android.os.IBinder;
     11 import android.provider.ContactsContract.Contacts;
     12 import android.telephony.PhoneStateListener;
     13 import android.telephony.TelephonyManager;
     14 import android.util.Log;
     15 import android.view.LayoutInflater;
     16 import android.view.View;
     17 import android.view.WindowManager;
     18 import android.widget.TextView;
     19 import cn.yj3g.TelPhoneMangerActivity.R;
     20 import cn.yj3g.TelPhoneMangerDb.TelphoneMangerDBHelper;
     21 import cn.yj3g.dao.TelphoneDao;
     22 
     23 import com.android.internal.telephony.ITelephony;
     24 
     25 /**
     26  * 实现来电拦截和归属地显示
     27  */
     28 public class TelphoneMangerListenterService extends Service {
     29     private TelphoneDao dao;
     30     private AddressService addressService;
     31     private WindowManager windowManager;
     32     private LayoutInflater inflater;
     33     private View addressView;
     34 
     35     @Override
     36     public IBinder onBind(Intent intent) {
     37         Log.v("TAG", "onBind");
     38         return null;
     39     }
     40 
     41     @Override
     42     public void onCreate() {
     43         Log.v("TAG", "service onCreate()");
     44         super.onCreate();
     45         dao = new TelphoneDao(new TelphoneMangerDBHelper(this));
     46         addressService = new AddressService(this);
     47         // 窗口界面管理
     48         windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
     49         // View加载器
     50         inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
     51         // 电话服务管理
     52         TelephonyManager manager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
     53         // 监听电话状态
     54         manager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
     55     }
     56 
     57     private PhoneStateListener listener = new PhoneStateListener() {
     58         @Override
     59         public void onCallStateChanged(int state, String incomingNumber) {
     60             super.onCallStateChanged(state, incomingNumber);
     61             // 打印电话状态改变信息
     62             Log.v("TAG", "onCallStateChanged state=" + state);
     63             switch (state) {
     64             case TelephonyManager.CALL_STATE_RINGING: // 响铃时
     65                 Cursor cursor = dao.findTelphone(incomingNumber);
     66                 //
     67                 if (cursor != null && cursor.getCount() != 0) {
     68                     stop(incomingNumber);
     69                 } else {
     70                     String number = getContactsName(incomingNumber);
     71                     String address = addressService.getAddress(incomingNumber)
     72                             +"  "+addressService.getType(incomingNumber);
     73                     showAddress(address, number);
     74                 }
     75                 cursor.close();
     76                 break;
     77             case TelephonyManager.CALL_STATE_IDLE:// 挂断或者无电话时
     78                 removeAddressView();
     79                 break;
     80             case TelephonyManager.CALL_STATE_OFFHOOK:// 接起电话
     81                 break;
     82             default:
     83                 break;
     84             }
     85         }
     86 
     87         /**
     88          * 来电号码和电话本里的号码进行匹配
     89          */
     90         private String getContactsName(String incomingNumber) {
     91             String number = incomingNumber;
     92             Uri uri = Uri
     93                     .parse("content://com.android.contacts/data/phones/filter/"
     94                             + incomingNumber);
     95             Cursor cursor = getContentResolver().query(uri,
     96                     new String[] { Contacts.DISPLAY_NAME }, null, null, null);
     97             if (cursor.moveToFirst()) {
     98                 number = cursor.getString(0);
     99             }
    100             cursor.close();
    101             return number;
    102         }
    103 
    104         /**
    105          * 显示来电归属地窗口
    106          */
    107         private void showAddress(String address, String incomingNumber) {
    108             WindowManager.LayoutParams params = new WindowManager.LayoutParams();
    109             params.height = WindowManager.LayoutParams.WRAP_CONTENT;
    110             params.width = WindowManager.LayoutParams.WRAP_CONTENT;
    111             params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
    112                     | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
    113             params.format = PixelFormat.TRANSLUCENT;
    114             params.y += 24;
    115             params.type = WindowManager.LayoutParams.TYPE_TOAST;
    116             addressView = inflater.inflate(R.layout.address, null);
    117             TextView shownumber = (TextView) addressView
    118                     .findViewById(R.id.shownumber);
    119             TextView showaddress = (TextView) addressView
    120                     .findViewById(R.id.showaddress);
    121             shownumber.setText(incomingNumber);
    122             showaddress.setText(address);
    123             windowManager.addView(addressView, params);
    124         }
    125     };
    126 
    127     /**
    128      * 去除添加的来电显示界面
    129      */
    130     private void removeAddressView() {
    131         if (addressView != null) {
    132             windowManager.removeView(addressView);
    133             addressView = null;
    134         }
    135     }
    136 
    137     /**
    138      * 电话拦截
    139      */
    140     public void stop(String s) {
    141         Log.e("TAG", "来电" + s + "为黑名单号码,已拦截!");
    142         // 调用ITelephony.endCall()结束通话
    143         try {
    144             Method method = Class.forName("android.os.ServiceManager")
    145                     .getMethod("getService", String.class);
    146             IBinder binder = (IBinder) method.invoke(null,
    147                     new Object[] { TELEPHONY_SERVICE });
    148             ITelephony telephony = ITelephony.Stub.asInterface(binder);
    149             telephony.endCall();
    150         } catch (Exception e) {
    151             e.printStackTrace();
    152         }
    153     }
    154 }


    BootCompleteReceiver:



    1. package
    2. 
    3. import
    4. import
    5. import
    6. import
    7. import
    8. import
    9. import
    10. import
    11. import
    12. import
    13. import
    14. import
    15. import
    16. 
    17. /** 
    18.  * 
    19.  * 定义一个广播接受者实现短信拦截 
    20.  * 
    21.  */
    22. public class BootCompleteReceiver extends
    23. private
    24. 
    25. public
    26.  Log.v("TAG", "开机了!"); 
    27.  } 
    28. 
    29.  @Override 
    30. public void
    31. /** 
    32.  * 运用广播开启监听这个服务 
    33.  */
    34. new TelphoneDao(new
    35.  Object[] pdus = (Object[]) intent.getExtras().get("pdus"); 
    36. if (pdus != null
    37. new
    38. for (int
    39. byte[] pdu = (byte[]) pdus[i]; 
    40.  messages[i] = SmsMessage.createFromPdu(pdu); 
    41.  } 
    42. for
    43. // 得到发信息的号码 
    44.  String content = message.getMessageBody();// 得到短信内容 
    45. 
    46. if (cursor != null
    47. // 中止发送 
    48.  //实例化通知 
    49.  Notification n = new
    50.  System.currentTimeMillis()); 
    51. new
    52.  i.setAction(Intent.ACTION_DIAL); 
    53.  i.setData(Uri.parse("tel:"+sender)); 
    54. //创建延期意图 
    55. 
    56. //设置通知的最新事件信息 
    57. 
    58. //获得通知管理器系统服务 
    59. 
    60.  nm.notify(1, n); 
    61.  Toast.makeText(context, "通知发布完成", 1).show(); 
    62.  Log.e("TAG", "号码" + sender + "为黑名单号码,已拦截!"); 
    63.  cursor.close(); 
    64.  } 
    65.  } 
    66.  } 
    67.  } 
    68.  }


    运行效果如下:


    Android 12 来电权限 安卓来电通_移动开发_05


    Android 12 来电权限 安卓来电通_android_06

    黑名单短信通知:


    Android 12 来电权限 安卓来电通_android_07

    显示归属地的运行效果如下:


    Android 12 来电权限 安卓来电通_移动开发_08

    <四>实现归属地查询功能

    SearchActivity:


    1 package cn.yj3g.TelPhoneMangerActivity;
     2 
     3 import cn.yj3g.TelphonemangerService.AddressService;
     4 import android.app.Activity;
     5 import android.os.Bundle;
     6 import android.view.View;
     7 import android.view.View.OnClickListener;
     8 import android.widget.Button;
     9 import android.widget.EditText;
    10 import android.widget.TextView;
    11 import android.widget.Toast;
    12 
    13 /**
    14  * 实现归属地查询功能
    15  */
    16 public class SearchActivity extends Activity implements OnClickListener {
    17     private AddressService addressService;
    18     private EditText numberEdit;
    19     private Button sureButton;
    20     private TextView numberText;
    21     private TextView addressText;
    22     private TextView typeText;
    23     private String address;
    24     private static final int COLOR = android.graphics.Color.RED;
    25 
    26     @Override
    27     protected void onCreate(Bundle savedInstanceState) {
    28         super.onCreate(savedInstanceState);
    29         setContentView(R.layout.search);
    30         addressService = new AddressService(this);
    31         numberEdit = (EditText) findViewById(R.id.et_search);
    32         sureButton = (Button) findViewById(R.id.btn_sure);
    33         numberText = (TextView) findViewById(R.id.tv_number);
    34         addressText = (TextView) findViewById(R.id.tv_address);
    35         typeText = (TextView) findViewById(R.id.tv_type);
    36         // 设置监听
    37         sureButton.setOnClickListener(this);
    38     }
    39 
    40     @Override
    41     public void onClick(View v) {
    42         String number = numberEdit.getText().toString();
    43         String areacode = addressService.getAreacode(number);
    44         if (areacode.length() == 0) {
    45             address = addressService.getAddress(number);
    46         } else
    47             address = addressService.getAddress(number) + "(" + areacode + ")";
    48         String type = "中国-" + addressService.getType(number);
    49         if (number.trim().length() <= 2 || address.length() == 0) {
    50             addressText.setText("未知地区");
    51             typeText.setText("未知");
    52             typeText.setTextColor(COLOR);
    53             addressText.setTextColor(COLOR);
    54             numberText.setText(number);
    55             numberText.setTextColor(COLOR);
    56             Toast.makeText(this, "请输入正确格式的电话号码", 0).show();
    57             numberEdit.setText(null);
    58         } else {
    59             numberText.setText(number);
    60             numberText.setTextColor(COLOR);
    61             addressText.setText(address);
    62             addressText.setTextColor(COLOR);
    63             typeText.setText(type);
    64             typeText.setTextColor(COLOR);
    65             numberEdit.setText(null);
    66         }
    67     }
    68 }


    归属地查询运行效果如下:


    Android 12 来电权限 安卓来电通_java_09


    Android 12 来电权限 安卓来电通_数据库_10


    Android 12 来电权限 安卓来电通_数据库_11

    以上就把这个功能基本上就实现了,下来我将一些相关的常量定义,布局设计,权限等代码附在下面,供大家参考。

    TableContanst:




    1. package

    2. public final class

    3. /**
    4. * 自定义的一些常量
    5. */
    6. public static final
    7. public static final
    8. public static final class
    9. public static final
    10. public static final
    11. }
    12. }


    Telphone:


    1 package cn.yj3g.entity;
     2 
     3 import java.io.Serializable;
     4 /**
     5  * 
     6  * 自定义一个Telphone类
     7  *
     8  */
     9 public class Telphone implements Serializable {
    10 
    11     private long _id;
    12     private String number;
    13     private String modifyDateTime;
    14     public Telphone(String number) {
    15         this.number = number;
    16     }
    17 
    18     public Telphone(long _id, String number) {
    19         super();
    20         this._id = _id;
    21         this.number = number;
    22     }
    23 
    24     public Telphone(long _id, String number, String modifyDateTime) {
    25         super();
    26         this._id = _id;
    27         this.number = number;
    28         this.modifyDateTime = modifyDateTime;
    29     }
    30 
    31     public Telphone() {
    32     }
    33     public long get_id() {
    34         return _id;
    35     }
    36     public void set_id(long _id) {
    37         this._id = _id;
    38     }
    39     public String getNumber() {
    40         return number;
    41     }
    42     public void setNumber(String number) {
    43         this.number = number;
    44     }
    45     public String getModifyDateTime() {
    46         return modifyDateTime;
    47     }
    48     public void setModifyDateTime(String modifyDateTime) {
    49         this.modifyDateTime = modifyDateTime;
    50     }
    51     @Override
    52     public int hashCode() {
    53         final int prime = 31;
    54         int result = 1;
    55         result = prime * result + (int) (_id ^ (_id >>> 32));
    56         result = prime * result
    57                 + ((modifyDateTime == null) ? 0 : modifyDateTime.hashCode());
    58         result = prime * result + ((number == null) ? 0 : number.hashCode());
    59         return result;
    60     }
    61     @Override
    62     public boolean equals(Object obj) {
    63         if (this == obj)
    64             return true;
    65         if (obj == null)
    66             return false;
    67         if (getClass() != obj.getClass())
    68             return false;
    69         Telphone other = (Telphone) obj;
    70         if (_id != other._id)
    71             return false;
    72         if (modifyDateTime == null) {
    73             if (other.modifyDateTime != null)
    74                 return false;
    75         } else if (!modifyDateTime.equals(other.modifyDateTime))
    76             return false;
    77         if (number == null) {
    78             if (other.number != null)
    79                 return false;
    80         } else if (!number.equals(other.number))
    81             return false;
    82         return true;
    83     }
    84     @Override
    85     public String toString() {
    86         return "Telphone [_id=" + _id + ", number=" + number + "]";
    87     }
    88 }


    view.xml:


    <?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="fill_parent">
    <ImageView 
        android:id="@+id/image" 
        android:layout_width="wrap_content"
        android:layout_height="fill_parent" 
        android:layout_marginRight="10dp" />
    <TextView 
        android:id="@+id/text" 
        android:layout_width="wrap_content"
        android:layout_height="fill_parent" 
        android:textColor="#000" />
    </LinearLayout>


    search.xml:




      1.  <?xml version="1.0" encoding="utf-8"?> 
      2.  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      3.  android:orientation="horizontal" 
      4.  android:layout_width="fill_parent" 
      5.  android:background="#8A2BE2" 
      6.  android:layout_height="fill_parent"> 
      7.  <Button 
      8.  android:id="@+id/btn_sure" 
      9.  android:layout_width="wrap_content" 
      10.  android:layout_height="wrap_content" 
      11.  android:layout_weight="5" 
      12.  android:text="查询" 
      13.  android:layout_alignParentRight="true" 
      14.  android:layout_marginLeft="2dip"/> 
      15.  <EditText android:layout_height="wrap_content" 
      16.  android:hint="可输入号码/区号" 
      17.  android:id="@+id/et_search" 
      18.  android:layout_width="wrap_content" 
      19.  android:padding="5dip" 
      20.  android:textSize="15sp" 
      21.  android:inputType="phone" 
      22.  android:maxLength="11" 
      23.  android:layout_alignParentTop="true" 
      24.  android:layout_alignParentLeft="true" 
      25.  android:layout_toLeftOf="@+id/btn_sure"/> 
      26.  <TextView android:layout_height="wrap_content" 
      27.  android:text="号码:" 
      28.  android:id="@+id/tv1" 
      29.  android:layout_width="wrap_content" 
      30.  android:layout_below="@+id/et_search" 
      31.  android:layout_marginRight="15dip" 
      32.  android:layout_alignParentLeft="true" 
      33.  android:layout_marginTop="16dp"/> 
      34.  <TextView 
      35.  android:id="@+id/tv_number" 
      36.  android:layout_height="wrap_content" 
      37.  android:layout_width="fill_parent" 
      38.  android:layout_toRightOf="@+id/tv1" 
      39.  android:layout_below="@+id/et_search" 
      40.  android:layout_alignBottom="@+id/tv1" 
      41.  android:layout_marginTop="16dp"/> 
      42.  <TextView android:layout_height="wrap_content" 
      43.  android:text="归属:" 
      44.  android:id="@+id/tv2" 
      45.  android:layout_width="wrap_content" 
      46.  android:layout_below="@+id/tv1" 
      47.  android:layout_marginRight="15dip" 
      48.  android:layout_alignParentLeft="true" 
      49.  android:layout_marginTop="20dp"/> 
      50.  <TextView 
      51.  android:id="@+id/tv_address" 
      52.  android:layout_height="wrap_content" 
      53.  android:layout_width="fill_parent" 
      54.  android:layout_toRightOf="@+id/tv2" 
      55.  android:layout_below="@+id/tv_number" 
      56.  android:layout_alignBottom="@+id/tv2" 
      57.  android:layout_marginTop="20dp"/> 
      58.  <TextView android:layout_height="wrap_content" 
      59.  android:text="类型:" 
      60.  android:id="@+id/tv3" 
      61.  android:layout_width="wrap_content" 
      62.  android:layout_below="@+id/tv2" 
      63.  android:layout_marginRight="15dip" 
      64.  android:layout_alignParentLeft="true" 
      65.  android:layout_marginTop="25dp"/> 
      66.  <TextView 
      67.  android:id="@+id/tv_type" 
      68.  android:layout_height="wrap_content" 
      69.  android:layout_width="fill_parent" 
      70.  android:layout_toRightOf="@+id/tv3" 
      71.  android:layout_below="@+id/tv_address" 
      72.  android:layout_alignBottom="@+id/tv3" 
      73.  android:layout_marginTop="25dp"/> 
      74.  </RelativeLayout>


      dialog.xml:


      1 <?xml version="1.0" encoding="utf-8"?>  
       2 <LinearLayout  
       3   xmlns:Android="http://schemas.android.com/apk/res/android"  
       4   Android:layout_width="fill_parent"  
       5   Android:layout_height="fill_parent"  
       6   Android:orientation="vertical">  
       7   <EditText     
       8     Android:layout_width="fill_parent"    
       9     Android:layout_height="wrap_content"    
      10     Android:id="@+id/et_number"  
      11     Android:inputType="phone"
      12     Android:hint="请输入电话号码"
      13     Android:maxLength="11"
      14     />  
      15 </LinearLayout>
      1 <?xml version="1.0" encoding="utf-8"?>  
       2 <LinearLayout  
       3   xmlns:Android="http://schemas.android.com/apk/res/android"  
       4   Android:layout_width="fill_parent"  
       5   Android:layout_height="fill_parent"  
       6   Android:orientation="vertical">  
       7   <EditText     
       8     Android:layout_width="fill_parent"    
       9     Android:layout_height="wrap_content"    
      10     Android:id="@+id/et_number"  
      11     Android:inputType="phone"
      12     Android:hint="请输入电话号码"
      13     Android:maxLength="11"
      14     />  
      15 </LinearLayout> 
       address.xml:
       
       
       
      1.  <?xml version="1.0" encoding="utf-8"?> 
      2.  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      3.  android:orientation="vertical" 
      4.  android:layout_width="wrap_content" 
      5.  android:background="@drawable/addressbackground" 
      6.  android:layout_height="wrap_content"> 
      7.  <LinearLayout 
      8.  android:orientation="horizontal" 
      9.  android:layout_width="wrap_content" 
      10.  android:layout_height="wrap_content"> 
      11.  <ImageButton android:id="@+id/showimage" 
      12.  android:layout_width="wrap_content" 
      13.  android:layout_height="wrap_content" 
      14.  android:background="@drawable/ic_launcher_vcard" 
      15.  android:scaleType="center"/> 
      16.  <TextView 
      17.  android:id="@+id/showaddress" 
      18.  android:layout_width="wrap_content" 
      19.  android:layout_height="wrap_content" 
      20.  android:gravity="center" 
      21.  android:textSize="20sp" 
      22.  android:textColor="#eee"/> 
      23.  </LinearLayout> 
      24.  <TextView 
      25.  android:id="@+id/shownumber" 
      26.  android:layout_width="fill_parent" 
      27.  android:layout_height="wrap_content" 
      28.  android:gravity="center" 
      29.  android:textSize="20sp" 
      30.  android:textColor="#eee"/> 
      31.  </LinearLayout>


      AndroidManifest.xml:


      1 <?xml version="1.0" encoding="utf-8"?>
       2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       3       package="cn.yj3g.TelPhoneMangerActivity"
       4       android:versionCode="1"
       5       android:versionName="1.0">
       6     <uses-sdk android:minSdkVersion="8" />
       7 
       8     <application android:icon="@drawable/phone" android:label="@string/app_name">
       9         <activity android:name=".TelPhoneMangerActivity"
      10                   android:label="@string/app_name">
      11             <intent-filter>
      12                 <action android:name="android.intent.action.MAIN" />
      13                 <category android:name="android.intent.category.LAUNCHER" />
      14             </intent-filter>
      15         </activity>
      16          <activity android:name=".SearchActivity"
      17                   android:label="归属地查询">
      18         </activity>
      19         <activity android:name=".ShowAvtivity"></activity>
      20         <service android:name="cn.yj3g.TelphonemangerService.TelphoneMangerListenterService">
      21             <intent-filter>
      22               <action android:name="cn.yj3g.TelphonemangerService.TelphoneMangerListenterService" ></action>
      23             </intent-filter>
      24         </service>
      25          <receiver android:name=".BootCompleteReceiver">
      26             <intent-filter android:priority="1000">
      27                 <action android:name="android.provider.Telephony.SMS_RECEIVED" />
      28             </intent-filter>
      29         </receiver>
      30     </application>
      31     <!-- 读取电话状态权限-->
      32     <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
      33     <!-- 开机启动广播的权限 -->
      34     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
      35     <!-- 挂断电话时需要的权限 -->
      36     <uses-permission android:name="android.permission.CALL_PHONE" />
      37     <!-- 接收短信权限 -->
      38     <uses-permission android:name="android.permission.RECEIVE_SMS"/>
      39     <!-- 发送短信权限 -->
      40     <uses-permission android:name="android.permission.SEND_SMS"/>
      41     <!-- 读取联系人信息权限 -->
      42     <uses-permission android:name="android.permission.READ_CONTACTS"/>
      43 </manifest>


      以上就是来电知了的全部代码和功能了,在做的过程中用到了许多的知识,比如数据库的增删查以及拷贝,线程的知识,广播机制,服务等知识。在做的过程中这些知识也就算是复习了一遍。如有有错误的地方,希望大家不吝指教。