测试机为 华为 8C,Android 版本 8.1.0。
<!-- 读短信权限 --> <uses-permission android:name="android.permission.READ_SMS" />
动态申请权限代码此处略过。
注册监听:
MmsDatabaseChangeObserver mmsObserver = new MmsDatabaseChangeObserver(getContentResolver(), new Handler(Looper.getMainLooper())); getContentResolver().registerContentObserver(MMS_MESSAGE_URI, true, mmsObserver);
废话不多说,直接上代码:
import android.content.ContentResolver; import android.database.ContentObserver; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Environment; import android.os.Handler; import android.text.TextUtils; import android.util.Log; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.text.MessageFormat; /** * @author zsl * @date 2019/9/20. * <p> * 监听彩信 * </p> */ public class MmsDatabaseChangeObserver extends ContentObserver { private final String TAG = "mms.zsl"; public static final Uri MMS_MESSAGE_URI = Uri.parse("content://mms-sms"); private final ContentResolver resolver; /** * Creates a content observer. * * @param handler The handler to run {@link #onChange} on, or null if none. */ public MmsDatabaseChangeObserver(ContentResolver resolver, Handler handler) { super(handler); this.resolver = resolver; } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); try { //查彩信id、日期(秒)、主题 // 此时查的是 pdu 表 Cursor pduCur = resolver.query(Uri.parse("content://mms"), new String[]{"_id", "date", "sub"}, null, null, // 根据 id 排序 "_id asc"); //日期:彩信数据库中存的单位是秒 long date = 0; int pduId = -1; // 主题 String sub = ""; if (pduCur != null && pduCur.getCount() > 0) { pduCur.moveToLast(); pduId = pduCur.getInt(pduCur.getColumnIndex("_id")); Log.e(TAG, "onChange: pduId=" + pduId); date = pduCur.getLong(pduCur.getColumnIndex("date")); sub = pduCur.getString(pduCur.getColumnIndex("sub")); try { if (!TextUtils.isEmpty(sub)) { // 防止乱码 sub = new String(sub.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); } } catch (Exception e) { e.printStackTrace(); } pduCur.close(); } Object body = getMmsBody(pduId); String address = getMmsAddress(pduId); String mmsData = "\n" + pduId + "\n" + sub + "\n" + body + "\n" + date + "\n" + address; Log.e(TAG, "onChange: " + mmsData); } catch (Exception e) { e.printStackTrace(); Log.e(TAG, "onChange: ", e); } } /** * 查号码 * * @param pduId 彩信 id * @return 彩信发送对象的号码 */ private String getMmsAddress(int pduId) { String address = ""; String numberUri = MessageFormat.format("content://mms/{0}/addr", pduId); Cursor addCur = resolver.query(Uri.parse(numberUri), new String[]{"address"}, null, null, null); if (addCur != null) { addCur.moveToLast(); address = addCur.getString(addCur.getColumnIndex("address")); addCur.close(); } else { Log.e(TAG, "onChange: addCur is null"); } return address; } /** * 查附件内容 * * @param pduId 彩信 id * @return 彩信附件内容 */ private Object getMmsBody(int pduId) { Object body = null; // 查 part 表 Cursor cursor = resolver.query(Uri.parse("content://mms/part"), null, "mid=" + pduId, null, null); if (cursor != null && cursor.getCount() > 0) { cursor.moveToLast(); // part表 ct 字段 标识此part内容类型,彩信始末:application/smil; // 文本附件:text/plain;图像附件:jpg:image/jpeg,gif:image/gif..;音频附件:audio/amr String type = cursor.getString(cursor.getColumnIndex("ct")); Log.e(TAG, "onChange: type=" + type); String text = "text/plain"; if (text.equals(type)) { String data = cursor.getString(cursor.getColumnIndex("_data")); Log.e(TAG, "onChange: data=" + data); if (data != null) { int id = cursor.getInt(cursor.getColumnIndex("_id")); Log.e(TAG, "onChange: _id=" + id); body = getMmsText(id); } } else { boolean isImage = "image/jpeg".equals(type) || "image/bmp".equals(type) || "image/gif".equals(type) || "image/png".equals(type) || "image/jpg".equals(type); if (isImage) { String data = cursor.getString(cursor.getColumnIndex("_data")); Log.e(TAG, "onChange: data=" + data); if (data != null) { int id = cursor.getInt(cursor.getColumnIndex("_id")); Log.e(TAG, "onChange: _id=" + id); body = getMmsImage(id); } } else { String audio = "audio/amr"; if (audio.equals(type)) { String audioPath = cursor.getString(cursor.getColumnIndex("fn")); Log.e(TAG, "onChange: fn=" + audioPath); if (!TextUtils.isEmpty(audioPath)) { // 华为 8C 测试机 语音彩信文件存放在 内部存储/Recordings/ 目录中 String audioDir = Environment.getExternalStorageDirectory() + "/Recordings/"; body = audioDir + audioPath; } } else { body = cursor.getString(cursor.getColumnIndex("text")); } } } cursor.close(); } return body; } /** * 查图片类型的彩信 * * @param id 彩信id * @return 彩信的图片数组 */ private byte[] getMmsImage(int id) { Uri uri = Uri.parse("content://mms/part/" + id); InputStream inputStream = null; try { inputStream = resolver.openInputStream(uri); Bitmap bitmap = BitmapFactory.decodeStream(inputStream); ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); return baos.toByteArray(); } catch (Exception e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } /** * 查文本类型的彩信 * * @param id 彩信 id * @return 彩信的文本内容 */ private String getMmsText(int id) { StringBuilder stringBuilder = new StringBuilder(); InputStream inputStream = null; InputStreamReader inputStreamReader = null; BufferedReader reader = null; try { inputStream = resolver.openInputStream(Uri.parse("content://mms/part/" + id)); if (inputStream != null) { inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); reader = new BufferedReader(inputStreamReader); String s = reader.readLine(); while (s != null) { stringBuilder.append(s); s = reader.readLine(); } return stringBuilder.toString(); } } catch (Exception e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (inputStreamReader != null) { try { inputStreamReader.close(); } catch (IOException e) { e.printStackTrace(); } } if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return stringBuilder.toString(); } }
参考文章:
https://blog.csdn.net/huanongjingchao/article/details/38415779
https://stackoverflow.com/questions/3012287/how-to-read-mms-data-in-android?answertab=active#tab-top