diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1c97ea7..5d7d10d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -26,7 +26,7 @@ - + @@ -154,6 +154,10 @@ android:launchMode="singleTask" android:screenOrientation="userLandscape" android:theme="@style/DialogCloseOnTouchOutside" /> + () { @Override public void onChanged(AppUpdateInfo appUpdateInfo) { @@ -231,9 +234,7 @@ public class MainActivity extends BaseMvvmActivity { + private static final String TAG = "PermissionActivity"; + + + public static final String[] PERMISSION_CHECK = new String[]{ + Permission.WRITE_EXTERNAL_STORAGE, + Permission.READ_PHONE_STATE, +// Permission.WRITE_SETTINGS, + Permission.ACCESS_COARSE_LOCATION, + Permission.ACCESS_FINE_LOCATION, + Permission.ACCESS_BACKGROUND_LOCATION, + }; + + @Override + public boolean setNightMode() { + return true; + } + + @Override + protected int getLayoutId() { + return R.layout.activity_permission; + } + + @Override + protected void initDataBinding() { + mViewModel.setCtx(this); + mViewModel.setVDBinding(mViewDataBinding); + mViewModel.setLifecycle(getLifecycleSubject()); + mViewDataBinding.setClick(new BtnClick()); + } + + @Override + protected void initView() { + + + } + + @Override + protected void initData() { + + } + + @Override + protected void onResume() { + super.onResume(); + if (XXPermissions.isGranted(this, PermissionActivity.PERMISSION_CHECK)) { + finish(); + } + if (XXPermissions.isGranted(this, Permission.WRITE_EXTERNAL_STORAGE)) { + mViewDataBinding.tvAuth0.setText("已授权"); + mViewDataBinding.tvAuth0.setEnabled(false); + } else { + mViewDataBinding.tvAuth0.setText("去授权"); + } + if (XXPermissions.isGranted(this, Permission.READ_PHONE_STATE)) { + mViewDataBinding.tvAuth1.setText("已授权"); + mViewDataBinding.tvAuth1.setEnabled(false); + } else { + mViewDataBinding.tvAuth1.setText("去授权"); + } + if (XXPermissions.isGranted(this, Permission.WRITE_SETTINGS)) { + mViewDataBinding.tvAuth2.setText("已授权"); + mViewDataBinding.tvAuth2.setEnabled(false); + } else { + mViewDataBinding.tvAuth2.setText("去授权"); + } + if (XXPermissions.isGranted(this, Permission.ACCESS_COARSE_LOCATION)) { + mViewDataBinding.tvAuth3.setText("已授权"); + mViewDataBinding.tvAuth3.setEnabled(false); + } else { + mViewDataBinding.tvAuth3.setText("去授权"); + } + if (XXPermissions.isGranted(this, Permission.ACCESS_FINE_LOCATION)) { + mViewDataBinding.tvAuth4.setText("已授权"); + mViewDataBinding.tvAuth4.setEnabled(false); + } else { + mViewDataBinding.tvAuth4.setText("去授权"); + } + if (XXPermissions.isGranted(this, Permission.ACCESS_BACKGROUND_LOCATION)) { + mViewDataBinding.tvAuth5.setText("已授权"); + mViewDataBinding.tvAuth5.setEnabled(false); + } else { + mViewDataBinding.tvAuth5.setText("去授权"); + } + + } + + private void getPermission(String... permissions) { + XXPermissions.with(this) + // 申请单个权限 + .permission(permissions) + // 申请多个权限 +// .permission(Permission.Group.STORAGE) + // 设置权限请求拦截器(局部设置) + .interceptor(new PermissionInterceptor()) + // 设置不触发错误检测机制(局部设置) + //.unchecked() + .request(new OnPermissionCallback() { + @Override + public void onGranted(@NonNull List permissions, boolean allGranted) { + Log.e(TAG, "onGranted: permissions = " + permissions + " allGranted = " + allGranted); + if (!allGranted) { + Toast.makeText(PermissionActivity.this, "获取部分权限成功,但部分权限未正常授予", Toast.LENGTH_SHORT).show(); + return; + } + Log.e(TAG, "onGranted: 获取权限成功"); + } + + @Override + public void onDenied(@NonNull List permissions, boolean doNotAskAgain) { + Log.e(TAG, "onDenied: permissions = " + permissions + " doNotAskAgain = " + doNotAskAgain); + if (doNotAskAgain) { + Toast.makeText(PermissionActivity.this, "被永久拒绝授权,请手动授予权限", Toast.LENGTH_SHORT).show(); + // 如果是被永久拒绝就跳转到应用权限系统设置页面 + XXPermissions.startPermissionActivity(PermissionActivity.this, permissions); + } else { + Log.e(TAG, "onGranted: 获取权限失败"); + } + } + }); + } + + public class BtnClick { + public void openStorage(View view) { + getPermission(Permission.WRITE_EXTERNAL_STORAGE); + } + + public void openReadPhone(View view) { + getPermission(Permission.READ_PHONE_STATE); + } + + public void openWriteSettings(View view) { + getPermission(Permission.WRITE_SETTINGS); + } + + public void open_coarse_location(View view) { + getPermission(Permission.ACCESS_COARSE_LOCATION); + } + + public void open_fine_location(View view) { + getPermission(Permission.ACCESS_FINE_LOCATION); + } + + public void open_background_location(View view) { + getPermission(Permission.ACCESS_BACKGROUND_LOCATION); + } + + } +} diff --git a/app/src/main/java/com/uiui/zyos/activity/permission/PermissionViewModel.java b/app/src/main/java/com/uiui/zyos/activity/permission/PermissionViewModel.java new file mode 100644 index 0000000..d9c7ed4 --- /dev/null +++ b/app/src/main/java/com/uiui/zyos/activity/permission/PermissionViewModel.java @@ -0,0 +1,18 @@ +package com.uiui.zyos.activity.permission; + +import com.trello.rxlifecycle4.android.ActivityEvent; +import com.uiui.zyos.base.mvvm.BaseViewModel; +import com.uiui.zyos.databinding.ActivityPermissionBinding; + +public class PermissionViewModel extends BaseViewModel { + + @Override + public ActivityPermissionBinding getVDBinding() { + return binding; + } + + @Override + public void onDestroy() { + + } +} diff --git a/app/src/main/java/com/uiui/zyos/interceptor/PermissionDescriptionConvert.java b/app/src/main/java/com/uiui/zyos/interceptor/PermissionDescriptionConvert.java new file mode 100644 index 0000000..093dfd7 --- /dev/null +++ b/app/src/main/java/com/uiui/zyos/interceptor/PermissionDescriptionConvert.java @@ -0,0 +1,54 @@ +package com.uiui.zyos.interceptor; + +import android.content.Context; +import android.util.Log; + +import androidx.annotation.NonNull; + + +import com.uiui.zyos.R; + +import java.util.List; + +/** + * author : Android 轮子哥 + * github : https://github.com/getActivity/XXPermissions + * time : 2023/01/02 + * desc : 权限描述转换器 + */ +public final class PermissionDescriptionConvert { + + /** + * 获取权限描述 + */ + public static String getPermissionDescription(Context context, List permissions) { + StringBuilder stringBuilder = new StringBuilder(); + List permissionNames = PermissionNameConvert.permissionsToNames(context, permissions); + for (String permissionName : permissionNames) { + stringBuilder.append(permissionName) + .append(context.getString(R.string.common_permission_colon)) + .append(permissionsToDescription(context, permissionName)) + .append("\n"); + } + return stringBuilder.toString().trim(); + } + + /** + * 将权限名称列表转换成对应权限描述 + */ + @NonNull + public static String permissionsToDescription(Context context, String permissionName) { + // 请根据权限名称转换成对应权限说明 + Log.e("TAG", "permissionsToDescription: " + permissionName); + switch (permissionName) { + case "存储权限": + return "存储图片或视频"; + case "电话权限": + return "拨打电话"; + case "定位权限": + return "获取设备定位"; + default: + return "用于" + permissionName; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/uiui/zyos/interceptor/PermissionInterceptor.java b/app/src/main/java/com/uiui/zyos/interceptor/PermissionInterceptor.java new file mode 100644 index 0000000..a694e03 --- /dev/null +++ b/app/src/main/java/com/uiui/zyos/interceptor/PermissionInterceptor.java @@ -0,0 +1,306 @@ +package com.uiui.zyos.interceptor; + +import android.app.Activity; +import android.content.Context; +import android.content.res.Configuration; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.os.Build; +import android.os.Handler; +import android.os.Looper; +import android.text.TextUtils; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.PopupWindow; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; + +import com.hjq.permissions.OnPermissionCallback; +import com.hjq.permissions.OnPermissionInterceptor; +import com.hjq.permissions.OnPermissionPageCallback; +import com.hjq.permissions.Permission; +import com.hjq.permissions.PermissionFragment; +import com.hjq.permissions.XXPermissions; +import com.hjq.toast.Toaster; +import com.uiui.zyos.R; + +import java.util.List; + +/** + * author : Android 轮子哥 + * github : https://github.com/getActivity/XXPermissions + * time : 2021/01/04 + * desc : 权限申请拦截器 + */ +public final class PermissionInterceptor implements OnPermissionInterceptor { + + public static final Handler HANDLER = new Handler(Looper.getMainLooper()); + + /** + * 权限申请标记 + */ + private boolean mRequestFlag; + + /** + * 权限申请说明 Popup + */ + private PopupWindow mPermissionPopup; + + /** + * 权限说明文案 + */ + @Nullable + private String mPermissionDescription; + + public PermissionInterceptor() { + this(null); + } + + public PermissionInterceptor(@Nullable String permissionDescription) { + mPermissionDescription = permissionDescription; + } + + @Override + public void launchPermissionRequest(@NonNull Activity activity, @NonNull List allPermissions, @Nullable OnPermissionCallback callback) { + mRequestFlag = true; + List deniedPermissions = XXPermissions.getDenied(activity, allPermissions); + + if (TextUtils.isEmpty(mPermissionDescription)) { + mPermissionDescription = generatePermissionDescription(activity, deniedPermissions); + } + + ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView(); + int activityOrientation = activity.getResources().getConfiguration().orientation; + + boolean showPopupWindow = activityOrientation == Configuration.ORIENTATION_PORTRAIT; + for (String permission : allPermissions) { + if (!XXPermissions.isSpecial(permission)) { + continue; + } + if (XXPermissions.isGranted(activity, permission)) { + continue; + } +// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R && + if (Build.VERSION.SDK_INT < 30 && + TextUtils.equals(Permission.MANAGE_EXTERNAL_STORAGE, permission)) { + continue; + } + // 如果申请的权限带有特殊权限,并且还没有授予的话 + // 就不用 PopupWindow 对话框来显示,而是用 Dialog 来显示 + showPopupWindow = false; + break; + } + + if (showPopupWindow) { + PermissionFragment.launch(activity, allPermissions, this, callback); + // 延迟 300 毫秒是为了避免出现 PopupWindow 显示然后立马消失的情况 + // 因为框架没有办法在还没有申请权限的情况下,去判断权限是否永久拒绝了,必须要在发起权限申请之后 + // 所以只能通过延迟显示 PopupWindow 来做这件事,如果 300 毫秒内权限申请没有结束,证明本次申请的权限没有永久拒绝 + HANDLER.postDelayed(() -> { + if (!mRequestFlag) { + return; + } + if (activity.isFinishing() || + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && activity.isDestroyed())) { + return; + } + showPopupWindow(activity, decorView, mPermissionDescription); + }, 300); + } else { + // 注意:这里的 Dialog 只是示例,没有用 DialogFragment 来处理 Dialog 生命周期 + new AlertDialog.Builder(activity) + .setTitle(R.string.common_permission_description_title) + .setMessage(mPermissionDescription) + .setCancelable(false) + .setPositiveButton(R.string.common_permission_granted, (dialog, which) -> { + dialog.dismiss(); + PermissionFragment.launch(activity, allPermissions, + PermissionInterceptor.this, callback); + }) + .setNegativeButton(R.string.common_permission_denied, (dialog, which) -> { + dialog.dismiss(); + if (callback == null) { + return; + } + callback.onDenied(deniedPermissions, false); + }) + .show(); + } + } + + @Override + public void grantedPermissionRequest(@NonNull Activity activity, @NonNull List allPermissions, + @NonNull List grantedPermissions, boolean allGranted, + @Nullable OnPermissionCallback callback) { + if (callback == null) { + return; + } + callback.onGranted(grantedPermissions, allGranted); + } + + @Override + public void deniedPermissionRequest(@NonNull Activity activity, @NonNull List allPermissions, + @NonNull List deniedPermissions, boolean doNotAskAgain, + @Nullable OnPermissionCallback callback) { + if (callback != null) { + callback.onDenied(deniedPermissions, doNotAskAgain); + } + + if (doNotAskAgain) { + if (deniedPermissions.size() == 1 && Permission.ACCESS_MEDIA_LOCATION.equals(deniedPermissions.get(0))) { + Toaster.show(R.string.common_permission_media_location_hint_fail); + return; + } + + showPermissionSettingDialog(activity, allPermissions, deniedPermissions, callback); + return; + } + + if (deniedPermissions.size() == 1) { + + String deniedPermission = deniedPermissions.get(0); + + String backgroundPermissionOptionLabel = getBackgroundPermissionOptionLabel(activity); + + if (Permission.ACCESS_BACKGROUND_LOCATION.equals(deniedPermission)) { + Toaster.show(activity.getString(R.string.common_permission_background_location_fail_hint, backgroundPermissionOptionLabel)); + return; + } + + if (Permission.BODY_SENSORS_BACKGROUND.equals(deniedPermission)) { + Toaster.show(activity.getString(R.string.common_permission_background_sensors_fail_hint, backgroundPermissionOptionLabel)); + return; + } + } + + final String message; + List permissionNames = PermissionNameConvert.permissionsToNames(activity, deniedPermissions); + if (!permissionNames.isEmpty()) { + message = activity.getString(R.string.common_permission_fail_assign_hint, + PermissionNameConvert.listToString(activity, permissionNames)); + } else { + message = activity.getString(R.string.common_permission_fail_hint); + } + Toaster.show(message); + } + + @Override + public void finishPermissionRequest(@NonNull Activity activity, @NonNull List allPermissions, + boolean skipRequest, @Nullable OnPermissionCallback callback) { + mRequestFlag = false; + dismissPopupWindow(); + } + + /** + * 生成权限说明文案 + */ + protected String generatePermissionDescription(Context context, @NonNull List permissions) { + return PermissionDescriptionConvert.getPermissionDescription(context, permissions); + } + + private void showPopupWindow(Activity activity, ViewGroup decorView, String message) { + if (mPermissionPopup == null) { + View contentView = LayoutInflater.from(activity) + .inflate(R.layout.permission_description_popup, decorView, false); + mPermissionPopup = new PopupWindow(activity); + mPermissionPopup.setContentView(contentView); + mPermissionPopup.setWidth(WindowManager.LayoutParams.MATCH_PARENT); + mPermissionPopup.setHeight(WindowManager.LayoutParams.WRAP_CONTENT); + mPermissionPopup.setAnimationStyle(android.R.style.Animation_Dialog); + mPermissionPopup.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + mPermissionPopup.setTouchable(true); + mPermissionPopup.setOutsideTouchable(true); + } + TextView messageView = mPermissionPopup.getContentView().findViewById(R.id.tv_permission_description_message); + messageView.setText(message); + // 注意:这里的 PopupWindow 只是示例,没有监听 Activity onDestroy 来处理 PopupWindow 生命周期 + mPermissionPopup.showAtLocation(decorView, Gravity.TOP, 0, 0); + } + + private void dismissPopupWindow() { + if (mPermissionPopup == null) { + return; + } + if (!mPermissionPopup.isShowing()) { + return; + } + mPermissionPopup.dismiss(); + } + + private void showPermissionSettingDialog(Activity activity, List allPermissions, + List deniedPermissions, OnPermissionCallback callback) { + if (activity == null || activity.isFinishing() || + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && activity.isDestroyed())) { + return; + } + + String message = null; + + List permissionNames = PermissionNameConvert.permissionsToNames(activity, deniedPermissions); + if (!permissionNames.isEmpty()) { + if (deniedPermissions.size() == 1) { + String deniedPermission = deniedPermissions.get(0); + + if (Permission.ACCESS_BACKGROUND_LOCATION.equals(deniedPermission)) { + message = activity.getString(R.string.common_permission_manual_assign_fail_background_location_hint, getBackgroundPermissionOptionLabel(activity)); + } else if (Permission.BODY_SENSORS_BACKGROUND.equals(deniedPermission)) { + message = activity.getString(R.string.common_permission_manual_assign_fail_background_sensors_hint, getBackgroundPermissionOptionLabel(activity)); + } + } + if (TextUtils.isEmpty(message)) { + message = activity.getString(R.string.common_permission_manual_assign_fail_hint, + PermissionNameConvert.listToString(activity, permissionNames)); + } + } else { + message = activity.getString(R.string.common_permission_manual_fail_hint); + } + + // 这里的 Dialog 只是示例,没有用 DialogFragment 来处理 Dialog 生命周期 + new AlertDialog.Builder(activity) + .setTitle(R.string.common_permission_alert) + .setMessage(message) + .setPositiveButton(R.string.common_permission_goto_setting_page, (dialog, which) -> { + dialog.dismiss(); + XXPermissions.startPermissionActivity(activity, + deniedPermissions, new OnPermissionPageCallback() { + + @Override + public void onGranted() { + if (callback == null) { + return; + } + callback.onGranted(allPermissions, true); + } + + @Override + public void onDenied() { + showPermissionSettingDialog(activity, allPermissions, + XXPermissions.getDenied(activity, allPermissions), callback); + } + }); + }) + .show(); + } + + /** + * 获取后台权限的《始终允许》选项的文案 + */ + @NonNull + private String getBackgroundPermissionOptionLabel(Context context) { + String backgroundPermissionOptionLabel = ""; +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { +// if (Build.VERSION.SDK_INT >= 30) { +// backgroundPermissionOptionLabel = String.valueOf(context.getPackageManager().getBackgroundPermissionOptionLabel()); +// } + if (TextUtils.isEmpty(backgroundPermissionOptionLabel)) { + backgroundPermissionOptionLabel = context.getString(R.string.common_permission_background_default_option_label); + } + return backgroundPermissionOptionLabel; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/uiui/zyos/interceptor/PermissionNameConvert.java b/app/src/main/java/com/uiui/zyos/interceptor/PermissionNameConvert.java new file mode 100644 index 0000000..5030e21 --- /dev/null +++ b/app/src/main/java/com/uiui/zyos/interceptor/PermissionNameConvert.java @@ -0,0 +1,333 @@ +package com.uiui.zyos.interceptor; + +import android.content.Context; +import android.os.Build; + +import androidx.annotation.NonNull; + +import com.hjq.permissions.Permission; +import com.uiui.zyos.R; + +import java.util.ArrayList; +import java.util.List; + +/** + * author : Android 轮子哥 + * github : https://github.com/getActivity/XXPermissions + * time : 2022/06/11 + * desc : 权限名称转换器 + */ +public final class PermissionNameConvert { + + /** + * 获取权限名称 + */ + public static String getPermissionNames(Context context, List permissions) { + return listToString(context, permissionsToNames(context, permissions)); + } + + /** + * String 列表拼接成一个字符串 + */ + public static String listToString(Context context, List hints) { + if (hints == null || hints.isEmpty()) { + return context.getString(R.string.common_permission_unknown); + } + + StringBuilder builder = new StringBuilder(); + for (String text : hints) { + if (builder.length() == 0) { + builder.append(text); + } else { + builder.append("、") + .append(text); + } + } + return builder.toString(); + } + + /** + * 将权限列表转换成对应名称列表 + */ + @NonNull + public static List permissionsToNames(Context context, List permissions) { + List permissionNames = new ArrayList<>(); + if (context == null) { + return permissionNames; + } + if (permissions == null) { + return permissionNames; + } + for (String permission : permissions) { + switch (permission) { + case Permission.READ_EXTERNAL_STORAGE: + case Permission.WRITE_EXTERNAL_STORAGE: { + String hint = context.getString(R.string.common_permission_storage); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.READ_MEDIA_IMAGES: + case Permission.READ_MEDIA_VIDEO: + case Permission.READ_MEDIA_VISUAL_USER_SELECTED: { + if (Build.VERSION.SDK_INT >= 33) { + String hint = context.getString(R.string.common_permission_image_and_video); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + } + break; + } + case Permission.READ_MEDIA_AUDIO: { + if (Build.VERSION.SDK_INT >= 33) { + String hint = context.getString(R.string.common_permission_music_and_audio); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + } + break; + } + case Permission.CAMERA: { + String hint = context.getString(R.string.common_permission_camera); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.RECORD_AUDIO: { + String hint = context.getString(R.string.common_permission_microphone); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.ACCESS_FINE_LOCATION: + case Permission.ACCESS_COARSE_LOCATION: + case Permission.ACCESS_BACKGROUND_LOCATION: { + String hint; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && + !permissions.contains(Permission.ACCESS_FINE_LOCATION) && + !permissions.contains(Permission.ACCESS_COARSE_LOCATION)) { + hint = context.getString(R.string.common_permission_location_background); + } else { + hint = context.getString(R.string.common_permission_location); + } + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.BODY_SENSORS: + case Permission.BODY_SENSORS_BACKGROUND: { + String hint; + if (Build.VERSION.SDK_INT >= 33 && + !permissions.contains(Permission.BODY_SENSORS)) { + hint = context.getString(R.string.common_permission_body_sensors_background); + } else { + hint = context.getString(R.string.common_permission_body_sensors); + } + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.BLUETOOTH_SCAN: + case Permission.BLUETOOTH_CONNECT: + case Permission.BLUETOOTH_ADVERTISE: { + if (Build.VERSION.SDK_INT >= 31) { + String hint = context.getString(R.string.common_permission_nearby_devices); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + } + break; + } + case Permission.NEARBY_WIFI_DEVICES: { + if (Build.VERSION.SDK_INT >= 33) { + String hint = context.getString(R.string.common_permission_nearby_devices); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + } + break; + } + case Permission.READ_PHONE_STATE: + case Permission.CALL_PHONE: + case Permission.ADD_VOICEMAIL: + case Permission.USE_SIP: + case Permission.READ_PHONE_NUMBERS: + case Permission.ANSWER_PHONE_CALLS: { + String hint = context.getString(R.string.common_permission_phone); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.GET_ACCOUNTS: + case Permission.READ_CONTACTS: + case Permission.WRITE_CONTACTS: { + String hint = context.getString(R.string.common_permission_contacts); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.READ_CALENDAR: + case Permission.WRITE_CALENDAR: { + String hint = context.getString(R.string.common_permission_calendar); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.READ_CALL_LOG: + case Permission.WRITE_CALL_LOG: + case Permission.PROCESS_OUTGOING_CALLS: { + String hint = context.getString(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ? + R.string.common_permission_call_logs : + R.string.common_permission_phone); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.ACTIVITY_RECOGNITION: { + String hint = context.getString(Build.VERSION.SDK_INT >= 30 ? + R.string.common_permission_activity_recognition_api30 : + R.string.common_permission_activity_recognition_api29); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.ACCESS_MEDIA_LOCATION: { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + String hint = context.getString(R.string.common_permission_access_media_location); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + } + break; + } + case Permission.SEND_SMS: + case Permission.RECEIVE_SMS: + case Permission.READ_SMS: + case Permission.RECEIVE_WAP_PUSH: + case Permission.RECEIVE_MMS: { + String hint = context.getString(R.string.common_permission_sms); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.MANAGE_EXTERNAL_STORAGE: { + if (Build.VERSION.SDK_INT >= 30) { + String hint = context.getString(R.string.common_permission_all_file_access); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + } + break; + } + case Permission.REQUEST_INSTALL_PACKAGES: { + String hint = context.getString(R.string.common_permission_install_unknown_apps); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.SYSTEM_ALERT_WINDOW: { + String hint = context.getString(R.string.common_permission_display_over_other_apps); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.WRITE_SETTINGS: { + String hint = context.getString(R.string.common_permission_modify_system_settings); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.NOTIFICATION_SERVICE: { + String hint = context.getString(R.string.common_permission_allow_notifications); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.POST_NOTIFICATIONS: { + if (Build.VERSION.SDK_INT >= 33) { + String hint = context.getString(R.string.common_permission_post_notifications); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + } + break; + } + case Permission.BIND_NOTIFICATION_LISTENER_SERVICE: { + String hint = context.getString(R.string.common_permission_allow_notifications_access); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.PACKAGE_USAGE_STATS: { + String hint = context.getString(R.string.common_permission_apps_with_usage_access); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.SCHEDULE_EXACT_ALARM: { + String hint = context.getString(R.string.common_permission_alarms_reminders); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.ACCESS_NOTIFICATION_POLICY: { + String hint = context.getString(R.string.common_permission_do_not_disturb_access); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS: { + String hint = context.getString(R.string.common_permission_ignore_battery_optimize); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.BIND_VPN_SERVICE: { + String hint = context.getString(R.string.common_permission_vpn); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.PICTURE_IN_PICTURE: { + String hint = context.getString(R.string.common_permission_picture_in_picture); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + case Permission.GET_INSTALLED_APPS: { + String hint = context.getString(R.string.common_permission_get_installed_apps); + if (!permissionNames.contains(hint)) { + permissionNames.add(hint); + } + break; + } + default: + break; + } + } + + return permissionNames; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/uiui/zyos/service/main/MainService.java b/app/src/main/java/com/uiui/zyos/service/main/MainService.java index 10a75aa..e2b394b 100644 --- a/app/src/main/java/com/uiui/zyos/service/main/MainService.java +++ b/app/src/main/java/com/uiui/zyos/service/main/MainService.java @@ -36,9 +36,9 @@ public class MainService extends BaseRxService implements MainSContact.MainSView @Override public void onConnected(NetworkUtils.NetworkType networkType) { Log.e(TAG, "onConnected: "); - if (Utils.isScreenOn(MainService.this)) { - mPresenter.getCloudLessonSettings(); - } +// if (Utils.isScreenOn(MainService.this)) { +// mPresenter.getCloudLessonSettings(); +// } } @Override diff --git a/app/src/main/res/drawable-hdpi/applet_qrcode.jpg b/app/src/main/res/drawable-hdpi/applet_qrcode.jpg deleted file mode 100644 index 3b28bac..0000000 Binary files a/app/src/main/res/drawable-hdpi/applet_qrcode.jpg and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/applet_qrcode.png b/app/src/main/res/drawable-hdpi/applet_qrcode.png new file mode 100644 index 0000000..1ac5538 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/applet_qrcode.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_dialer_cancel_black.png b/app/src/main/res/drawable-hdpi/icon_dialer_cancel_black.png new file mode 100644 index 0000000..d7f4a9e Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_dialer_cancel_black.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_dialer_cancel_white.png b/app/src/main/res/drawable-hdpi/icon_dialer_cancel_white.png new file mode 100644 index 0000000..92b9c05 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_dialer_cancel_white.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_dialer_confirm_black.png b/app/src/main/res/drawable-hdpi/icon_dialer_confirm_black.png new file mode 100644 index 0000000..e06153f Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_dialer_confirm_black.png differ diff --git a/app/src/main/res/drawable-hdpi/icon_dialer_confirm_white.png b/app/src/main/res/drawable-hdpi/icon_dialer_confirm_white.png new file mode 100644 index 0000000..ed6f6d2 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/icon_dialer_confirm_white.png differ diff --git a/app/src/main/res/drawable/bt_dialer_color.xml b/app/src/main/res/drawable/bt_dialer_color.xml new file mode 100644 index 0000000..3a9cbf1 --- /dev/null +++ b/app/src/main/res/drawable/bt_dialer_color.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bt_dialer_normnl.xml b/app/src/main/res/drawable/bt_dialer_normnl.xml new file mode 100644 index 0000000..f1d7727 --- /dev/null +++ b/app/src/main/res/drawable/bt_dialer_normnl.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bt_dialer_pressed.xml b/app/src/main/res/drawable/bt_dialer_pressed.xml new file mode 100644 index 0000000..d0eaaa5 --- /dev/null +++ b/app/src/main/res/drawable/bt_dialer_pressed.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bt_dialer_selector.xml b/app/src/main/res/drawable/bt_dialer_selector.xml new file mode 100644 index 0000000..6a3fdd6 --- /dev/null +++ b/app/src/main/res/drawable/bt_dialer_selector.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/icon_dialer_cancel.xml b/app/src/main/res/drawable/icon_dialer_cancel.xml new file mode 100644 index 0000000..4fd9063 --- /dev/null +++ b/app/src/main/res/drawable/icon_dialer_cancel.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/icon_dialer_confirm.xml b/app/src/main/res/drawable/icon_dialer_confirm.xml new file mode 100644 index 0000000..bbeb0a3 --- /dev/null +++ b/app/src/main/res/drawable/icon_dialer_confirm.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/permission_auth_bg.xml b/app/src/main/res/drawable/permission_auth_bg.xml new file mode 100644 index 0000000..d05e149 --- /dev/null +++ b/app/src/main/res/drawable/permission_auth_bg.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/permission_auth_dis_bg.xml b/app/src/main/res/drawable/permission_auth_dis_bg.xml new file mode 100644 index 0000000..a86b347 --- /dev/null +++ b/app/src/main/res/drawable/permission_auth_dis_bg.xml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/permission_auth_selector.xml b/app/src/main/res/drawable/permission_auth_selector.xml new file mode 100644 index 0000000..48bf356 --- /dev/null +++ b/app/src/main/res/drawable/permission_auth_selector.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/permission_card_background.xml b/app/src/main/res/drawable/permission_card_background.xml new file mode 100644 index 0000000..c42196d --- /dev/null +++ b/app/src/main/res/drawable/permission_card_background.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/permission_description_popup_bg.xml b/app/src/main/res/drawable/permission_description_popup_bg.xml new file mode 100644 index 0000000..b33fb6a --- /dev/null +++ b/app/src/main/res/drawable/permission_description_popup_bg.xml @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-land/activity_exit.xml b/app/src/main/res/layout-land/activity_exit.xml index 660539a..86de838 100644 --- a/app/src/main/res/layout-land/activity_exit.xml +++ b/app/src/main/res/layout-land/activity_exit.xml @@ -11,7 +11,42 @@ + android:background="@color/gray"> + + + + + + + + + + + app:layout_constraintVertical_bias="0.35"> @@ -70,11 +106,12 @@ android:layout_height="wrap_content" android:layout_marginStart="@dimen/dp_48" android:layout_marginEnd="@dimen/dp_48" + android:layout_marginTop="@dimen/dp_8" android:gravity="center" android:maxLines="2" android:minLines="2" android:text="退出系统" - android:textColor="@color/white" + android:textColor="@color/black" android:textSize="@dimen/sp_14" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -89,7 +126,9 @@ android:visibility="visible" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintStart_toStartOf="parent"> + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/imageView5" + app:layout_constraintVertical_bias="0.9"> - + android:layout_weight="1"> - + - + + + android:layout_weight="1"> + + + + + + + + + - + android:layout_weight="1"> - + + - + android:layout_weight="1"> + + + + + + + + + - + android:layout_weight="1"> - + - + + + android:layout_weight="1"> + + + + + + + + + - + android:layout_weight="1"> - + + - + android:layout_weight="1"> + + + + + + + + + + diff --git a/app/src/main/res/layout-land/activity_passwd.xml b/app/src/main/res/layout-land/activity_passwd.xml new file mode 100644 index 0000000..83c52bd --- /dev/null +++ b/app/src/main/res/layout-land/activity_passwd.xml @@ -0,0 +1,382 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout-land/fragment_chinese.xml b/app/src/main/res/layout-land/fragment_chinese.xml index efcf6e3..b66bc23 100644 --- a/app/src/main/res/layout-land/fragment_chinese.xml +++ b/app/src/main/res/layout-land/fragment_chinese.xml @@ -130,8 +130,7 @@ android:layout_marginBottom="@dimen/dp_8" android:orientation="vertical" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintTop_toBottomOf="@+id/tv_more_app" - tools:layout_editor_absoluteX="6dp"> + app:layout_constraintTop_toBottomOf="@+id/tv_more_app"> + app:layout_constraintTop_toTopOf="parent"> + android:background="@color/gray"> + + + + + + + + + + app:layout_constraintVertical_bias="0.35"> + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/imageView5" + app:layout_constraintVertical_bias="0.9"> - + android:layout_weight="1"> - + - + + + android:layout_weight="1"> + + + + + + + + + - + android:layout_weight="1"> - + + - + android:layout_weight="1"> + + + + + + + + + - + android:layout_weight="1"> - + - + + + android:layout_weight="1"> + + + + + + + + + - + android:layout_weight="1"> - + + - + android:layout_weight="1"> + + + + + + + + + + diff --git a/app/src/main/res/layout-sw800dp/activity_passwd.xml b/app/src/main/res/layout-sw800dp/activity_passwd.xml new file mode 100644 index 0000000..83c52bd --- /dev/null +++ b/app/src/main/res/layout-sw800dp/activity_passwd.xml @@ -0,0 +1,382 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout-sw800dp/fragment_chinese.xml b/app/src/main/res/layout-sw800dp/fragment_chinese.xml index cb40018..74a4327 100644 --- a/app/src/main/res/layout-sw800dp/fragment_chinese.xml +++ b/app/src/main/res/layout-sw800dp/fragment_chinese.xml @@ -130,8 +130,7 @@ android:layout_marginBottom="@dimen/dp_8" android:orientation="vertical" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintTop_toBottomOf="@+id/tv_more_app" - tools:layout_editor_absoluteX="6dp"> + app:layout_constraintTop_toBottomOf="@+id/tv_more_app"> + app:layout_constraintTop_toTopOf="parent"> + android:background="@color/gray"> + + + + + + + + + + app:layout_constraintVertical_bias="0.35"> + app:layout_constraintVertical_bias="0.8"> - + android:layout_weight="1"> - + - + + + android:layout_weight="1"> + + + + + + + + + - + android:layout_weight="1"> - + + - + android:layout_weight="1"> + + + + + + + + + - + android:layout_weight="1"> - + - + + + android:layout_weight="1"> + + + + + + + + + - + android:layout_weight="1"> - + + - + android:layout_weight="1"> + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 085c222..e2808ee 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -195,7 +195,7 @@ android:id="@+id/tv_appname2" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="我的设备" + android:text="设备守护" android:textColor="@color/white" android:textSize="@dimen/sp_7" app:layout_constraintEnd_toEndOf="@+id/iv_icon2" diff --git a/app/src/main/res/layout/activity_manual.xml b/app/src/main/res/layout/activity_manual.xml index a03503e..387abcb 100644 --- a/app/src/main/res/layout/activity_manual.xml +++ b/app/src/main/res/layout/activity_manual.xml @@ -34,8 +34,7 @@ android:layout_marginTop="@dimen/dp_8" android:layout_marginEnd="@dimen/dp_16" android:background="@drawable/search_view_bg" - app:layout_constraintTop_toBottomOf="@+id/textView9" - tools:layout_editor_absoluteX="18dp"> + app:layout_constraintTop_toBottomOf="@+id/textView9"> + android:background="@color/gray"> + app:layout_constraintVertical_bias="0.35"> + app:layout_constraintVertical_bias="0.8"> - + android:layout_weight="1"> - + - + + + android:layout_weight="1"> + + + + + + + + + - + android:layout_weight="1"> - + + - + android:layout_weight="1"> + + + + + + + + + - + android:layout_weight="1"> - + - + + + android:layout_weight="1"> + + + + + + + + + - + android:layout_weight="1"> - + + - + android:layout_weight="1"> + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_permission.xml b/app/src/main/res/layout/activity_permission.xml new file mode 100644 index 0000000..fce5a46 --- /dev/null +++ b/app/src/main/res/layout/activity_permission.xml @@ -0,0 +1,399 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_chinese.xml b/app/src/main/res/layout/fragment_chinese.xml index efcf6e3..b66bc23 100644 --- a/app/src/main/res/layout/fragment_chinese.xml +++ b/app/src/main/res/layout/fragment_chinese.xml @@ -130,8 +130,7 @@ android:layout_marginBottom="@dimen/dp_8" android:orientation="vertical" app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintTop_toBottomOf="@+id/tv_more_app" - tools:layout_editor_absoluteX="6dp"> + app:layout_constraintTop_toBottomOf="@+id/tv_more_app"> + app:layout_constraintTop_toTopOf="parent"> + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings_demo.xml b/app/src/main/res/values/strings_demo.xml new file mode 100644 index 0000000..1b0c5cc --- /dev/null +++ b/app/src/main/res/values/strings_demo.xml @@ -0,0 +1,41 @@ + + + + 获取%s成功 + 检测到你刚刚从权限设置界面返回回来 + + 当前版本不是 Android 12 及以上,旧版本的需要定位权限才能进行扫描蓝牙 + 当前版本不是 Android 13 及以上,旧版本的需要定位权限才能进行扫描 WIFI + 当前版本不是 Android 10 及以上,旧版本的需要读取存储权限才能获取媒体位置权限 + 当前版本不是 Android 13 及以上,会自动变更为旧版的请求方式 + 当前版本不是 Android 11 及以上,会自动变更为旧版的请求方式 + 当前版本不是 Android 13 及以上,会自动变更为旧版的请求方式 + + 监听到新的通知消息,标题为:%s,内容为:%s + + 申请单个危险权限 + 申请多个危险权限 + 申请定位权限 + 申请传感器权限 + 申请身体活动权限 + 申请蓝牙权限 + 申请 WIFI 权限 + 申请读取图片位置权限 + 申请媒体文件读取权限 + 申请所有文件管理权限 + 申请安装包权限 + 申请悬浮窗权限 + 申请系统设置权限 + 申请通知权限 + 申请新版通知权限 + 申请通知栏监听权限 + 申请使用统计权限 + 申请闹钟提醒权限 + 申请勿扰权限 + 申请忽略电池优化权限 + 申请画中画权限 + 申请 VPN 权限 + 申请读取应用列表 + 跳转到应用详情页 + + \ No newline at end of file diff --git a/app/src/main/res/values/strings_permission.xml b/app/src/main/res/values/strings_permission.xml new file mode 100644 index 0000000..8ce4a50 --- /dev/null +++ b/app/src/main/res/values/strings_permission.xml @@ -0,0 +1,59 @@ + + + + 权限说明 + 授予 + 取消 + + 授权提醒 + 授权失败,请正确授予权限 + 授权失败,请正确授予%s + 获取权限失败,请手动授予权限 + 获取权限失败,请手动授予%s + 获取后台定位权限失败,请在定位权限中选择%s + 获取后台传感器权限失败,请在传感器权限中选择%s + 获取后台定位权限失败,\n请选择%s选项 + 获取后台传感器权限失败,\n请选择%s选项 + 始终允许 + 获取媒体位置权限失败\n请清除应用数据后重试 + 前往授权 + + 权限 + + + + 日历权限 + 相机权限 + 通讯录权限 + 定位权限 + 后台定位权限 + 附近设备权限 + 麦克风权限 + 电话权限 + 通话记录权限 + 身体传感器权限 + 后台身体传感器权限 + 健身运动权限 + 身体活动权限 + 读取媒体文件位置权限 + 短信权限 + 存储权限 + 发送通知权限 + 照片和视频权限 + 音乐和音频权限 + 读取应用列表权限 + + 所有文件访问权限 + 安装应用权限 + 悬浮窗权限 + 修改系统设置权限 + 通知权限 + 通知栏监听权限 + 查看使用情况权限 + 查看闹钟提醒权限 + 勿扰权限 + 忽略电池优化权限 + 画中画权限 + \tVPN\t权限 + + \ No newline at end of file diff --git a/verification-view/src/main/java/com/tuo/customview/PwdTextView.java b/verification-view/src/main/java/com/tuo/customview/PwdTextView.java index c364b8e..c10f1cc 100644 --- a/verification-view/src/main/java/com/tuo/customview/PwdTextView.java +++ b/verification-view/src/main/java/com/tuo/customview/PwdTextView.java @@ -2,7 +2,6 @@ package com.tuo.customview; import android.content.Context; import android.graphics.Canvas; -import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; @@ -33,7 +32,6 @@ public class PwdTextView extends AppCompatTextView { super(context, attrs, defStyleAttr); } - @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); @@ -41,7 +39,7 @@ public class PwdTextView extends AppCompatTextView { if (hasPwd) { // 画一个黑色的圆 Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); - paint.setColor(Color.WHITE); + paint.setColor(getResources().getColor(R.color.circle_f)); paint.setStyle(Paint.Style.FILL); canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, paint); }else { diff --git a/verification-view/src/main/res/values/colors.xml b/verification-view/src/main/res/values/colors.xml index 13365a7..3290900 100644 --- a/verification-view/src/main/res/values/colors.xml +++ b/verification-view/src/main/res/values/colors.xml @@ -1,6 +1,7 @@ - #2a2c36 + #C6C5C5 + #0480ff \ No newline at end of file