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

随着Android系统升级,WRITE_SMS权限被移除,本文探讨如何在Android4.4及更高版本中通过设置应用为默认短信应用来实现短信写入功能。提供两种方法:使用反射静默设置(不推荐)与利用系统Intent引导用户选择(推荐)。同时介绍如何恢复默认短信应用以优化用户体验。

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

随着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);
<think>好的,用户的问题是关于如何使用sys.remove_orphan_files或解决相关问题。首先,我需要确认这个系统存储过程的具体作用和适用场景。根据名称,它可能用于删除数据库中的孤立文件,也就是那些存在于文件系统中但不在数据库元数据中的文件。这种情况通常发生在数据库文件被手动删除或某些操作未正确完成时。 接下来,我需要回忆SQL Server中相关的文档或经验。记得在SQL Server中,孤立文件可能出现在使用FILESTREAM或者某些备份操作失败后。sys.remove_orphan_files是系统存储过程,可能用于清理这些文件。需要确认用户使用的是否是SQL Server,因为不同数据库系统的处理方式不同。 用户提供的引用中有一个关于alter system set的命令,这可能涉及Oracle的参数设置,但问题本身是关于SQL Server的,所以可能引用中的内容不直接相关。需要专注于SQL Server的环境。 接下来,步骤应该是: 1. 确认孤立文件的存在。通常需要检查数据库的文件目录,比对物理文件和数据库记录。 2. 使用sys.remove_orphan_files前,确保数据库处于单用户模式,以防止数据不一致。 3. 执行存储过程,可能需要指定文件类型或路径。 4. 处理可能出现的错误,例如权限问题或文件仍在使用中。 另外,用户可能遇到的常见问题包括权限不足、数据库未处于正确状态,或者存储过程执行后文件未被正确删除。需要提供解决这些问题的步骤,比如检查错误日志,确认数据库模式,以及验证文件是否确实孤立。 还需要考虑备份的重要性,建议用户在操作前进行完整备份,避免数据丢失。同时,如果存储过程不可用,可能需要手动删除文件,但需极度谨慎,确保文件确实无用。 最后,生成相关问题,帮助用户深入理解,比如如何检查孤立文件、权限设置、替代方法等。</think>### 如何执行 `sys.remove_orphan_files` 或解决相关问题? #### 1. **功能与适用场景** `sys.remove_orphan_files` 是 SQL Server 中的系统存储过程,用于删除数据库中的“孤立文件”(即物理存储在磁盘上但未在数据库元数据中注册的文件)。这种情况通常由以下原因导致: - 手动删除数据库文件但未更新元数据。 - 备份或还原操作意外中断。 - FILESTREAM 或内存优化表的文件残留[^1]。 #### 2. **使用步骤** **步骤 1:确认孤立文件存在** ```sql USE [数据库名]; SELECT name, physical_name FROM sys.master_files WHERE database_id = DB_ID('数据库名'); ``` 对比查询结果与实际文件系统中的文件,找出未被记录的孤立文件。 **步骤 2:设置数据库为单用户模式** 为避免数据不一致,需先隔离数据库: ```sql ALTER DATABASE [数据库名] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; ``` **步骤 3:执行 `sys.remove_orphan_files`** 调用存储过程清理文件: ```sql EXEC sys.remove_orphan_files @dbname = N'数据库名', @filename = N'孤立文件名.ext'; -- 可选参数,若未指定则清理所有孤立文件 ``` **步骤 4:恢复数据库为多用户模式** ```sql ALTER DATABASE [数据库名] SET MULTI_USER; ``` #### 3. **常见问题与解决** - **权限不足** 确保执行账户拥有 `sysadmin` 角色权限,并对数据库文件目录有读写权限[^3]。 - **文件仍被占用** 若文件被其他进程占用,需通过任务管理器或 `sp_who2` 终止相关进程。 - **元数据不一致** 若存储过程无法识别孤立文件,可手动删除文件(需谨慎验证是否为孤立文件): ```sql -- 手动删除示例(高风险操作) EXEC xp_cmdshell 'DEL "C:\Path\To\OrphanFile.ext"'; ``` - **备份与恢复** 操作前务必备份数据库,避免误删关键文件[^4]。 #### 4. **替代方案** - 使用 `DBCC CHECKDB` 检测并修复元数据不一致: ```sql DBCC CHECKDB ('数据库名') WITH NO_INFOMSGS, ALL_ERRORMSGS; ``` - 通过 SQL Server Management Studio (SSMS) 的“数据库文件管理”界面手动删除。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值