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

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 }

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

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

TelphoneMangerDBHelper:

  
  1. package cn.yj3g.TelPhoneMangerDb;
  2. import cn.yj3g.entity.TableContanst;
  3. import android.content.Context;
  4. import android.database.sqlite.SQLiteDatabase;
  5. import android.database.sqlite.SQLiteDatabase.CursorFactory;
  6. import android.database.sqlite.SQLiteOpenHelper;
  7. import android.util.Log;
  8. /**
  9. *
  10. *创建一个数据库帮助类
  11. *
  12. */
  13. public class TelphoneMangerDBHelper extends SQLiteOpenHelper {
  14. private static final String TAG = "TelphoneMangerDBHelper";
  15. public static final String DB_NAME = "telphone_black.db";
  16. public static final int VERSION = 1;
  17. public TelphoneMangerDBHelper(Context context, String name,
  18. CursorFactory factory, int version) {
  19. super(context, name, factory, version);
  20. }
  21. public TelphoneMangerDBHelper(Context context) {
  22. this(context, DB_NAME, null, VERSION);
  23. }
  24. /**
  25. * 创建数据库
  26. */
  27. public void onCreate(SQLiteDatabase db) {
  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 newVersion) {
  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 cn.yj3g.TelphonemangerService;
  2. import java.io.File;
  3. import java.io.FileOutputStream;
  4. import java.io.InputStream;
  5. import java.util.regex.Pattern;
  6. import cn.yj3g.entity.TableContanst;
  7. import android.content.Context;
  8. import android.database.Cursor;
  9. import android.database.sqlite.SQLiteDatabase;
  10. /**
  11. * 定义一个归属地服务的类,为以后的归属地查询等提供方法。
  12. */
  13. public class AddressService {
  14. private Context context;
  15. public AddressService(Context context) {
  16. this.context = context;
  17. }
  18. /**
  19. * 判断当前databases目录下有无phoneAddres.db
  20. */
  21. public boolean dbIsexit() {
  22. return context.getDatabasePath(TableContanst.ADDRESS_DB_NAME).exists();
  23. }
  24. /**
  25. * 将phoneAddres.db拷贝到datebases目录下
  26. */
  27. public void copyDB() throws Exception {
  28. File databases = new File(context.getFilesDir().getParentFile(),
  29. "databases"); // 找到data目录下的databases文件夹
  30. if (!databases.exists()) {
  31. databases.mkdirs();
  32. }
  33. File dbFile = new File(databases, TableContanst.ADDRESS_DB_NAME);
  34. FileOutputStream fos = new FileOutputStream(dbFile);
  35. InputStream is = this.getClass().getClassLoader()
  36. .getResourceAsStream(TableContanst.ADDRESS_DB_NAME); // 得到phoneAddress.db
  37. byte[] bs = new byte[1024];
  38. int length = 0;
  39. while ((length = is.read(bs)) != -1) {
  40. fos.write(bs, 0, length);
  41. }
  42. fos.flush();
  43. is.close();
  44. }
  45. /**
  46. * 获得来电的归属地 手机的正则表达式为:^1[358]\d{9}$
  47. */
  48. public String getAddress(String number) {
  49. String address = null;
  50. File file = context.getDatabasePath(TableContanst.ADDRESS_DB_NAME);
  51. SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(),
  52. null, SQLiteDatabase.OPEN_READONLY);
  53. if (db.isOpen()) {
  54. if (Pattern.compile("^1[358]\\d{9}$").matcher(number).matches()) {// 手机来电匹配
  55. String subNumber7 = number.substring(0, 7);
  56. Cursor cursor = db
  57. .rawQuery(
  58. "select p.name as province,c.name as city from address as a "
  59. + "inner join city as c on a.cityid=c._id "
  60. + "inner join province as p on c.provinceid=p._id "
  61. + "where a.mobileprefix=?",
  62. new String[] { subNumber7 });
  63. address = getAddressInfo(cursor);
  64. } else {// 座机电话匹配
  65. Cursor cursor = null;
  66. String subNumber4 = null;
  67. String subNumber3 = null;
  68. switch (number.length()) {
  69. case 12: // 4位区号+8位电话号码
  70. subNumber4 = number.substring(0, 4);
  71. cursor = db
  72. .rawQuery(
  73. "select p.name as province,c.name as city from city c "
  74. + "inner join province p on c.provinceid=p._id "
  75. + "where c.areacode=? "
  76. + "order by c._id asc limit 1",
  77. new String[] { subNumber4 });
  78. address = getAddressInfo(cursor);
  79. break;
  80. case 11:// 4位区号+8位电话号码 或者 3位区号+8位电话号码
  81. subNumber4 = number.substring(0, 4);
  82. subNumber3 = number.substring(0, 3);
  83. cursor = db
  84. .rawQuery(
  85. "select p.name as province,c.name as city from city c "
  86. + "inner join province p on c.provinceid=p._id "
  87. + "where c.areacode in(?,?) "
  88. + "order by c._id asc limit 1",
  89. new String[] { subNumber4, subNumber3 });
  90. address = getAddressInfo(cursor);
  91. break;
  92. case 10:// 3位区号+7位电话号码
  93. subNumber3 = number.substring(0, 3);
  94. cursor = db
  95. .rawQuery(
  96. "select p.name as province,c.name as city from city c "
  97. + "inner join province p on c.provinceid=p._id "
  98. + "where c.areacode=? "
  99. + "order by c._id asc limit 1",
  100. new String[] { subNumber3 });
  101. address = getAddressInfo(cursor);
  102. break;
  103. case 8:
  104. case 7:// 本地号码
  105. address = "本地号码";
  106. break;
  107. case 4:
  108. if (number.startsWith("555")) {
  109. address = "模拟器";
  110. } else {
  111. cursor = db
  112. .rawQuery(
  113. "select p.name as province,c.name as city from city c "
  114. + "inner join province p on c.provinceid=p._id "
  115. + "where c.areacode=? "
  116. + "order by c._id asc limit 1",
  117. new String[] { number });
  118. address = getAddressInfo(cursor);
  119. }
  120. break;
  121. case 3:
  122. cursor = db
  123. .rawQuery(
  124. "select p.name as province,c.name as city from city c "
  125. + "inner join province p on c.provinceid=p._id "
  126. + "where c.areacode=? "
  127. + "order by c._id asc limit 1",
  128. new String[] { number });
  129. address = getAddressInfo(cursor);
  130. break;
  131. default:
  132. break;
  133. }
  134. }
  135. db.close();
  136. }
  137. return address;
  138. }
  139. /**
  140. * 根据查询所得游标得到来电的具体归属地并返回
  141. */
  142. private String getAddressInfo(Cursor cursor) {
  143. if (cursor.moveToFirst()) {
  144. String province = cursor.getString(0);
  145. String city = cursor.getString(1);
  146. if (province.equals(city)) {
  147. return province;
  148. } else
  149. return province + "省" + city + "市";
  150. }
  151. cursor.close();
  152. return "";
  153. }
  154. /**
  155. * 得到来电的类型
  156. */
  157. public String getType(String number) {
  158. if (Pattern.compile("^1[38][0126]\\d{8}$").matcher(number).matches()) {
  159. return "联通";
  160. } else if (Pattern.compile("^1[358][1456789]\\d{8}$").matcher(number)
  161. .matches()) {
  162. return "移动";
  163. } else if (Pattern.compile("^1[358][039]\\d{8}$").matcher(number)
  164. .matches()) {
  165. return "电信";
  166. } else if (number.startsWith("555")) {
  167. return "模拟器";
  168. } else if (getAddress(number).length() == 0) {
  169. return "未知";
  170. } else
  171. return "固话";
  172. }
  173. /**
  174. * 根据查询输入框输入的号码找到响应的归属地区号
  175. */
  176. public String getAreacode(String number) {
  177. String areacode = null;
  178. File file = context.getDatabasePath(TableContanst.ADDRESS_DB_NAME);
  179. SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(),
  180. null, SQLiteDatabase.OPEN_READONLY);
  181. if (db.isOpen()) {
  182. if (Pattern.compile("^1[358]\\d{9}$").matcher(number).matches()) {// 手机来电匹配
  183. String subNumber7 = number.substring(0, 7);
  184. Cursor cursor = db
  185. .rawQuery(
  186. "select c.areacode as areacode from city as c "
  187. + "inner join address a on a.cityid=c._id "
  188. + "where a.mobileprefix=? order by c._id asc limit 1",
  189. new String[] { subNumber7 });
  190. areacode = getAreacodeInfo(cursor);
  191. } else {
  192. if (number.length() == 3) {
  193. Cursor cursor = db
  194. .rawQuery(
  195. "select c.name as name from city as c "
  196. + "where c.areacode =? order by c._id asc limit 1",
  197. new String[] { number });
  198. areacode = getAreacodeInfo2(cursor, number);
  199. } else if (number.length() >= 4) {
  200. String subNumber4 = number.substring(0, 4);
  201. Cursor cursor = db
  202. .rawQuery(
  203. "select c.name as name from city as c "
  204. + "where c.areacode =? order by c._id asc limit 1",
  205. new String[] { subNumber4 });
  206. areacode = getAreacodeInfo2(cursor, subNumber4);
  207. }
  208. }
  209. }
  210. db.close();
  211. return areacode;
  212. }
  213. /**
  214. * 根据查询所得游标得到查询手机号码的归属地
  215. */
  216. private String getAreacodeInfo(Cursor cursor) {
  217. if (cursor.moveToFirst()) {
  218. return cursor.getString(0);
  219. }
  220. cursor.close();
  221. return "";
  222. }
  223. /**
  224. * 根据查询所得游标得到查询固话号码的归属地
  225. */
  226. private String getAreacodeInfo2(Cursor cursor, String number) {
  227. if (cursor.moveToFirst()) {
  228. return number;
  229. } else
  230. cursor.close();
  231. return "";
  232. }
  233. }

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

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

