记录remove掉WRITE_SMS权限后,写入短信操作

随着Android系统的升级,Google对安全这一块是越发的看重,所以对于开发惹人员来说权限这一块就是一个不得不注意的内容,开发中会遇到很多关于动态权限管理的bug。

####记录remove掉WRITE_SMS权限后,写入短信

现在很多手机助手都会对短信进行备份和恢复,无奈再Android4.4以后就移除掉WRITE_SMS的权限了,那么要继续写入短信怎么办呢??

我发现QQ手机助手会弹窗让你设置该应用为短信应用,不然没法写入短信。
所以别再去尝试着寻找写入短信的权限了,没有了。QQ都妥协了,我们也跟着妥协把。

设置本应用为短信应用的两种方式:
利用反射,让用户没有感知的情况下设置(不推荐):

public static final String CLASS_SMS_MANAGER = 
"com.android.internal.telephony.SmsApplication";

public static final String METHOD_SET_DEFAULT = "setDefaultApplication";

private void setDefaultSms(Boolean isMyApp) {
    try {
        Class<?> smsClass = Class.forName(CLASS_SMS_MANAGER);
        Method method = smsClass.getMethod(METHOD_SET_DEFAULT, String.class, Context.class);
        method.invoke(null, "要设置的包名", this);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

####利用系统的Intent,让用户自己选择(着重强调,推荐):

Manifest文件中声明:

    <!-- BroadcastReceiver that listens for incoming SMS messages -->
    <receiver android:name="com.unipeso.phone.smssetting.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="com.unipeso.phone.smssetting.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>

    <!-- Service that delivers messages from the phone "quick response" -->
    <service android:name="com.unipeso.phone.smssetting.HeadlessSmsSendService"
        android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
        android:exported="true" >
        <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>

SmsReceiver和MmsReceiver就是广播接收者,继承BroadcastReceiver并实现其onReceive方法就可以了,不需要做任何操作,HeadlessSmsSendService继承自Service 并实现其onBind方法即可不需要做任何操作。

        <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>

再你需要设置的Activity中加入上面的Intent内容。

设置本应用为短信应用:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
String defaultSmsApp = Telephony.Sms.getDefaultSmsPackage(getActivity());//获取手机当前设置的默认短信应用的包名

            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
                Intent smsIntent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
                intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, CashLendingApp.getAppPackageName());
                startActivity(smsIntent);
            }

ok,再你需要写入短信的时候,设置你应用为短信应用就可以获取到写入短信的权限。

但是,如果让用户修改系统本身的短信应用,估计会分分钟卸载你的app,所以考虑到用户体验,再备份或者你需要写入短信完成后,最好恢复默认的短信应用。

恢复默认的短信应用

//获取手机当前设置的默认短信应用的包名
 String defaultSmsApp =  Telephony.Sms.getDefaultSmsPackage(getActivity());

android 提供了这个API获取到默认短信应用包名,再完成你的操作后,将本应用的包名替换成系统默认短信应用的包名

	Intent smsIntent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
                intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, defaultSmsApp );
                startActivity(smsIntent);
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
这三个函数是 STL 算法中用于删除元素的函数。它们的作用分别是: - `remove_if`:删除满足指定条件的元素,返回指向新的逻辑结尾的迭代器。 - `remove_copy`:将满足指定条件的元素拷贝到另一个容器中,返回指向新的逻辑结尾的迭代器。 - `remove_copy_if`:将不满足指定条件的元素拷贝到另一个容器中,返回指向新的逻辑结尾的迭代器。 下面是它们的用法和示例: ```cpp #include <iostream> #include <algorithm> #include <vector> using namespace std; int main() { // remove_if vector<int> v1{1, 2, 3, 4, 5}; auto it1 = remove_if(v1.begin(), v1.end(), [](int x) { return x % 2 == 0; }); v1.erase(it1, v1.end()); for (int x : v1) { cout << x << " "; // 输出 1 3 5 } cout << endl; // remove_copy vector<int> v2{1, 2, 3, 4, 5}; vector<int> v3; remove_copy(v2.begin(), v2.end(), back_inserter(v3), [](int x) { return x % 2 == 0; }); for (int x : v3) { cout << x << " "; // 输出 1 3 5 } cout << endl; // remove_copy_if vector<int> v4{1, 2, 3, 4, 5}; vector<int> v5; remove_copy_if(v4.begin(), v4.end(), back_inserter(v5), [](int x) { return x % 2 == 0; }); for (int x : v5) { cout << x << " "; // 输出 1 3 5 } cout << endl; return 0; } ``` 注意,这三个函数并不真正删除容器中的元素,而是返回指向新的逻辑结尾的迭代器。如果要真正删除元素,需要结合容器的 `erase` 函数使用。此外,`remove_copy` 和 `remove_copy_if` 会将满足条件的元素拷贝到另一个容器中,因此要注意目标容器的类型和大小。在示例中,使用了 `back_inserter` 函数将元素插入 `vector` 的尾部。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值