如何在 Android API <19 & API >=19 中监控传入的短信?

Posted

技术标签:

【中文标题】如何在 Android API <19 & API >=19 中监控传入的短信?【英文标题】:How to Monitor Incoming SMS in Android API <19 & API >=19? 【发布时间】:2017-05-23 13:26:29 【问题描述】:

我尝试在我的应用中监控传入的短信。在 android 方面,他们对从 API 19 监控传入的 SMS 进行了一些更改。

API 23 中无法在后台跟踪传入消息(在应用程序不在后台和移动屏幕处于关闭状态时)。

在 Android 文档中说,如果您的应用不是来自 API 19 的默认消息应用,则无法在后台跟踪传入的短信。

参考:-Getting Your SMS Apps Ready for KitKat

但它在我的 API 21(LOLLIPOP) 设备上运行。它不适用于 API 23(Marshmallow) 设备。当设备屏幕打开或应用程序打开时意味着它也在 API 23(Marshmallow) 中工作。

您能否更新我在 API 23(Marshmallow) 中是否有任何方法可以在后台跟踪传入消息。

清单代码

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

<receiver
        android:name=".SMSReceiver"
        android:enabled="true"
        android:exported="true"
        android:permission="android.permission.BROADCAST_SMS">
        <intent-filter android:priority="5822">
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
        </intent-filter>
</receiver>

这是我的 Java 代码

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.telephony.SmsMessage;

public class SMSReceiver extends BroadcastReceiver 

public static final String BROADCAST = "SMS_RECEIVER";
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";

Intent broadcast_intent;
String message_body = "", originAddress;

StringBuilder bodyText;

@Override
public void onReceive(Context context, Intent intent) 


    if (intent.getAction().equalsIgnoreCase(SMS_RECEIVED)) 

        broadcast_intent = new Intent(BROADCAST);

        Bundle bundle = intent.getExtras();
        SmsMessage[] messages;

        if (bundle != null) 

            Object[] pdus = (Object[]) bundle.get("pdus");

            messages = new SmsMessage[pdus.length];

            bodyText = new StringBuilder();

            for (int i = 0; i < messages.length; i++) 

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
                    String format = bundle.getString("format");
                    messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i], format);
                 else 
                    messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
                

                originAddress = messages[i].getOriginatingAddress().toUpperCase();
                bodyText.append(messages[i].getMessageBody());

            

            message_body = bodyText.toString();

        
    


【问题讨论】:

【参考方案1】:

在引入 Android 6.0 (API 23) 之初,Google 对应用权限技术进行了巨大更改。因此对于 API >=23,用户需要在应用运行时授予应用权限,而不是在安装应用时授予应用权限

系统权限分为正常和危险两类:

    普通权限不会直接危及用户的隐私。如果您的应用在其清单中列出了正常权限,系统会自动授予该权限。 危险权限可以让应用访问用户的机密数据。如果您的应用在其清单中列出了正常权限,系统会自动授予该权限。如果您列出危险权限,用户必须明确批准您的应用。

访问手机短信管理器的权限被视为危险权限,这就是为什么需要在您尝试使用手机短信管理器的代码中以编程方式调用它。

你可以像这样在你的 mainActivity 中请求权限

int hasSMSPermission = checkSelfPermission( Manifest.permission.SEND_SMS );
List<String> permissions = new ArrayList<String>();

if( hasSMSPermission != PackageManager.PERMISSION_GRANTED ) 
    permissions.add( Manifest.permission.SEND_SMS );


if( !permissions.isEmpty() ) 
    requestPermissions( permissions.toArray( new String[permissions.size()] ), REQUEST_CODE_SOME_FEATURES_PERMISSIONS );

为了接收权限请求结果并设置您的广播接收器,请像这样覆盖 onActivityResult 方法:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) 
    switch ( requestCode ) 
        case REQUEST_CODE_SOME_FEATURES_PERMISSIONS: 
            for( int i = 0; i < permissions.length; i++ ) 
                if( grantResults[i] == PackageManager.PERMISSION_GRANTED ) 
                    Log.d( "Permissions", "Permission Granted: " + permissions[i] );
                 else if( grantResults[i] == PackageManager.PERMISSION_DENIED ) 
                    Log.d( "Permissions", "Permission Denied: " + permissions[i] );
                
            
        
        break;
        default: 
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        
    

查看此链接了解更多详情:https://developer.android.com/training/permissions/requesting.html

【讨论】:

我已完成所有安全权限检查。对于我使用的权限。【参考方案2】:

基本上你可以注册一个广播接收器来监听SMS_Receive并查看以下内容。

Intent intent = getIntent();
Bundle bundle = intent.getBundleExtra("mySMS");

if (bundle != null) 
    Object[] pdus = (Object[])bundle.get("pdus");
    SmsMessage sms = SmsMessage.createFromPdu((byte[])pdus[0]);
    Log.i(TAG, "smsActivity : SMS is <" +  sms.getMessageBody() +">");


    String message = sms.getMessageBody();
    //required sms
    TextView tx = (TextView) findViewById(R.id.TextBox);
    tx.setText(message);            
 else
    Log.i(TAG, "smsActivity : NULL SMS bundle");

【讨论】:

“SMS_Receive”或“android.permission.RECEIVE_SMS”被认为是危险的吗?我可以在不作为默认短信应用的情况下使用它吗?

以上是关于如何在 Android API <19 & API >=19 中监控传入的短信?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 android API 19 (KitKat) 中保持权限?

android 当我转到 API>19 时,我的 Java 接口给了我“TypeError: Android.mthod is not a function

以离子形式生成API级别19的Apk

如何让信任锚在 Android API 级别 16-19 上正常工作

API 19:android.view.InflateException:二进制 XML 文件行 #0:膨胀类 SeekBar 时出错

Android API 19:操作栏不显示 menu_main.xml