android之来电知了
来源:互联网 发布:收银软件破解版 编辑:程序博客网 时间:2024/05/17 07:30
这周做了一个来电知了的项目,具体需求如下:
1.可以设置黑名单号码,拒接电话和短信
2.来电归属地查询
在生活中我们用到这些东西的时候感觉挺简单,但是让我们实现这些功能时,还是非常麻烦的。下面是我在做这个项目时的实现过程。
<一>设计首页,显示黑名单号码,并能进行黑名单添加和删除及其归属地查询功能。具体代码如下:
main.xml:主界面的布局文件
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="#8A2BE2">
- <TextView
- android:layout_height="wrap_content"
- android:layout_width="fill_parent"
- android:text="黑名单号码"
- android:id="@+id/tv_blacknumber"
- android:gravity="center"
- android:textColor="#ff0000"
- android:textSize="25px"/>
- <ListView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:id="@android:id/list"
- android:cacheColorHint="#00000000"
- android:layout_weight="1"/>
- <TextView
- android:id="@android:id/empty"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:text="无黑名单号码,请添加!"
- android:gravity="center"
- android:textColor="#00CD00"
- android:textSize="25px"
- android:layout_weight="1"/>
- <LinearLayout android:id="@+id/ll_bottom"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/buttonbackground">
- <Button android:id="@+id/btn_add"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:background="@drawable/button_selector"
- android:text="添 加"/>
- <Button android:id="@+id/btn_search"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:background="@drawable/button_selector"
- android:text="归属地查询"/>
- <Button android:id="@+id/btn_delete"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:background="@drawable/button_selector"
- android:text="删 除"/>
- <CheckBox android:id="@+id/cb_select_all"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_weight="1"
- android:text="全 选"/>
- </LinearLayout>
- </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 <stroke14 android:width="2dp"15 android:color="#CCCC00"16 android:dashWidth="5dp" 17 android:dashGap="3dp" />18 <!-- 圆角 -->19 <corners20 android:radius="5dp"/>21 <!-- 内边距 -->22 <padding23 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 <gradient33 android:startColor="#FF0099"34 android:endColor="#FF0033"35 android:angle="270" />36 <stroke37 android:width="2dp"38 android:color="#00FFFF" />39 <corners40 android:radius="4dp" />41 42 <padding43 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 <stroke54 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 <padding62 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:
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <TextView android:id="@+id/tv_item_number"
- android:layout_width="wrap_content"
- android:layout_height="40dip"
- android:gravity="center"
- android:textSize="20sp"
- android:textColor="@drawable/itemcolor"
- android:layout_weight="1"
- android:layout_marginRight="6dip" />
- <CheckBox
- android:id="@+id/cb_item_delete"
- android:layout_width="wrap_content"
- android:layout_height="40dip"
- android:layout_weight="1"
- android:focusable="false"
- android:checked="false"
- android:clickable="false"
- android:layout_alignParentRight="true"
- android:layout_marginLeft="2dip"/>
- </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 } else110 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 @Override122 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) this149 .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 @Override156 public void onClick(DialogInterface dialog, int which) {157 numberEditText = (EditText) view158 .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.this164 .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 @Override179 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 } else211 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 @Override229 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>) listView253 .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 @Override280 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:
- package cn.yj3g.TelPhoneMangerDb;
- import cn.yj3g.entity.TableContanst;
- import android.content.Context;
- import android.database.sqlite.SQLiteDatabase;
- import android.database.sqlite.SQLiteDatabase.CursorFactory;
- import android.database.sqlite.SQLiteOpenHelper;
- import android.util.Log;
- /**
- *
- *创建一个数据库帮助类
- *
- */
- public class TelphoneMangerDBHelper extends SQLiteOpenHelper {
- private static final String TAG = "TelphoneMangerDBHelper";
- public static final String DB_NAME = "telphone_black.db";
- public static final int VERSION = 1;
- public TelphoneMangerDBHelper(Context context, String name,
- CursorFactory factory, int version) {
- super(context, name, factory, version);
- }
- public TelphoneMangerDBHelper(Context context) {
- this(context, DB_NAME, null, VERSION);
- }
- /**
- * 创建数据库
- */
- public void onCreate(SQLiteDatabase db) {
- Log.v(TAG, "onCreate");
- db.execSQL("create table "
- + TableContanst.BLACK_NUMBER_TABLE
- + "(_id Integer primary key AUTOINCREMENT,"
- + "number char,"
- + "modify_time DATETIME)");
- }
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- Log.v(TAG, "onUpgrade");
- }
- }
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(cursor54 .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:
- package cn.yj3g.TelphonemangerService;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.util.regex.Pattern;
- import cn.yj3g.entity.TableContanst;
- import android.content.Context;
- import android.database.Cursor;
- import android.database.sqlite.SQLiteDatabase;
- /**
- * 定义一个归属地服务的类,为以后的归属地查询等提供方法。
- */
- public class AddressService {
- private Context context;
- public AddressService(Context context) {
- this.context = context;
- }
- /**
- * 判断当前databases目录下有无phoneAddres.db
- */
- public boolean dbIsexit() {
- return context.getDatabasePath(TableContanst.ADDRESS_DB_NAME).exists();
- }
- /**
- * 将phoneAddres.db拷贝到datebases目录下
- */
- public void copyDB() throws Exception {
- File databases = new File(context.getFilesDir().getParentFile(),
- "databases"); // 找到data目录下的databases文件夹
- if (!databases.exists()) {
- databases.mkdirs();
- }
- File dbFile = new File(databases, TableContanst.ADDRESS_DB_NAME);
- FileOutputStream fos = new FileOutputStream(dbFile);
- InputStream is = this.getClass().getClassLoader()
- .getResourceAsStream(TableContanst.ADDRESS_DB_NAME); // 得到phoneAddress.db
- byte[] bs = new byte[1024];
- int length = 0;
- while ((length = is.read(bs)) != -1) {
- fos.write(bs, 0, length);
- }
- fos.flush();
- is.close();
- }
- /**
- * 获得来电的归属地 手机的正则表达式为:^1[358]\d{9}$
- */
- public String getAddress(String number) {
- String address = null;
- File file = context.getDatabasePath(TableContanst.ADDRESS_DB_NAME);
- SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(),
- null, SQLiteDatabase.OPEN_READONLY);
- if (db.isOpen()) {
- if (Pattern.compile("^1[358]\\d{9}$").matcher(number).matches()) {// 手机来电匹配
- String subNumber7 = number.substring(0, 7);
- Cursor cursor = db
- .rawQuery(
- "select p.name as province,c.name as city from address as a "
- + "inner join city as c on a.cityid=c._id "
- + "inner join province as p on c.provinceid=p._id "
- + "where a.mobileprefix=?",
- new String[] { subNumber7 });
- address = getAddressInfo(cursor);
- } else {// 座机电话匹配
- Cursor cursor = null;
- String subNumber4 = null;
- String subNumber3 = null;
- switch (number.length()) {
- case 12: // 4位区号+8位电话号码
- subNumber4 = number.substring(0, 4);
- cursor = db
- .rawQuery(
- "select p.name as province,c.name as city from city c "
- + "inner join province p on c.provinceid=p._id "
- + "where c.areacode=? "
- + "order by c._id asc limit 1",
- new String[] { subNumber4 });
- address = getAddressInfo(cursor);
- break;
- case 11:// 4位区号+8位电话号码 或者 3位区号+8位电话号码
- subNumber4 = number.substring(0, 4);
- subNumber3 = number.substring(0, 3);
- cursor = db
- .rawQuery(
- "select p.name as province,c.name as city from city c "
- + "inner join province p on c.provinceid=p._id "
- + "where c.areacode in(?,?) "
- + "order by c._id asc limit 1",
- new String[] { subNumber4, subNumber3 });
- address = getAddressInfo(cursor);
- break;
- case 10:// 3位区号+7位电话号码
- subNumber3 = number.substring(0, 3);
- cursor = db
- .rawQuery(
- "select p.name as province,c.name as city from city c "
- + "inner join province p on c.provinceid=p._id "
- + "where c.areacode=? "
- + "order by c._id asc limit 1",
- new String[] { subNumber3 });
- address = getAddressInfo(cursor);
- break;
- case 8:
- case 7:// 本地号码
- address = "本地号码";
- break;
- case 4:
- if (number.startsWith("555")) {
- address = "模拟器";
- } else {
- cursor = db
- .rawQuery(
- "select p.name as province,c.name as city from city c "
- + "inner join province p on c.provinceid=p._id "
- + "where c.areacode=? "
- + "order by c._id asc limit 1",
- new String[] { number });
- address = getAddressInfo(cursor);
- }
- break;
- case 3:
- cursor = db
- .rawQuery(
- "select p.name as province,c.name as city from city c "
- + "inner join province p on c.provinceid=p._id "
- + "where c.areacode=? "
- + "order by c._id asc limit 1",
- new String[] { number });
- address = getAddressInfo(cursor);
- break;
- default:
- break;
- }
- }
- db.close();
- }
- return address;
- }
- /**
- * 根据查询所得游标得到来电的具体归属地并返回
- */
- private String getAddressInfo(Cursor cursor) {
- if (cursor.moveToFirst()) {
- String province = cursor.getString(0);
- String city = cursor.getString(1);
- if (province.equals(city)) {
- return province;
- } else
- return province + "省" + city + "市";
- }
- cursor.close();
- return "";
- }
- /**
- * 得到来电的类型
- */
- public String getType(String number) {
- if (Pattern.compile("^1[38][0126]\\d{8}$").matcher(number).matches()) {
- return "联通";
- } else if (Pattern.compile("^1[358][1456789]\\d{8}$").matcher(number)
- .matches()) {
- return "移动";
- } else if (Pattern.compile("^1[358][039]\\d{8}$").matcher(number)
- .matches()) {
- return "电信";
- } else if (number.startsWith("555")) {
- return "模拟器";
- } else if (getAddress(number).length() == 0) {
- return "未知";
- } else
- return "固话";
- }
- /**
- * 根据查询输入框输入的号码找到响应的归属地区号
- */
- public String getAreacode(String number) {
- String areacode = null;
- File file = context.getDatabasePath(TableContanst.ADDRESS_DB_NAME);
- SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(),
- null, SQLiteDatabase.OPEN_READONLY);
- if (db.isOpen()) {
- if (Pattern.compile("^1[358]\\d{9}$").matcher(number).matches()) {// 手机来电匹配
- String subNumber7 = number.substring(0, 7);
- Cursor cursor = db
- .rawQuery(
- "select c.areacode as areacode from city as c "
- + "inner join address a on a.cityid=c._id "
- + "where a.mobileprefix=? order by c._id asc limit 1",
- new String[] { subNumber7 });
- areacode = getAreacodeInfo(cursor);
- } else {
- if (number.length() == 3) {
- Cursor cursor = db
- .rawQuery(
- "select c.name as name from city as c "
- + "where c.areacode =? order by c._id asc limit 1",
- new String[] { number });
- areacode = getAreacodeInfo2(cursor, number);
- } else if (number.length() >= 4) {
- String subNumber4 = number.substring(0, 4);
- Cursor cursor = db
- .rawQuery(
- "select c.name as name from city as c "
- + "where c.areacode =? order by c._id asc limit 1",
- new String[] { subNumber4 });
- areacode = getAreacodeInfo2(cursor, subNumber4);
- }
- }
- }
- db.close();
- return areacode;
- }
- /**
- * 根据查询所得游标得到查询手机号码的归属地
- */
- private String getAreacodeInfo(Cursor cursor) {
- if (cursor.moveToFirst()) {
- return cursor.getString(0);
- }
- cursor.close();
- return "";
- }
- /**
- * 根据查询所得游标得到查询固话号码的归属地
- */
- private String getAreacodeInfo2(Cursor cursor, String number) {
- if (cursor.moveToFirst()) {
- return number;
- } else
- cursor.close();
- return "";
- }
- }
<三>设置黑名单拦截和短信拦截以及归属地查询功能。具体代码如下:
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_FOCUSABLE112 | 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) addressView118 .findViewById(R.id.shownumber);119 TextView showaddress = (TextView) addressView120 .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:
- package cn.yj3g.TelPhoneMangerActivity;
- import cn.yj3g.TelPhoneMangerDb.TelphoneMangerDBHelper;
- import cn.yj3g.dao.TelphoneDao;
- import android.app.Notification;
- import android.app.NotificationManager;
- import android.app.PendingIntent;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.database.Cursor;
- import android.net.Uri;
- import android.telephony.SmsMessage;
- import android.util.Log;
- import android.widget.Toast;
- /**
- *
- * 定义一个广播接受者实现短信拦截
- *
- */
- public class BootCompleteReceiver extends BroadcastReceiver {
- private String sender;
- public BootCompleteReceiver() {
- Log.v("TAG", "开机了!");
- }
- @Override
- public void onReceive(Context context, Intent intent) {
- /**
- * 运用广播开启监听这个服务
- */
- TelphoneDao dao = new TelphoneDao(new TelphoneMangerDBHelper(context));
- Object[] pdus = (Object[]) intent.getExtras().get("pdus");
- if (pdus != null && pdus.length > 0) {
- SmsMessage[] messages = new SmsMessage[pdus.length];
- for (int i = 0; i < pdus.length; i++) {
- byte[] pdu = (byte[]) pdus[i];
- messages[i] = SmsMessage.createFromPdu(pdu);
- }
- for (SmsMessage message : messages) {
- sender = message.getOriginatingAddress();// 得到发信息的号码
- String content = message.getMessageBody();// 得到短信内容
- Cursor cursor = dao.findTelphone(sender);
- if (cursor != null && cursor.getCount() != 0) {
- abortBroadcast();// 中止发送
- //实例化通知
- Notification n = new Notification(R.drawable.ic_email_pending,"黑名单短信",
- System.currentTimeMillis());
- Intent i = new Intent();
- i.setAction(Intent.ACTION_DIAL);
- i.setData(Uri.parse("tel:"+sender));
- //创建延期意图
- PendingIntent pi = PendingIntent.getActivity(context, 1, i, PendingIntent.FLAG_ONE_SHOT);
- //设置通知的最新事件信息
- n.setLatestEventInfo(context, "黑名单短信",content, pi);
- //获得通知管理器系统服务
- NotificationManager nm = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
- nm.notify(1, n);
- Toast.makeText(context, "通知发布完成", 1).show();
- Log.e("TAG", "号码" + sender + "为黑名单号码,已拦截!");
- cursor.close();
- }
- }
- }
- }
- }
运行效果如下:
黑名单短信通知:
显示归属地的运行效果如下:
<四>实现归属地查询功能
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 @Override27 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 @Override41 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 } else47 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:
- package cn.yj3g.entity;
- public final class TableContanst {
- /**
- * 自定义的一些常量
- */
- public static final String BLACK_NUMBER_TABLE = "number";
- public static final String ADDRESS_DB_NAME="phoneAddress.db";
- public static final class NumberColumns {
- public static final String ID = "_id";
- public static final String NUMBER = "number";
- }
- }
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 @Override52 public int hashCode() {53 final int prime = 31;54 int result = 1;55 result = prime * result + (int) (_id ^ (_id >>> 32));56 result = prime * result57 + ((modifyDateTime == null) ? 0 : modifyDateTime.hashCode());58 result = prime * result + ((number == null) ? 0 : number.hashCode());59 return result;60 }61 @Override62 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 @Override85 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:
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:background="#8A2BE2"
- android:layout_height="fill_parent">
- <Button
- android:id="@+id/btn_sure"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_weight="5"
- android:text="查询"
- android:layout_alignParentRight="true"
- android:layout_marginLeft="2dip"/>
- <EditText android:layout_height="wrap_content"
- android:hint="可输入号码/区号"
- android:id="@+id/et_search"
- android:layout_width="wrap_content"
- android:padding="5dip"
- android:textSize="15sp"
- android:inputType="phone"
- android:maxLength="11"
- android:layout_alignParentTop="true"
- android:layout_alignParentLeft="true"
- android:layout_toLeftOf="@+id/btn_sure"/>
- <TextView android:layout_height="wrap_content"
- android:text="号码:"
- android:id="@+id/tv1"
- android:layout_width="wrap_content"
- android:layout_below="@+id/et_search"
- android:layout_marginRight="15dip"
- android:layout_alignParentLeft="true"
- android:layout_marginTop="16dp"/>
- <TextView
- android:id="@+id/tv_number"
- android:layout_height="wrap_content"
- android:layout_width="fill_parent"
- android:layout_toRightOf="@+id/tv1"
- android:layout_below="@+id/et_search"
- android:layout_alignBottom="@+id/tv1"
- android:layout_marginTop="16dp"/>
- <TextView android:layout_height="wrap_content"
- android:text="归属:"
- android:id="@+id/tv2"
- android:layout_width="wrap_content"
- android:layout_below="@+id/tv1"
- android:layout_marginRight="15dip"
- android:layout_alignParentLeft="true"
- android:layout_marginTop="20dp"/>
- <TextView
- android:id="@+id/tv_address"
- android:layout_height="wrap_content"
- android:layout_width="fill_parent"
- android:layout_toRightOf="@+id/tv2"
- android:layout_below="@+id/tv_number"
- android:layout_alignBottom="@+id/tv2"
- android:layout_marginTop="20dp"/>
- <TextView android:layout_height="wrap_content"
- android:text="类型:"
- android:id="@+id/tv3"
- android:layout_width="wrap_content"
- android:layout_below="@+id/tv2"
- android:layout_marginRight="15dip"
- android:layout_alignParentLeft="true"
- android:layout_marginTop="25dp"/>
- <TextView
- android:id="@+id/tv_type"
- android:layout_height="wrap_content"
- android:layout_width="fill_parent"
- android:layout_toRightOf="@+id/tv3"
- android:layout_below="@+id/tv_address"
- android:layout_alignBottom="@+id/tv3"
- android:layout_marginTop="25dp"/>
- </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:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="wrap_content"
- android:background="@drawable/addressbackground"
- android:layout_height="wrap_content">
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
- <ImageButton android:id="@+id/showimage"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/ic_launcher_vcard"
- android:scaleType="center"/>
- <TextView
- android:id="@+id/showaddress"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:textSize="20sp"
- android:textColor="#eee"/>
- </LinearLayout>
- <TextView
- android:id="@+id/shownumber"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:textSize="20sp"
- android:textColor="#eee"/>
- </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之来电知了
- android之来电知了
- android之来电知了--手机号码归属地查询
- android开发笔记之来电小骗子
- Android开发之监听手机来电
- Android开发之黑名单来电自动挂断
- Android开发之来电电话挂断实现
- Android开发之监听手机来电
- Android源码开发之来电接听振动
- android源码开发之监听来电状态
- Android之来电秀实现(一)
- Android之来电秀实现(二)
- Android之来电状态的监听
- Android BroadcastReceiver之修改来电号码
- Android O 拨打电话流程之来电
- 知了
- 初学Android,手机管理器之监听手机来电(六十三)
- android项目 之 来电管家(1) ----- 界面设计
- C/C++字符串总结
- Android 学生信息管理系统
- Android手机分辨率基础知识(DPI,DIP计算)
- 做技术的伤痛
- Java中Interface的用法
- android之来电知了
- myeclipse 8.6 优化 .
- SMTP邮件格式、SMTP 协议,SMTP的MIME写法,SMTP发送HTML邮件
- 电话窃听和拦截应用
- php在线生成word文档.doc文档 关键代码
- Java中Thread的使用、死锁以及生产者消费者问题详解
- Android之Animation
- 在哪个字段有判断I,B,P帧的信息
- 练习地址1