android之来电知了

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

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 
 3 import cn.yj3g.entity.TableContanst;
 4 import android.content.Context;
 5 import android.database.sqlite.SQLiteDatabase;
 6 import android.database.sqlite.SQLiteDatabase.CursorFactory;
 7 import android.database.sqlite.SQLiteOpenHelper;
 8 import android.util.Log;
 9 /**
10  * 
11  *创建一个数据库帮助类
12  *
13  */
14 public class TelphoneMangerDBHelper extends SQLiteOpenHelper {
15     private static final String TAG = "TelphoneMangerDBHelper";
16     public static final String DB_NAME = "telphone_black.db";
17     public static final int VERSION = 1;
18 
19     public TelphoneMangerDBHelper(Context context, String name,
20             CursorFactory factory, int version) {
21         super(context, name, factory, version);
22     }
23     
24     public TelphoneMangerDBHelper(Context context) {
25         this(context, DB_NAME, null, VERSION);
26     }
27 
28     /**
29      * 创建数据库
30      */
31     public void onCreate(SQLiteDatabase db) {
32         Log.v(TAG, "onCreate");
33         db.execSQL("create table "
34                 + TableContanst.BLACK_NUMBER_TABLE
35                 + "(_id Integer primary key AUTOINCREMENT,"
36                 + "number char,"
37                 + "modify_time DATETIME)");
38     }
39     @Override
40     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
41         Log.v(TAG, "onUpgrade");
42     }
43 
44 }
复制代码

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

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

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

运行效果如下:

黑名单短信通知:

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

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

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 
 3 public final class TableContanst {
 4     
 5     /**
 6      * 自定义的一些常量
 7      */
 8     public static final String BLACK_NUMBER_TABLE = "number";
 9     public static final String ADDRESS_DB_NAME="phoneAddress.db";
10     public static final class NumberColumns {
11         public static final String ID = "_id";
12         public static final String NUMBER = "number";
13     }
14 }
复制代码

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>
复制代码

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值