Android 监听彩信

测试机为 华为 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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 中,可以通过注册屏幕广播接收器来监听屏幕的开关状态,从而实现监听息屏的功能。具体实现步骤如下: 1. 创建一个广播接收器类,继承自 BroadcastReceiver 类,重写 onReceive() 方法。 2. 在 onReceive() 方法中,通过 Intent 对象获取屏幕的开关状态。 3. 在 AndroidManifest.xml 文件中注册广播接收器。 4. 在需要监听屏幕开关状态的 Activity 中,注册广播接收器,并在 onDestroy() 方法中注销广播接收器。 以下是示例代码: ``` public class ScreenReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { // 息屏 // do something } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { // 亮屏 // do something } } } ``` 在 AndroidManifest.xml 文件中注册广播接收器: ``` <receiver android:name=".ScreenReceiver"> <intent-filter> <action android:name="android.intent.action.SCREEN_ON" /> <action android:name="android.intent.action.SCREEN_OFF" /> </intent-filter> </receiver> ``` 在需要监听屏幕状态的 Activity 中注册广播接收器: ``` ScreenReceiver mScreenReceiver = new ScreenReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_SCREEN_OFF); registerReceiver(mScreenReceiver, filter); ``` 在 onDestroy() 方法中注销广播接收器: ``` unregisterReceiver(mScreenReceiver); ``` 需要注意的是,如果应用程序处于后台或者被系统杀死,广播接收器将不会收到任何消息。这种情况下,可以考虑使用 Service 来监听屏幕状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值