Android 利用廣播實現黑名單【指定號碼】的簡訊的攔截 附原始碼下載連結
阿新 • • 發佈:2018-12-14
Android 利用廣播實現指定號碼的簡訊的攔截
根據最近的學習內容,今天實現了利用廣播進行指定號碼的攔截
步驟:
①、寫一個數據庫的幫助類,實現對資料庫的建立,總共建立兩個資料庫psms(受保護的簡訊的資料庫)和protectedPhone(受保護的聯絡人資料庫),粘程式碼:
public class DBHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "protectedSMS.db";
private static final int DB_VERSION = 2 ;
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
String sql = "create table psms(_id integer primary key autoincrement,address varchar(20),type integer,state integer,body varchar(500),date varchar(20),person varchar(20))" ;
String sql1 = "create table protectedPhone(_id integer primary key autoincrement,person varchar(20),phone varchar(20))";
db.execSQL(sql);
db.execSQL(sql1);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
②、寫一個類對資料庫的增刪改查進行封裝,程式碼及註釋如下:
/**
* 封裝DAO,對資料庫進位制crud操作
*
* @author Administrator
*
*/
public class ProtectedDAO {
private SQLiteDatabase db;
public ProtectedDAO(Context context) {
DBHelper helper = new DBHelper(context);
db = helper.getWritableDatabase();
}
/**
* 插入資料到中
*
* @param table
* 表名
* @param values
* 對應的鍵和值
* @return 行號
*/
public long insert(String table, ContentValues values) {
// String sql = "insert into person(name,age) values('zhangsan',21)";
// db.execSQL(sql);
return db.insert(table, null, values);
}
/**
* 更新表中的資料
*
* @param table
* 表名
* @param values
* 修改後的值
* @param whereClause
* 條件語句可以使用佔位符 ?
* @param whereArgs
* 使用該陣列中的值替換佔位符
* @return 受影響資料表的行數
*/
public int update(String table, ContentValues values, String whereClause,
String[] whereArgs) {
return db.update(table, values, whereClause, whereArgs);
}
/**
*
* 刪除表中的資料
*
* @param table
* 表名
* @param whereClause
* 條件語句,可以使用佔位符
* @param whereArgs
* 使用該陣列中的值替換佔位符
* @return 受影響資料的行數
*/
public int delete(String table, String whereClause, String[] whereArgs) {
return db.delete(table, whereClause, whereArgs);
}
/**
* 查詢資料
*
* @param sql
* sql語句,查詢語句,可以包含條件,sql語句不用使用分號結尾,系統自動新增
* @param selectionArgs
* sql的查詢條件可以使用佔位符,佔位符可以使用selectionArgs的值替代
* @return Cursor 遊標,可以比作結果集
*/
public Cursor select(String sql, String[] selectionArgs) {
return db.rawQuery(sql, selectionArgs);
}
/**
* 查詢資料
*
* @param table
* 表名
* @param columns
* 查詢的列(欄位)
* @param selection
* where後的條件子句,可以使用佔位符
* @param selectionArgs
* 替換佔位符的值,
* @param groupBy
* 根據某個欄位進行分組
* @param having
* 分組之後再進一步過濾
* @param orderBy
* 排序
* @return Cursor 遊標,可以比作結果集
*/
public Cursor select(String table, String[] columns, String selection,
String[] selectionArgs, String groupBy, String having,
String orderBy) {
// distinct: 消除重複資料項(去掉重複項)
// 1、table: 表名
// 2、columns: 查詢的列(欄位)
// 3、selection: where後的條件子句,可以使用佔位符
// 4、selectionArgs: 替換佔位符的值
// 5、groupBy: 根據某個欄位進行分組
// 6、having: 分組之後再進一步過濾
// 7、orderBy: 排序
// limit: 進行分頁查詢
return db.query(table, columns, selection, selectionArgs, groupBy,
having, orderBy);
}
public void close() {
if (db != null) {
db.close();
}
}
}
③、建立一個PhoneManagerActivity頁面,實現顯示,新增及修改,刪除受保護的聯絡人的電話號碼及姓名資訊
佈局檔案:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="@+id/lv_phone"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
在ActionBar中添加了新增按鈕
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.protect.sms.activity.PhoneManagerActivity" >
<item
android:id="@+id/action_add"
android:icon="@drawable/button_03"
android:orderInCategory="100"
android:showAsAction="always"
android:title="新增"/>
</menu>
PhoneManagerActivity頁面處理增加的時間,及處理ListView點選和長按彈出選單的事件
public class PhoneManagerActivity extends Activity {
private ProtectedDAO pd;
private ListView lv_phone;
private SimpleCursorAdapter adapter;
private Cursor cursor;
private int position;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_phone_manager);
pd = new ProtectedDAO(this);
lv_phone = (ListView) findViewById(R.id.lv_phone);
flushList();
registerForContextMenu(lv_phone);
}
private void flushList() {
cursor = pd.select("protectedPhone", new String[] { "_id", "person",
"phone" }, null, null, null, null, null);
adapter = new SimpleCursorAdapter(this, R.layout.phonelist_item,
cursor, new String[] { "person", "phone" }, new int[] {
R.id.tv_phone_name, R.id.tv_phone_address },
SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
lv_phone.setAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.phone_manager, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_add) {
View view = getLayoutInflater().inflate(R.layout.add_item, null);
final EditText et_phone = (EditText) view
.findViewById(R.id.et_phone);
final EditText et_name = (EditText) view.findViewById(R.id.et_name);
Builder builder = new AlertDialog.Builder(this)
.setIcon(R.drawable.ic_launcher).setTitle("新增受保護的電話號碼")
.setView(view)
.setPositiveButton("新增", new OnClickListener() {
@SuppressWarnings("deprecation")
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
String phone = et_phone.getText().toString().trim();
Cursor select = pd.select("protectedPhone",
new String[] { "_id", "person", "phone" },
" phone =?", new String[] { phone }, null,
null, null);
if (select.moveToNext()) {
Toast.makeText(PhoneManagerActivity.this,
"您已新增過該號碼,不能重複新增!", Toast.LENGTH_SHORT)
.show();
} else {
String name = et_name.getText().toString();
ProtectedDAO pd = new ProtectedDAO(
PhoneManagerActivity.this);
ContentValues values = new ContentValues();
values.put("person", name);
values.put("phone", phone);
long l = pd.insert("protectedPhone", values);
if (l > 0) {
Toast.makeText(PhoneManagerActivity.this,
"新增保護成功", Toast.LENGTH_LONG).show();
cursor.requery();
}
}
}
}).setNegativeButton("取消", null).setCancelable(false);
builder.show();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if (pd != null) {
pd.close();
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
// TODO Auto-generated method stub
super.onCreateContextMenu(menu, v, menuInfo);
getMenuInflater().inflate(R.menu.phone_menu, menu);
AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
position = acmi.position;
}
@SuppressWarnings("deprecation")
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
// TODO Auto-generated method stub
switch (item.getItemId()) {
case R.id.action_update:
View view = getLayoutInflater().inflate(R.layout.add_item, null);
final EditText et_phone = (EditText) view
.findViewById(R.id.et_phone);
final EditText et_name = (EditText) view.findViewById(R.id.et_name);
final Cursor c = (Cursor) (adapter.getItem(position));
et_name.setText(c.getString(c.getColumnIndex("person")));
et_phone.setText(c.getString(c.getColumnIndex("phone")));
Builder builder = new AlertDialog.Builder(this)
.setIcon(R.drawable.ic_launcher).setTitle("修改聯絡人資訊")
.setView(view)
.setPositiveButton("修改", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
String phone = et_phone.getText().toString().trim();
Cursor select = pd.select("protectedPhone",
new String[] { "_id", "person", "phone" },
" phone =?", new String[] { phone }, null,
null, null);
if (select.moveToNext()) {
Toast.makeText(PhoneManagerActivity.this,
"您已新增過該號碼,不能重複新增!", Toast.LENGTH_SHORT)
.show();
} else {
String name = et_name.getText().toString();
ProtectedDAO pd = new ProtectedDAO(
PhoneManagerActivity.this);
ContentValues values = new ContentValues();
values.put("person", name);
values.put("phone", phone);
long l = pd.update(
"protectedPhone",
values,
" _id = ?",
new String[] { c.getInt(c
.getColumnIndex("_id")) + "" });
if (l > 0) {
Toast.makeText(PhoneManagerActivity.this,
"修改成功", Toast.LENGTH_LONG).show();
cursor.requery();
} else {
Toast.makeText(PhoneManagerActivity.this,
"修改失敗", Toast.LENGTH_LONG).show();
}
}
}
}).setNegativeButton("取消", null).setCancelable(false);
builder.show();
break;
case R.id.action_delete:
Builder builder1 = new AlertDialog.Builder(this)
.setIcon(R.drawable.ic_launcher).setTitle("刪除聯絡人資訊")
.setMessage("刪除該聯絡人資訊以後,您與該聯絡人之間的簡訊將不會受到保護,是否繼續刪除?")
.setPositiveButton("刪除", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
Cursor c = (Cursor) (adapter.getItem(position));
pd.delete(
"protectedPhone",
"_id = ?",
new String[] { c.getInt(c
.getColumnIndex("_id")) + "" });
cursor.requery();
}
}).setNegativeButton("取消", null).setCancelable(false);
builder1.show();
break;
}
cursor.requery();
return super.onMenuItemSelected(featureId, item);
}
}
④、靜態註冊廣播接收器,實現廣播接收器攔截簡訊的功能
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.protect.sms.activity"
android:versionCode="1"
android:versionName="1.0" >
<!-- 必須開啟的許可權 -->
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<!-- 靜態註冊廣播接收器 priority:優先順序,越大越好,但不能超過9999-->
<receiver android:name=".ProtectedSMSReceiver" >
<intent-filter android:priority="1000" >
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
建立廣播接收器,處理onReceive()方法,先獲取簡訊的來源地址,即電話號碼,根據該電話號碼在受保護的聯絡人資料庫(protectedPhone)資訊中查詢,若查詢到該聯絡人資訊,則進行攔截,儲存到資料庫,否則,不做處理,傳送到手機簡訊
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
if ("android.provider.Telephony.SMS_RECEIVED".equals(action)) {
// StringBuffer sb = new StringBuffer();
// 接收有SMS傳遞的資料
Bundle bundle = intent.getExtras();
// 判斷是否有資料
if (bundle != null) {
// 通過pdus可以獲得接收到的所有簡訊訊息
Object[] pdus = (Object[]) bundle.get("pdus");
// 構建簡訊物件array,並依據收到的物件長度來建立array的大小
SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
for (SmsMessage message : messages) {
// 獲得簡訊來源
String address = message.getDisplayOriginatingAddress();
if (address.startsWith("+86")) {
address = address.substring(address.indexOf("+86")
+ "+86".length());
}
String person = null;
ProtectedDAO pd = new ProtectedDAO(context);
Cursor cursor = pd.select("protectedPhone", new String[] {
"person", "phone" }, "phone = ?",
new String[] { address }, null, null, null);
if (cursor.moveToNext()) {
String body = message.getDisplayMessageBody();
String date = formatDate(message.getTimestampMillis());
int type = 1;
int state = 0;
person = cursor.getString(cursor
.getColumnIndex("person"));
ContentValues values = new ContentValues();
values.put("address", address);
values.put("type", type);
values.put("state", state);
values.put("body", body);
values.put("date", date);
values.put("person", person);
long l = pd.insert("psms", values);
if (l > 0) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(
context);
builder.setContentTitle((person == null || "null"
.equals(person)) ? address : person);
builder.setContentText(body);
builder.setContentInfo(date);
builder.setDefaults(Notification.DEFAULT_ALL);
builder.setSmallIcon(R.drawable.ic_launcher);
// builder.setSmallIcon(R.drawable.ic_launcher);//設定小圖示
// Notification notification = builder.build();//
// 建立通知
// 通過系統服務,建立通知管理器
NotificationManager manager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
// 傳送通知:引數1:通知的唯一標識,引數2:通知的物件
Intent intent1 = new Intent(context,
DetailsActivity.class);
Bundle bd = new Bundle();
bd.putString("address", address);
bd.putInt("type", type);
bd.putInt("state", state);
bd.putString("body", body);
bd.putString("date", date);
intent1.putExtras(bd);
PendingIntent pIntent = PendingIntent.getActivity(
context, 101, intent1,
PendingIntent.FLAG_ONE_SHOT);
builder.setContentIntent(pIntent);
manager.notify(101, builder.build());
// 中止傳送通知
abortBroadcast();
}
}
}
}
}
}
//格式化時間,即將毫秒數轉換成“yyyy-MM-dd HH:mm:ss”的時間
@SuppressLint("SimpleDateFormat")
public String formatDate(long millis) {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = df.format(new Date(millis));
return date;
}
原理就是這樣,具體程式碼過多,這裡將不再進行展示。。。。。。
原始碼下載 :http://download.csdn.net/detail/qq_20538515/9174971
謝謝支援!