Android获取短信、监听短信数据库变化、删除短信

奋斗奋斗以下代码均有注释,个人学习,运行无异常,若有疑问或建议欢迎留言,大家一起讨论进步~奋斗奋斗

MainActivity:

public class MainActivity extends Activity {
    /**
     * 信息列表
     */
    private Uri SMS_ALL = Uri.parse("content://sms/");  //全部短信
    private ListView session_listView;
    private List<MesInfo> list;  //封装数据
    private MesBaseAdapter mesBaseAdapter;  //信息数据
    private SmsObserver smsObserver;  //监控数据库变化

    private Handler smsHandler = new Handler() {

    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        /**
         * 信息列表
         */
        session_listView = (ListView) findViewById(R.id.session_list);
        List<MesInfo> lists = getSMSInfo();  //获取全部短信内容
        mesBaseAdapter = new MesBaseAdapter((List<MesInfo>) lists, context);  //将短信内容List传递到适配器(显示)
        session_listView.setAdapter(mesBaseAdapter);  //绑定适配器
        smsObserver = new SmsObserver(this, smsHandler);  //实例化内容观察者的子类
        getContentResolver().registerContentObserver(SMS_ALL, true, smsObserver);  //注册内容观察者
                    /**
                     * 删除短信
                     */
                    Button all_delete = (Button) findViewById(R.id.all_delete);
                    all_delete.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                                //动态获取权限
                                if (!SmsWriteOpUtil.isWriteEnabled(getApplicationContext())) {
                                    SmsWriteOpUtil.setWriteEnabled(getApplicationContext(), true);
                                }
                                deleteSMS();  //执行删除
                        }
                    });
                } 
            }
        });

    }
    /**
     * 获取短信信息
     */
    private List<MesInfo> getSMSInfo() {

        String[] field = {"_id", "address", "person", "body", "date", "type"};  //字段
        ContentResolver contentResolver = this.getContentResolver();  //内容解析器(数据共享)——读取短信内容
        Cursor cursor = contentResolver.query(SMS_ALL, field, null, null, "date desc");  //获取短信内容
        if (cursor == null) {  //游标无内容
            return null;
        }
        list = new ArrayList<MesInfo>();
        while (cursor.moveToNext()) {
            String phoneNumber = cursor.getString(cursor.getColumnIndex("address"));  //手机号
            String name = cursor.getString(cursor.getColumnIndex("person"));  //联系人
            String body = cursor.getString(cursor.getColumnIndex("body"));  //短信内容
            //格式化短信日期
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm");
            Date time = new Date(Long.parseLong(cursor.getString(cursor.getColumnIndex("date"))));
            String date = simpleDateFormat.format(time);
            //保存短信信息
            list.add(new MesInfo(name, phoneNumber, date, body));
        }
        return list;
    }

    /**
     * 监听数据库变化(短信数的变化)
     */
    class SmsObserver extends ContentObserver {

        public SmsObserver(Context context, Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            List<MesInfo> lists = getSMSInfo();
            //绑定适配器,显示变化后的数据
            mesBaseAdapter = new MesBaseAdapter((List<MesInfo>) lists, context);
            session_listView.setAdapter(mesBaseAdapter);
        }
    }

    /**
     * 删除短信
     */
    public void deleteSMS() {
        ContentResolver cr = this.getContentResolver();  //内容解析器(数据共享)——读取短信内容
        Cursor cur = cr.query(SMS_ALL, new String[]{"_id", "thread_id"}, null, null, null);  //获取短信内容
        if (cur != null && cur.moveToFirst()) {
            do {
                long threadId = cur.getLong(1);
                cr.delete(Uri.parse("content://sms/conversations/" + threadId), null, null);
            } while (cur.moveToNext());
        }
    }
}

MesInfo:

package com.example.mjon.smssystem;

/**
 * 封装短信数据
 */

public class MesInfo {

    private String name;
    private String phoneNumber;
    private String date;
    private String message;

