diff --git a/app/src/main/java/com/nnbc123/app/base/BaseActivity.java b/app/src/main/java/com/nnbc123/app/base/BaseActivity.java index 7ec185a82..f9767b42f 100644 --- a/app/src/main/java/com/nnbc123/app/base/BaseActivity.java +++ b/app/src/main/java/com/nnbc123/app/base/BaseActivity.java @@ -134,7 +134,7 @@ public abstract class BaseActivity extends RxAppCompatActivity */ protected static final String STATUS_TAG = "STATUS_TAG"; - private final RxPermissions rxPermissions = new RxPermissions(this); + protected final RxPermissions rxPermissions = new RxPermissions(this); protected TitleBar mTitleBar; protected DefaultToolBar mToolBar; protected CompositeDisposable mCompositeDisposable; diff --git a/app/src/main/java/com/nnbc123/app/common/permission/PermissionHelper.kt b/app/src/main/java/com/nnbc123/app/common/permission/PermissionHelper.kt new file mode 100644 index 000000000..86b4cf58c --- /dev/null +++ b/app/src/main/java/com/nnbc123/app/common/permission/PermissionHelper.kt @@ -0,0 +1,26 @@ +package com.nnbc123.app.common.permission + +import com.tbruyelle.rxpermissions2.RxPermissions + +/** + * Created by Max on 2024/1/8 10:25 + * Desc: + **/ +object PermissionHelper { + + /** + * 检查权限是否都授权 + */ + fun isAllGender(rxPermissions: RxPermissions, vararg perms: String?): Boolean { + if (perms.firstOrNull { + if (it == null) { + false + } else { + !rxPermissions.isGranted(it) + } + } != null) { + return false + } + return true + } +} \ No newline at end of file diff --git a/app/src/main/java/com/nnbc123/app/qiyukefu/RequestPermissionEvent.kt b/app/src/main/java/com/nnbc123/app/qiyukefu/RequestPermissionEvent.kt index ac22a6d79..7ecfcd125 100644 --- a/app/src/main/java/com/nnbc123/app/qiyukefu/RequestPermissionEvent.kt +++ b/app/src/main/java/com/nnbc123/app/qiyukefu/RequestPermissionEvent.kt @@ -5,12 +5,17 @@ import android.content.Context import android.content.Intent import android.net.Uri import android.provider.Settings +import androidx.fragment.app.FragmentActivity +import com.chuhai.utils.ktx.asActivity import com.nnbc123.app.R +import com.nnbc123.app.common.permission.PermissionHelper import com.nnbc123.app.ui.widget.dialog.CommonTipDialog +import com.nnbc123.app.ui.widget.dialog.RequestPermissionPromptDialog import com.nnbc123.library.utils.ResUtil import com.qiyukf.unicorn.api.event.EventCallback import com.qiyukf.unicorn.api.event.UnicornEventBase import com.qiyukf.unicorn.api.event.entry.RequestPermissionEventEntry +import com.tbruyelle.rxpermissions2.RxPermissions /** * Created by Max on 2024/1/4 11:10 @@ -22,18 +27,60 @@ class RequestPermissionEvent : UnicornEventBase { p1: Context?, p2: EventCallback? ) { - p2?.onNotPorcessEvent() + val tips = getPermissionTips(p0?.scenesType) + val activity = (p1?.asActivity() as? FragmentActivity) + val perms = p0?.permissionList?.toTypedArray() + if (RequestPermissionPromptDialog.isNeedPrompt() + && tips != null + && activity != null + && perms != null + ) { + val rxPermissions = RxPermissions(activity) + if (PermissionHelper.isAllGender(rxPermissions, * perms)) { + p2?.onNotPorcessEvent() + } else { + RequestPermissionPromptDialog(p1, tips).show() + val d = rxPermissions.request(*perms).subscribe({ aBoolean: Boolean? -> + RequestPermissionPromptDialog.dismissCurrentDialog() + if (aBoolean == true) { + p2?.onProcessEventSuccess(p0) + } else { + showDeniedTips(p1, tips) + p2?.onInterceptEvent() + } + }) { obj: Throwable -> + RequestPermissionPromptDialog.dismissCurrentDialog() + obj.printStackTrace() + p2?.onNotPorcessEvent() + } + } + } else { + p2?.onNotPorcessEvent() + } } override fun onDenyEvent(p0: Context?, p1: RequestPermissionEventEntry?): Boolean { if (p0 == null) { return super.onDenyEvent(p0, p1) } - when (p1?.scenesType) { + val tips = getPermissionTips(p1?.scenesType) + return if (tips != null) { + showDeniedTips(p0, tips) + true + } else { + super.onDenyEvent(p0, p1) + } + } + + /** + * 获取场景对应的权限提示信息(不需要提示的权限返回null) + */ + private fun getPermissionTips(scenesType: Int?): String? { + when (scenesType) { RequestPermissionEventEntry.SCENES_TAKE_AUDIO -> { - showDeniedTips(p0, ResUtil.getString(R.string.permission_denied_tips_mic)) - return true + return ResUtil.getString(R.string.permission_denied_tips_mic) } + RequestPermissionEventEntry.SCENES_SELECT_MEDIA, RequestPermissionEventEntry.SCENES_TAKE_VIDEO, RequestPermissionEventEntry.SCENES_SAVE_IMAGE, @@ -43,12 +90,11 @@ class RequestPermissionEvent : UnicornEventBase { RequestPermissionEventEntry.SCENES_SELECT_IMAGE, RequestPermissionEventEntry.SCENES_TAKE_PHOTO, RequestPermissionEventEntry.SCENES_VIDEO_CHAT -> { - showDeniedTips(p0, ResUtil.getString(R.string.permission_denied_tips_image)) - return true + return ResUtil.getString(R.string.permission_denied_tips_image) } else -> { - return super.onDenyEvent(p0, p1) + return null } } } diff --git a/app/src/main/java/com/nnbc123/app/ui/im/fragment/MessageFragment.java b/app/src/main/java/com/nnbc123/app/ui/im/fragment/MessageFragment.java index 378e01aef..6069243ba 100644 --- a/app/src/main/java/com/nnbc123/app/ui/im/fragment/MessageFragment.java +++ b/app/src/main/java/com/nnbc123/app/ui/im/fragment/MessageFragment.java @@ -2,6 +2,7 @@ package com.nnbc123.app.ui.im.fragment; import android.Manifest; import android.annotation.SuppressLint; +import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.media.AudioManager; @@ -54,6 +55,7 @@ import com.netease.nimlib.sdk.robot.model.NimRobotInfo; import com.netease.nimlib.sdk.robot.model.RobotAttachment; import com.netease.nimlib.sdk.robot.model.RobotMsgType; import com.nnbc123.app.R; +import com.nnbc123.app.common.permission.PermissionHelper; import com.nnbc123.app.common.widget.OriginalDrawStatusClickSpan; import com.nnbc123.app.ui.im.GreetPresenter; import com.nnbc123.app.ui.im.MessageListPanelEx; @@ -61,6 +63,7 @@ import com.nnbc123.app.ui.im.chat.MVHChatterBoxStart; import com.nnbc123.app.ui.im.model.IMCustomModel; import com.nnbc123.app.ui.webview.CommonWebViewActivity; import com.nnbc123.app.ui.widget.dialog.CommonTipDialog; +import com.nnbc123.app.ui.widget.dialog.RequestPermissionPromptDialog; import com.nnbc123.app.utils.PushMessageHandler; import com.nnbc123.core.UriProvider; import com.nnbc123.core.auth.AuthModel; @@ -230,7 +233,7 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi IMMessage anchor = (IMMessage) getArguments().getSerializable(Extras.EXTRA_ANCHOR); customization = (SessionCustomization) getArguments().getSerializable(Extras.EXTRA_CUSTOMIZATION); - Container container = new Container(getActivity(), sessionId, sessionType, this,this::requestPermission); + Container container = new Container(getActivity(), sessionId, sessionType, this, this::requestPermission); if (messageListPanel == null) { messageListPanel = new MessageListPanelEx(container, rootView, anchor, false, false); @@ -321,10 +324,16 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi } - private void requestPermission(Consumer consumer, String deniedTips, String... perms) { + private void requestPermission(Consumer consumer, String tips, String... perms) { + Context context = getContext(); + if (context != null && RequestPermissionPromptDialog.Companion.isNeedPrompt() + && !PermissionHelper.INSTANCE.isAllGender(rxPermissions, perms)) { + new RequestPermissionPromptDialog(context, tips).show(); + } Disposable disposable = rxPermissions.request(perms).subscribe(aBoolean -> { + RequestPermissionPromptDialog.Companion.dismissCurrentDialog(); if (!aBoolean) { - showPermissionDeniedTipsDialog(deniedTips); + showPermissionDeniedTipsDialog(tips); } if (consumer != null) { consumer.accept(aBoolean); @@ -616,19 +625,26 @@ public class MessageFragment extends TFragment implements ModuleProxy, MessageLi @Subscribe(threadMode = ThreadMode.MAIN) @SuppressLint("CheckResult") public void onNimAudioChatEvent(NimAudioChatEvent event) { - checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, + String[] perms = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, - Manifest.permission.RECORD_AUDIO) + Manifest.permission.RECORD_AUDIO}; + String tips = ResUtil.getString(R.string.permission_denied_tips_mic); + if (RequestPermissionPromptDialog.Companion.isNeedPrompt() + && !PermissionHelper.INSTANCE.isAllGender(rxPermissions, perms)) { + new RequestPermissionPromptDialog(requireContext(), tips).show(); + } + checkPermission(perms) .subscribe(result -> { + RequestPermissionPromptDialog.Companion.dismissCurrentDialog(); if (result) { event.getSuccess().accept(result); } else { - showPermissionDeniedTipsDialog(ResUtil.getString(R.string.permission_denied_tips_mic)); + showPermissionDeniedTipsDialog(tips); } }); } - private void showPermissionDeniedTipsDialog(String message){ + private void showPermissionDeniedTipsDialog(String message) { CommonTipDialog mPrivacyDialog = new CommonTipDialog(getContext()); mPrivacyDialog.setTipMsg(message); mPrivacyDialog.setOkText("去设置"); diff --git a/app/src/main/java/com/nnbc123/app/ui/user/UserInfoModifyActivity.kt b/app/src/main/java/com/nnbc123/app/ui/user/UserInfoModifyActivity.kt index 82fd5cf79..8486dd829 100644 --- a/app/src/main/java/com/nnbc123/app/ui/user/UserInfoModifyActivity.kt +++ b/app/src/main/java/com/nnbc123/app/ui/user/UserInfoModifyActivity.kt @@ -28,6 +28,7 @@ import com.nnbc123.app.ui.login.ModifyInfoActivity import com.nnbc123.app.ui.user.UserPhotoAdapter.ImageClickListener import com.nnbc123.app.ui.utils.ImageLoadUtils import com.nnbc123.app.ui.widget.dialog.CommonTipDialog +import com.nnbc123.app.ui.widget.dialog.RequestPermissionPromptDialog import com.nnbc123.app.utils.RegexUtil import com.nnbc123.core.auth.AuthModel import com.nnbc123.core.file.FileModel @@ -40,6 +41,7 @@ import com.nnbc123.library.common.photo.PhotoProviderNew import com.nnbc123.library.common.util.PhotoCompressCallback import com.nnbc123.library.common.util.PhotoCompressUtil import com.nnbc123.library.easypermisssion.EasyPermissions +import com.nnbc123.library.utils.ResUtil import com.nnbc123.library.utils.TimeUtils import com.sleepbot.datetimepicker.time.RadialPickerLayout import com.sleepbot.datetimepicker.time.TimePickerDialog @@ -276,6 +278,7 @@ class UserInfoModifyActivity : BaseViewBindingActivity) { if (requestCode == PERMISSION_CODE_STORAGE) { + RequestPermissionPromptDialog.dismissCurrentDialog() val requestTip = "为了能正常加载您本地的文件内容,请前往应用权限设置界面打开存储空间权限。" val mPrivacyDialog = CommonTipDialog(context) mPrivacyDialog.setTipMsg(requestTip) @@ -307,12 +310,19 @@ class UserInfoModifyActivity : BaseViewBindingActivity) { if (requestCode == PERMISSION_CODE_STORAGE) { + RequestPermissionPromptDialog.dismissCurrentDialog() val requestTip = "为了能正常加载您本地的文件内容,请前往应用权限设置界面打开存储空间权限。" val mPrivacyDialog = CommonTipDialog(context) mPrivacyDialog.setTipMsg(requestTip) @@ -256,12 +259,19 @@ class UserModifyPhotosActivity : TakePhotoActivity(), PhotoItemClickListener, } private fun checkStoragePermission() { + RequestPermissionPromptDialog.dismissCurrentDialog() if (!EasyPermissions.hasPermissions( this, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE ) ) { + if (RequestPermissionPromptDialog.isNeedPrompt()) { + RequestPermissionPromptDialog( + this, + ResUtil.getString(R.string.permission_denied_tips_image) + ).show() + } EasyPermissions.requestPermissions( this, "请您再次考虑授予存储空间权限,否则将无法正常加载您本地的文件内容。", diff --git a/app/src/main/java/com/nnbc123/app/ui/widget/dialog/RequestPermissionPromptDialog.kt b/app/src/main/java/com/nnbc123/app/ui/widget/dialog/RequestPermissionPromptDialog.kt new file mode 100644 index 000000000..c3f43d5b3 --- /dev/null +++ b/app/src/main/java/com/nnbc123/app/ui/widget/dialog/RequestPermissionPromptDialog.kt @@ -0,0 +1,70 @@ +package com.nnbc123.app.ui.widget.dialog + +import android.app.Dialog +import android.content.Context +import android.os.Bundle +import android.view.Gravity +import android.view.View +import android.view.WindowManager +import android.widget.TextView +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.LifecycleOwner +import com.nnbc123.app.R +import com.nnbc123.library.utils.config.BasicConfig + +/** + * Created by Max on 2024/1/8 10:06 + * Desc:申请权限提示 + **/ +class RequestPermissionPromptDialog(context: Context, private val message: String) : + Dialog(context, R.style.dialog_full_width), LifecycleEventObserver { + + companion object { + private var currentDialog: RequestPermissionPromptDialog? = null + fun dismissCurrentDialog() { + currentDialog?.dismiss() + currentDialog = null + } + + /** + * 是否需要展示权限申请说明 + */ + fun isNeedPrompt(): Boolean { + return (BasicConfig.INSTANCE.channel == "huawei") + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + currentDialog = this + val window = window + if (window != null) { + val lps = window.attributes + lps.gravity = Gravity.TOP + lps.verticalMargin = 0f + lps.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + window.attributes = lps + } + setCanceledOnTouchOutside(false) + setContentView(R.layout.dialog_request_permission_prompt) + val rootView = findViewById(R.id.layout_root) + // 权限已被拒时再申请权限会立即回调结果,这个弹窗看起来闪一下就没了,优化这个体验:延迟可见 + rootView?.animate()?.alpha(1f)?.setStartDelay(200)?.start() + val messageView = findViewById(R.id.tv_message) + messageView?.text = message + (ownerActivity as? LifecycleOwner)?.lifecycle?.addObserver(this) + } + + override fun dismiss() { + currentDialog = null + (ownerActivity as? LifecycleOwner)?.lifecycle?.removeObserver(this) + super.dismiss() + } + + override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) { + if (event == Lifecycle.Event.ON_DESTROY) { + this@RequestPermissionPromptDialog.dismiss() + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_request_permission_prompt.xml b/app/src/main/res/layout/dialog_request_permission_prompt.xml new file mode 100644 index 000000000..493612a37 --- /dev/null +++ b/app/src/main/res/layout/dialog_request_permission_prompt.xml @@ -0,0 +1,35 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index f52a89082..740058106 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -125,6 +125,19 @@ 0.5 + +