以下代码均有注释,个人学习,运行无异常,若有疑问或建议欢迎留言,大家一起讨论进步~
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