strColumnName=_id strColumnValue=48 //短消息序号
strColumnName=thread_id strColumnValue=16 //对话的序号(conversation)
strColumnName=address strColumnValue=+8613411884805 //发件人地址,手机号
strColumnName=person strColumnValue=null //发件人,返回一个数字就是联系人列表里的序号,陌生人为null
strColumnName=date strColumnValue=1256539465022 //日期 long型,想得到具体日期自己转换吧!
strColumnName=protocol strColumnValue=0 //协议
strColumnName=read strColumnValue=1 //是否阅读
strColumnName=status strColumnValue=-1 //状态
strColumnName=type strColumnValue=1 //类型 1是**到的,2是发出的
strColumnName=reply_path_present strColumnValue=0 //
strColumnName=subject strColumnValue=null //主题
strColumnName=body strColumnValue=您好 //短消息内容
strColumnName=service_center strColumnValue=+8613800755500 //短信服务中心号码编号,可以得知该短信
package com.app.utils;
import android.annotation.SuppressLint;
import android.app.AppOpsManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.CallLog;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class SmsUtil {
private final String TAG = SmsUtil.class.getSimpleName();
private final String TAG1 = "AEESmsObserver";
private final String SMS_MGR = "android.telephony.SmsManager";
public final static String SENT_SMS_ACTION = "SENT_SMS_ACTION";
private static SmsUtil mInstance = null;
private static int smsId = 0;
public final static String SMS_URI_ALL ="content://sms/";
public final static String SMS_URI_INBOX ="content://sms/inbox";
public final static String SMS_URI_SEND ="content://sms/sent";
public final static String SMS_URI_DRAFT ="content://sms/draft";
public final static String SMS_URI_OUTBOX = "content://sms/outbox";
public final static String SMS_URI_FAILED ="content://sms/failed";
public final static String SMS_URI_QUEUED ="content://sms/queued";
protected SmsUtil() {
}
public static SmsUtil getInst() {
if (mInstance == null) {
mInstance = new SmsUtil();
}
return mInstance;
}
public static SmsManager getSmsManager(Context context) {
//if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
if (Build.VERSION.SDK_INT > 21) {
return getSmsManager22(context);
//} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
} else if (Build.VERSION.SDK_INT == 21) {
return getSmsManager21(context);
} else {
return SmsManager.getDefault();
}
}
private static SmsManager getSmsManager21(Context context) {
try {
Class<SmsManager> clazz = SmsManager.class;
Method method = clazz.getMethod("getSmsManagerForSubscriber",
new Class[]{Long.TYPE});
method.setAccessible(true);
long subid = (long) getSubId(context);
try {
return (SmsManager) method.invoke(null, new Object[]{subid});
} catch (Exception e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return SmsManager.getDefault();
}
private static SmsManager getSmsManager22(Context context) {
try {
Class<SmsManager> clazz = SmsManager.class;
Method method = clazz.getMethod("getSmsManagerForSubscriptionId",
new Class[]{Integer.TYPE});
method.setAccessible(true);
int subid = getSubId(context);
return (SmsManager) method.invoke(null, new Object[]{subid});
} catch (Exception e) {
e.printStackTrace();
return SmsManager.getDefault();
}
}
private static int getSubId(Context context) {
Uri uri = Uri.parse("content://telephony/siminfo");
Cursor cursor = context.getContentResolver().query(uri,
null, null, null, "sim_id desc");
if (cursor == null) {
return -1;
}
do {
int subId = cursor.getInt(cursor.getColumnIndex("_id"));
int simId = cursor.getInt(cursor.getColumnIndex("sim_id"));
if (simId == 0 || simId == 1) {
cursor.close();
return subId;
}
}
while (cursor.moveToNext());
cursor.close();
return -1;
}
public void sendDataMessage(Context context, BroadcastReceiver sendReceiver,
String to, byte[] content) {
Log.i(TAG, "sendDataMessage() to=" + to);
if (content != null && !TextUtils.isEmpty(to)) {
try {
Intent sentIntent = new Intent(SENT_SMS_ACTION);
sentIntent.putExtra("sms_id", ++smsId);
sentIntent.putExtra("sms_to", to);
Log.i(TAG, "sendDataMessage() id=" + smsId);
PendingIntent sentPI = PendingIntent.getBroadcast(context, smsId, sentIntent,
PendingIntent.FLAG_CANCEL_CURRENT); //保证Bundle数据更更新
context.registerReceiver(sendReceiver, new IntentFilter(SENT_SMS_ACTION));
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendDataMessage(to, null, (short) 0, content, sentPI, null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void sendTextMessage(Context context, BroadcastReceiver sendReceiver,
String to, String content) {
Log.i(TAG, "sendTextMessage() to=" + to);
if (content != null && !TextUtils.isEmpty(to) && !TextUtils.isEmpty(content)) {
try {
Intent sentIntent = new Intent(SENT_SMS_ACTION);
sentIntent.putExtra("sms_id", ++smsId);
sentIntent.putExtra("sms_to", to);
Log.i(TAG, "sendTextMessage() id=" + smsId);
PendingIntent sentPI = PendingIntent.getBroadcast(context, smsId, sentIntent,
PendingIntent.FLAG_CANCEL_CURRENT); //保证Bundle数据更更新
context.registerReceiver(sendReceiver, new IntentFilter(SENT_SMS_ACTION));
SmsManager smsManager = getSmsManager(context);
List<String> divideContents = smsManager.divideMessage(content);
for (String text : divideContents) {
smsManager.sendTextMessage(to, null, text, sentPI, null);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void unRegiReceiver(Context context, BroadcastReceiver receiver) {
Log.i(TAG, "unRegiReceiver()");
if (context != null && receiver != null) {
context.unregisterReceiver(receiver);
}
}
/*public boolean deleteSms(Context context, String smsTo) {
Log.i(TAG1, "deleteSms() smsTo:" + smsTo);
if (context == null || smsTo == null) {
return false;
}
try {
Uri smsUrl = Uri.parse("content://sms");
ContentResolver cr = context.getContentResolver();
int dNum = cr.delete(smsUrl, "address=?", new String[]{smsTo});
Log.i(TAG1, "resolver.delete(smsUrl) dNum:" + dNum);
//int dNum2 = cr.delete(smsUrl, "address=" + smsTo, null);
//Log.i(TAG, "resolver.delete(smsUrl) dNum2:" + dNum2);
return dNum > 0;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}*/
public boolean deleteSms(Context context, String thread_id) {
try {
if (!isWriteEnabled(context.getApplicationContext())) {
setWriteEnabled(
context.getApplicationContext(), true);
}
ContentResolver CR = context.getContentResolver();
// Query SMS
Uri uriSms = Uri.parse(SMS_URI_ALL);
Cursor c = CR.query(uriSms, new String[]{"_id", "thread_id"},
null, null, null);
if (null != c && c.moveToFirst()) {
do {
// Delete SMS
long threadId = c.getLong(1);
int id = c.getInt(0);
if(Long.parseLong(thread_id) == threadId) {
int result = CR.delete(Uri
.parse("content://sms/conversations/" + threadId),
null, null);
LogUtils.i("threadId:: " + threadId + " result::"
+ result);
}
} while (c.moveToNext());
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
public boolean deleteSms(Context context, String _Id, String thread_id) {
try {
if (!isWriteEnabled(context.getApplicationContext())) {
setWriteEnabled(
context.getApplicationContext(), true);
}
ContentResolver CR = context.getContentResolver();
// Query SMS
Uri uriSms = Uri.parse("content://sms");
Cursor c = CR.query(uriSms, new String[]{"_id", "thread_id"},
null, null, null);
if (null != c && c.moveToFirst()) {
do {
// Delete SMS
long threadId = c.getLong(1);
int id = c.getInt(0);
LogUtils.i("deleteSms _Id = "+_Id+", id = "+id
+", threadId = "+threadId);
if(id == Long.parseLong(_Id)) {
int result = CR.delete(Uri
.parse("content://sms/conversations/" + threadId),
"_id=?", new String[]{_Id});
LogUtils.i("threadId:: " + threadId + " result::"
+ result);
break;
}
} while (c.moveToNext());
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
public boolean deleteSms(Context context, Cursor cursor) {
int colIndex = cursor.getColumnIndexOrThrow("thread_id");
String threadId = cursor.getString(colIndex);
int colIndexId = cursor.getColumnIndexOrThrow("_id");
String _id = cursor.getString(colIndexId);
Log.i(TAG1, "deleteSms() id:" + _id);
try {
//if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //5.0及以上
// if (Build.VERSION.SDK_INT >= 21) { //5.0及以上
// Log.i(TAG, "Build.VERSION.SDK_INT:" + Build.VERSION.SDK_INT);
// long convId = Long.parseLong(threadId);
// Log.i(TAG, "deleteStoredConversation() convId:" + convId);
// boolean ret = deleteStoredConversation(context, convId);
// Log.i(TAG, "deleteStoredConversation() ret:" + ret);
// return ret;
// } else {
// Uri convUrl = Uri.parse("content://sms/conversations/" + threadId);
// ContentResolver cr = context.getContentResolver();
//
// long convId = Long.parseLong(threadId);
// int dNum = cr.delete(Uri
// .parse("content://sms/conversations/" + convId),
// null, null);
// Log.d(TAG, "threadId:: " + threadId + " result::"
// + dNum);
// //int id = cursor.getInt(cursor.getColumnIndex("_id"));
// //int dNum =cr.delete(Uri.parse("content://sms/"),"_id=?",
// // new String[]{ String.valueOf(id)});
//
// //int dNum = cr.delete(convUrl, "_id=?", new String[]{_id});
// Log.i(TAG, "resolver.delete(convUrl) dNum:" + dNum);
// return dNum > 0;
if (!isWriteEnabled(context.getApplicationContext())) {
setWriteEnabled(
context.getApplicationContext(), true);
}
deleteSMS(context.getApplicationContext());
// }
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
private boolean deleteStoredConversation(Context context, long conversationId) {
Log.i(TAG, "deleteSms() conversationId:" + conversationId);
try {
Class<?> cls = Class.forName(SMS_MGR);
Method method = cls.getMethod("deleteStoredConversation",
new Class[]{long.class});
SmsManager smsManager = SmsUtil.getSmsManager(context);
Object obj = method.invoke(smsManager, conversationId);
if (obj instanceof Boolean) {
return (Boolean) obj;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public void deleteSMS(Context context) {
try {
ContentResolver CR = context.getContentResolver();
// Query SMS
Uri uriSms = Uri.parse("content://sms/inbox");
Cursor c = CR.query(uriSms, new String[] { "_id", "thread_id" },
null, null, null);
if (null != c && c.moveToFirst()) {
do {
// Delete SMS
long threadId = c.getLong(1);
int result = CR.delete(Uri
.parse("content://sms/conversations/" + threadId),
null, null);
Log.d(TAG1, "threadId:: " + threadId + " result::"
+ result);
} while (c.moveToNext());
}
} catch (Exception e) {
Log.d(TAG1, "Exception:: " + e);
}
}
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 {
@SuppressLint("WrongConstant") int uid = context.getPackageManager().getApplicationInfo(
context.getPackageName(), PackageManager.GET_SERVICES).uid;
return uid;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return 0;
}
}
public static void obtainPhoneMessage(Context context, List<SMSInfo> list,
List<String> threadidlist) {
try {
Uri SMS_INBOX = Uri.parse(SMS_URI_ALL);
ContentResolver cr = context.getContentResolver();
String[] projection = new String[]{"_id", "address", "person", "body",
"date", "read", "thread_id", "type"};
Cursor cur = cr.query(SMS_INBOX, projection, null,
null, "date desc");
if (null == cur) {
LogUtils.i("cur == null");
return;
}
cur.moveToFirst();
while (cur.isAfterLast() == false) {
String _id = cur.getString(cur.getColumnIndex("_id"));//短信id
String address = cur.getString(cur.getColumnIndex("address"));//手机号
String person = cur.getString(cur.getColumnIndex("person"));//联系人姓名列表
//String body = cur.getString(cur.getColumnIndex("body"));//短信内容
String date = cur.getString(cur.getColumnIndex("date"));//短信时间
String read = cur.getString(cur.getColumnIndex("read"));//短信是否已读
String thread_id = cur.getString(cur.getColumnIndex("thread_id"));//
String type = cur.getString(cur.getColumnIndex("type"));//
LogUtils.i("obtainPhoneMessage type = " + type + ", thread_id = " + thread_id);
if (threadidlist != null && !threadidlist.contains(thread_id)) {
SMSInfo sms = new SMSInfo(_id, person, date, read, address, thread_id);
list.add(sms);
threadidlist.add(thread_id);
} else {
for (int i = 0; i < list.size(); i++) {
SMSInfo sms = list.get(i);
LogUtils.i("obtainPhoneMessage thread_id = " + thread_id
+ ", getThread_id = " + sms.getThread_id());
if (sms.getThread_id() == thread_id) {
SMSInfo sms2 = list.get(i);
if (sms2.getRead().equals("0")) {
read = "0";
}
list.remove(i);
SMSInfo sms1 = new SMSInfo(_id, address, date, read, person, thread_id);
list.add(sms1);
break;
}
}
}
cur.moveToNext();
}
}
catch (Exception e){
}
}
public static void obtainPhoneConversationsMessage(Context context, List<SMSInfo> list) {
Uri SMS_INBOX = Uri.parse(SMS_URI_OUTBOX);
ContentResolver cr = context.getContentResolver();
// String[] projection = new String[]{"_id", "address", "person", "body", "date", "read",
// "thread_id"};
String[] projection = new String[]{"_id", "address"};
Cursor cur = cr.query(SMS_INBOX, projection, null, null, "date desc");
if (null == cur) {
LogUtils.i("cur == null");
return;
}
cur.moveToFirst();
do {
String _id = cur.getString(cur.getColumnIndex("_id"));//短信id
String address = cur.getString(cur.getColumnIndex("address"));//手机号
String person = cur.getString(cur.getColumnIndex("person"));//联系人姓名列表
//String body = cur.getString(cur.getColumnIndex("body"));//短信内容
String date = cur.getString(cur.getColumnIndex("date"));//短信时间
String read = cur.getString(cur.getColumnIndex("read"));//短信是否已读
String thread_id = cur.getString(cur.getColumnIndex("thread_id"));//
SMSInfo sms = new SMSInfo(_id, address, date, read, person, thread_id);
list.add(sms);
}
while (cur.moveToNext());
}
public static String obtainPhoneMessageByMsgId(Context context, int smsId) {
try{
Uri SMS_INBOX = Uri.parse("content://sms/");
ContentResolver cr = context.getContentResolver();
String[] projection = new String[]{"_id", "address", "person",
"body", "date", "type"};
Cursor cur = cr.query(SMS_INBOX, projection, null,
null, "date desc");
if (null == cur) {
LogUtils.i("cur == null");
return "";
}
do{
int id = cur.getInt(cur.getColumnIndex("_id"));//短信id
if(id == smsId) {
String body = cur.getString(cur.getColumnIndex("body"));//短信内容
return body;
}
}
while (cur.moveToNext());
}
catch (Exception e){
}
return "";
}
/**
* 更新短信为已读
* */
public static void updatePhoneMessageByMsgId(Context context,
String thread_id) {
int result = 0;
try {
if (!isWriteEnabled(context.getApplicationContext())) {
setWriteEnabled(
context.getApplicationContext(), true);
}
Uri SMS_INBOX = Uri.parse("content://sms/conversations/");
ContentResolver cr = context.getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put("read", "1");
contentValues.put("thread_id", thread_id);
result = cr.update(SMS_INBOX, contentValues,
"thread_id = ?", new String[]{thread_id});
}
catch (Exception e){
}
}
public static boolean isNumeric(String str){
Pattern pattern = Pattern.compile("[0-9]*");
Matcher isNum = pattern.matcher(str);
if( !isNum.matches() ){
return false;
}
return true;
}
}