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" >

        
        <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
谢谢支持!

你可能感兴趣的:(Android,Android/NDK开发)