    public MesInfo(String name, String phoneNumber, String date, String message) {
        this.name = name;
        this.phoneNumber = phoneNumber;
        this.date = date;
        this.message = message;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
自定义BaseAdapter:


package com.example.mjon.smssystem;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.RadioButton;
import android.widget.TextView;

import java.util.List;

/**
 * 显示信息内容列表
 */

public class MesBaseAdapter extends BaseAdapter {

    private List<MesInfo> iData;
    private Context context;

    public MesBaseAdapter(List<MesInfo> iData, Context context) {
        this.iData = iData;
        this.context = context;
    }

    @Override
    public int getCount() {
        return iData.size();
    }

    @Override
    public Object getItem(int i) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View view, ViewGroup viewGroup) {
        view = LayoutInflater.from(context).inflate(R.layout.activity_main_session_list, viewGroup, false);  //关联布局
        //获取控件
        RadioButton session_radio = (RadioButton)view.findViewById(R.id.session_radio);
        TextView session_user_phoneNumber = (TextView)view.findViewById(R.id.session_user_phoneNumber);
        TextView session_user_time = (TextView)view.findViewById(R.id.session_user_time);
        TextView session_user_message = (TextView)view.findViewById(R.id.session_user_message);
        //设置控件
        session_user_phoneNumber.setText(iData.get(position).getPhoneNumber());
        session_user_time.setText(iData.get(position).getDate());
        session_user_message.setText(iData.get(position).getMessage());
        //返回视图对象
        return view;
    }

}

SmsWriteOpUtil(动态获取删除短信权限,针对4.4及以上版本的变化)

package com.example.mjon.smssystem;

import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.PackageManager;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 动态获得权限
 */

public final class SmsWriteOpUtil {
    private static final int OP_WRITE_SMS = 15;

    public static boolean isWriteEnabled(Context context) {
        int uid = getUid(context);
        Object opRes = checkOp(context, OP_WRITE_SMS, uid);

        if (opRes instanceof Integer) {
            return (Integer) opRes == AppOpsManager.MODE_ALLOWED;
        }
        return false;
    }

    public static boolean setWriteEnabled(Context context, boolean enabled) {
        int uid = getUid(context);
        int mode = enabled ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED;
        return setMode(context, OP_WRITE_SMS, uid, mode);
    }

    private static Object checkOp(Context context, int code, int uid) {
        AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        Class appOpsManagerClass = appOpsManager.getClass();
        try {
            Class[] types = new Class[3];
            types[0] = Integer.TYPE;
            types[1] = Integer.TYPE;
            types[2] = String.class;
            Method checkOpMethod = appOpsManagerClass.getMethod("checkOp", types);
            Object[] args = new Object[3];
            args[0] = Integer.valueOf(code);
            args[1] = Integer.valueOf(uid);
            args[2] = context.getPackageName();
            Object result = checkOpMethod.invoke(appOpsManager, args);
            return result;
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static boolean setMode(Context context, int code, int uid, int mode) {
        AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        Class appOpsManagerClass = appOpsManager.getClass();
        try {
            Class[] types = new Class[4];
            types[0] = Integer.TYPE;
            types[1] = Integer.TYPE;
            types[2] = String.class;
            types[3] = Integer.TYPE;
            Method setModeMethod = appOpsManagerClass.getMethod("setMode", types);
            Object[] args = new Object[4];
            args[0] = Integer.valueOf(code);
            args[1] = Integer.valueOf(uid);
            args[2] = context.getPackageName();
            args[3] = Integer.valueOf(mode);
            setModeMethod.invoke(appOpsManager, args);
            return true;
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return false;
    }

    private static int getUid(Context context) {
        try {
            int uid = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_SERVICES).uid;
            return uid;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return 0;
        }
    }

}

AndroidManifest.xml:

<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS" />

注意:刚开始在没有动态获取权限时,即使在AndroidManifest.xml文件中添加了权限也出现无法删除短信的情况。因为从Andrid 4.4版本开始,不是默认的短信应用就无法删除短信了,不过我们可以通过在apk中利用反射来调用AppOpsManager,再利用setMode方法来为自己的应用获取权限。AndroidManifest.xml里的权限不可省略~

参考文章:Android 4.4


猜你喜欢

转载自blog.csdn.net/march0000/article/details/80174705