Android 4.4以上第三方应用不能插入短信的解决办法

本文介绍了在Android 4.4及以上版本中,由于系统限制第三方应用无法直接插入短信的问题及解决方案。需要将应用设置为默认短信应用,执行备份恢复操作后,再恢复原默认短信应用。主要步骤包括注册Receiver、Activity和服务,显示警告并打开系统设置界面,以及在操作结束后还原默认短信应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android4.4及其以上版本限制了第三方短信App的插入数据库的功能,只有默认短信程序才可以进行插入操作,系统也提供了设置界面,用来设置默认短信应用。这样的话,我们的备份应用如果还盲目地getContentResolver().insert的话,就会发现代码成功执行,但是短信里啥都没有。所以解决办法是,要先把自己的应用设置成默认短信应用,然后再进行插入操作,然后记得把默认短信应用恢复回来。当然这里最主要的步骤就是设置成默认短信应用,因为这需要打开系统界面让用户点了才行。

这里记录一下我所做的过程,关于备份和恢复短信的具体代码这里就不赘述了。


下面分步说明:

  • 第一步,注册2个receiver,1个activity,1个service:
        <!-- BroadcastReceiver that listens for incoming SMS messages -->
        <receiver
            android:name=".sms.SmsReceiver"
            android:permission="android.permission.BROADCAST_SMS" >
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_DELIVER" />
            </intent-filter>
        </receiver>
        <!--BroadcastReceiver that listens for incoming MMS messages-->
        <receiver
            android:name=".sms.MmsReceiver"
            android:permission="android.permission.BROADCAST_WAP_PUSH" >
            <intent-filter>
                <action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />

                <data android:mimeType="application/vnd.wap.mms-message" />
            </intent-filter>
        </receiver>
        <!--Activity that allows the user to send new SMS/MMS messages-->
        <activity
            android:name=".sms.ComposeSmsActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:screenOrientation="portrait" >
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <action android:name="android.intent.action.SENDTO" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="sms" />
                <data android:scheme="smsto" />
                <data android:scheme="mms" />
                <data android:scheme="mmsto" />
            </intent-filter>
        </activity>
        <!--Service that delivers messages from the phone "quick response"-->
        <service
            android:name=".sms.HeadlessSmsSendService"
            android:exported="true"
            android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE" >
            <intent-filter>
                <action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:scheme="sms" />
                <data android:scheme="smsto" />
                <data android:scheme="mms" />
                <data android:scheme="mmsto" />
            </intent-filter>
        </service>

为啥要注册这些?这几个东西能干啥?
这些是收发短信用的,既然你都成为了这个手机的默认短信app了,那你肯定要负责手机的短信相关事务啊,不能光想拿钱不想干活是不是?上面的代码不用做修改,直接放到manifest里面即可,还有一些相关的权限也不用加,因为我们只是稍稍用那么一小会儿,并不打算真的充当一个默认短信应用。

  • 第二步,把上面声明的几个类都给写成java类:
    啥也不说,alt+enter,按提示都给整出来,一句多的都不用加,看下代码:
public class ComposeSmsActivity extends Activity {
}

public class HeadlessSmsSendService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

public class MmsReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

    }
}

public class SmsReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

    }
}

上面两步做完后,你才能调起系统的设置界面。

  • 第三步,在用户点击“恢复”按钮时给个警告说明:

这里写图片描述

  • 第四步,在点完确定后,打开系统设置界面:
    /**
     * 系统默认的短信应用保存一下,方便后面还原
     */
    private String defaultSmsApp;
//点击"恢复"以后执行的代码
//是否是4.4版本以上,如果不是直接执行恢复代码
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
    //获得自己app的包名
    String myPackageName = getPackageName();
    //获得系统默认短信应用的包名
    defaultSmsApp = Telephony.Sms.getDefaultSmsPackage(XXXActivity.this);
    //如果自己的app不是默认app的话,就打开设置的界面,否则就直接执行恢复代码
    if (!defaultSmsApp.equals(myPackageName)) {
        Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
        intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME,myPackageName);
        //这里加ForResult是为了加一个检验是否设置成功的时机
        startActivityForResult(intent,101);
        //一旦走了这里,就不能执行恢复代码了
        return;
    }
}
//执行恢复代码
recoverySms();

下面是onActivityResult中的代码

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(requestCode == 101){
            //设置默认短信成功
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
                final String myPackageName = getPackageName();
                if (Telephony.Sms.getDefaultSmsPackage(XXXActivity.this)
                .equals(myPackageName)) {
                    //继续执行恢复代码
                    recoverySms();
                }
            }
        }
    }

这样,就能在用户同意之后继续执行恢复代码了

  • 第五步,在恢复结束后,不论成功与否,都应该将默认短信应用还原
    下面是恢复结束的代码:
//恢复结束,将默认短信还原
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
    String myPackageName = getPackageName();
    if (Telephony.Sms.getDefaultSmsPackage(XXXActivity.this)
                .equals(myPackageName)) {
         Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
         //这里的defaultSmsApp是前面保存的
         intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, defaultSmsApp);
         startActivity(intent);
    }
}

Over,问题解决了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值