Android编程实现用户修改默认短信应用,API29无弹窗如何解决?
问题原因
- 代码执行顺序错误:你当前的逻辑是先触发修改默认短信应用的Intent,紧接着就执行权限检查和权限申请操作。在API29及以上系统中,后续弹出的权限申请弹窗会直接覆盖/取消掉修改默认应用的系统弹窗,导致看不到提示。
- API29行为变更限制:Android 10(API29)对
ACTION_CHANGE_DEFAULT的触发逻辑做了收紧,只有当前应用未被设为默认短信应用时,才会弹出请求弹窗。
适配方案
1. 先添加默认短信应用判断逻辑
触发修改请求前先判断当前应用是否已经是默认短信应用,避免无效请求:
// 判断是否是默认短信应用 private boolean isDefaultSmsApp(Context context) { return context.getPackageName().equals(Telephony.Sms.getDefaultSmsPackage(context)); }
2. 调整点击事件执行顺序
先处理权限申请,权限全部通过后再判断是否要触发修改默认应用的请求,避免弹窗冲突:
@Override public void onViewCreated(@NonNull final View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); view.findViewById(R.id.btnEnreg).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { btnEnreg = view.findViewById(R.id.btnEnreg); // 先处理权限校验 if (hasPermissions(getContext(),Permissions)){ // 权限通过后再判断是否需要修改默认短信应用 if (!isDefaultSmsApp(getContext())) { Intent setSmsAppIntent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT); setSmsAppIntent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, getActivity().getPackageName()); startActivityForResult(setSmsAppIntent, 5); } else { // 已经是默认应用,直接执行后续业务逻辑 createOnClicBtnEnreg(); Toast.makeText(getContext(), "Insertion Réussi", Toast.LENGTH_SHORT).show(); } }else{ if(!ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),Manifest.permission.SEND_SMS)){ String[] permissions = {Manifest.permission.WRITE_CALL_LOG,Manifest.permission.SEND_SMS,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.WRITE_CONTACTS,Manifest.permission.READ_SMS}; ActivityCompat.requestPermissions(getActivity(),permissions,1); }else{ lay_dataset1=view.findViewById(R.id.lay_dataset1); messagePermissionObligatoire(); } } } }); }
3. 添加修改结果回调处理
在onActivityResult中接收用户的选择结果,确认用户同意设为默认应用后再执行后续业务逻辑:
@Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 5) { if (resultCode == Activity.RESULT_OK && isDefaultSmsApp(getContext())) { // 用户同意设为默认短信应用,执行后续逻辑 createOnClicBtnEnreg(); Toast.makeText(getContext(), "Insertion Réussi", Toast.LENGTH_SHORT).show(); } else { // 用户拒绝,可自行添加降级提示逻辑 Toast.makeText(getContext(), "需要设为默认短信应用才能使用该功能", Toast.LENGTH_SHORT).show(); } } }
4. 兼容API30及以上版本(可选)
如果你的应用targetSdkVersion >=30,需要在AndroidManifest.xml的根<manifest>标签下添加查询配置,否则获取默认短信应用的接口会返回null:
<queries> <intent> <action android:name="android.provider.Telephony.SMS_DELIVER" /> </intent> </queries>
内容的提问来源于stack exchange,提问作者Android4Ever
相关产品推荐
相关产品推荐