运行效果如下:

黑名单短信通知:

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

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

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 }

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

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

TableContanst:

  
  1. package cn.yj3g.entity;
  2. public final class TableContanst {
  3. /**
  4. * 自定义的一些常量
  5. */
  6. public static final String BLACK_NUMBER_TABLE = "number";
  7. public static final String ADDRESS_DB_NAME="phoneAddress.db";
  8. public static final class NumberColumns {
  9. public static final String ID = "_id";
  10. public static final String NUMBER = "number";
  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>  

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>

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

原文地址: http://www.cnblogs.com/zxl-jay/archive/2011/09/30/2196555.html#2300170

android之来电知了相关推荐

  1. Android 号码, 来电归属地 Jni 使用C++对二进制文件查询(一) 理论篇

    1.效果图 左边的是应用程序界面,只是做个测试.右边的是应用程序信息,你会发现数据这块很小,只有420KB,要知道里面有近280,000记录. 2.尝试使用sqlite数据库, 用db格式文件. 随便 ...

  2. android 来电过滤,Android实现来电挂断

    Android实现来电挂断要注意区分系统版本 Android 9.0 以后使用TelecomManager (需要权限Manifest.permission.ANSWER_PHONE_CALLS). ...

  3. Android实现来电和去电的监听

    写个实例实现Android中来电和去电的监听,来电可以使用PhoneStateListener对电话状态的改变进行监听,去电需要动态或者静态去注册广播接收器,对去电进行监听: 来电: 来电所对应的三种 ...

  4. android监控来电显示

    当电话来电的时候,我们要监控着电话号码的来电,哪我们是通过代码控制,下面我们看看利用吐丝显示来电显示 package com.smart;   import android.app.Activity; ...

  5. android 模拟来电广播,在Android模拟器上模拟来电

    最近项目要做一个控制来电显示的Android 应用 需要在Emulator上模拟来电 效果 方法如下: 1.单个电话 打开命令行cmd,输入telnet 回车. 然后输入 o localhost 55 ...

  6. Android设置来电号码归属地

    FAQ Content [DESCRIPTION] 如何关闭MTK内置来电号码归属地? [SOLUTION]   MTK平台号码归属地分为两种:1.手机号码归属地:2.固话号码归属地:   手机号码归 ...

  7. Android中来电号码归属地的显示

    昨日实现了360手机卫士的来电显示归属地的功能,具体的功能就是当来电的时候,界面会弹出来一个自定义的土司,显示当前号码的归属地,学习之后发现操作非常的简单,总结下加强自己的回忆. 具体细节大概为:别人 ...

  8. android来电电话获取,Android获取来电号码代码

    对于Android平台的整个来电软件制作十分简单,Android平台在各方面都比较智能,加上一个BOOT_COMPLETED获取,保证开机自动运行,一个来电通就很容易的制作完成了. Android来电 ...

  9. android 来电显示号码,android监控来电显示

    原理:电话预订功能,需要显示来电者的电话号码,c#实现获取电话号码,并在应用程序中显示出来.将电话机通过支持来电显示的moderm或USB来电显示盒(来电宝)与电话线连接,即可实现来电显示功能. 为了 ...

最新文章

  1. this keyword details
  2. linux grep 基本正则表达式与扩展正则表达式使用解析
  3. mysql不同count的性能分析
  4. nginx配置thinkphp5
  5. 在c#中用mutex类实现线程的互斥_面试官经常问的synchronized实现原理和锁升级过程,你真的了解吗...
  6. android 通知传值,Android消息通知(notification)和PendingIntent传值
  7. 计算机辅助语言和语言学关系,西方语言学与多媒体计算机辅助语言学习_王艳萍...
  8. 2014-3-16 星期天 晴[改变生活规律,稳中求进]
  9. kali字典WiFi
  10. VSCode 设置为 Monaco字体
  11. gwipr70驱动天空_gwi驱动
  12. STM8L HALT与IWDG同时使用问题
  13. web 打开pdf文件
  14. CVPR2021 多目标跟踪(MOT)汇总
  15. 跨境电商如何通过WhatsApp Business进行客户服务?
  16. 计算机组成原理八位全加器,8位全加器-课程设计
  17. 边打游戏边学编程,是一种怎样的体验?
  18. 虚拟机硬盘格式vdi、vhd、vmdk进行互相转换
  19. openGauss 极简版安装
  20. eclipse突然打不开,双击没反应

热门文章

  1. 美团二面:说说单点登录吧
  2. 手撸SSO单点登录(三):统一跳转至SSO登录页
  3. 【C语言学习笔记】int和long的范围
  4. python中import语句的作用是什么_什么是Pythonimport语句?在Python中的import语句作用有哪些?...
  5. 安卓开启子线程常用的方法
  6. AI正在让很多行业的红利消失
  7. c枚举类型enum例题_c枚举类型enum用法 枚举类型enum用法 怎么去取所有
  8. 可爱的皮卡丘print代码
  9. 《Automatic Image-Based WasteClassification》论文笔记
  10. 给vue的页面添加背景图片