1. 程式人生 > >Android 利用廣播實現黑名單【指定號碼】的簡訊的攔截 附原始碼下載連結

Android 利用廣播實現黑名單【指定號碼】的簡訊的攔截 附原始碼下載連結

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
謝謝支援!