From df9d2538121b1a8899f2d620f16188f4ac889286 Mon Sep 17 00:00:00 2001 From: xinfengkun Date: Fri, 31 Mar 2023 13:42:31 +0800 Subject: [PATCH] =?UTF-8?q?[=E5=B7=A5=E6=8E=A7=E6=9C=BA=E8=B0=83=E8=AF=95]?= =?UTF-8?q?=20=E6=B7=BB=E5=8A=A0=E6=9D=83=E9=99=90=E7=94=B3=E8=AF=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app_ipc_monitoring/gradle.properties | 4 +- .../zhidao/adas/client/ui/MainActivity.java | 111 ++++- .../adas/client/utils/PermissionUtil.java | 434 ++++++++++++++++++ 3 files changed, 546 insertions(+), 3 deletions(-) create mode 100644 app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/PermissionUtil.java diff --git a/app_ipc_monitoring/gradle.properties b/app_ipc_monitoring/gradle.properties index dd007305b4..32484a1fa7 100644 --- a/app_ipc_monitoring/gradle.properties +++ b/app_ipc_monitoring/gradle.properties @@ -1,2 +1,2 @@ -#Wed Mar 08 16:14:51 CST 2023 -VERSION_CODE=3 +#Fri Mar 31 13:39:14 CST 2023 +VERSION_CODE=4 diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/MainActivity.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/MainActivity.java index 494f0354c4..d42ebc1b04 100644 --- a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/MainActivity.java +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/ui/MainActivity.java @@ -1,5 +1,6 @@ package com.zhidao.adas.client.ui; +import android.Manifest; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -33,6 +34,11 @@ import android.widget.RadioGroup; import android.widget.TextView; import android.widget.Toast; +import androidx.activity.result.ActivityResult; +import androidx.activity.result.ActivityResultCallback; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.AppCompatButton; import androidx.fragment.app.FragmentManager; @@ -72,6 +78,7 @@ import com.zhidao.adas.client.other.permission.OnAdasPermissionListener; import com.zhidao.adas.client.other.router.RouterActivity; import com.zhidao.adas.client.ui.special.SpecialVehicleDialog; import com.zhidao.adas.client.utils.Constants; +import com.zhidao.adas.client.utils.PermissionUtil; import com.zhidao.adas.client.utils.PreferencesUtils; import com.zhidao.support.adas.high.AdasManager; import com.zhidao.support.adas.high.AdasOptions; @@ -99,6 +106,7 @@ import java.util.Date; import java.util.Enumeration; import java.util.List; import java.util.Locale; +import java.util.Set; import java.util.concurrent.ScheduledExecutorService; import bag_manager.BagManagerOuterClass; @@ -182,6 +190,9 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas PowerManager.WakeLock wakeLock; WifiManager.WifiLock wifiLock; + private ActivityResultLauncher intentActivityResultLauncher; + + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -199,6 +210,8 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas showIPCIP(); canDrawOverlays(); showHint(); + initRegisterForActivityResult(); + checkSavePermission(); // PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); // wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); // wakeLock.acquire(); @@ -213,7 +226,103 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas // wifiLock = wifiManager.createWifiLock(wifiLockType, TAG); // wifiLock.acquire(); } + private void initRegisterForActivityResult() { + intentActivityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback() { + @Override + public void onActivityResult(ActivityResult result) { + checkSavePermission(); +// Intent data = result.getData(); +// int resultCode = result.getResultCode(); + //RESULT_OK +// Log.i("dddd", "resultCode=" + resultCode); + } + }); + } + /** + * 权限检查 + */ + private void checkSavePermission() { + //权限申请 + String[] pgList = new String[]{Manifest.permission_group.STORAGE}; + PermissionUtil.requestByGroupName(this, pgList, 10000, permissionsListener); + } + + // 跳转到当前应用的设置界面 + private void goToAppSetting() { + Uri uri = Uri.fromParts("package", getPackageName(), null); + Intent intent = new Intent(); + intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + intent.setData(uri); + intentActivityResultLauncher.launch(intent); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + PermissionUtil.onRequestPermissionsResult(this, permissions, grantResults, permissionsListener, false); + } + + //权限申请回调 + private final PermissionUtil.OnPermissionsListener permissionsListener = new PermissionUtil.OnPermissionsListener() { + @Override + public void onPermissionsOwned() { + + } + + @Override + public void onPermissionsForbidden(String[] permissions, int[] grantResults, ArrayList pmList) { + Set nameSet = PermissionUtil.getPermissionsNameByChinese(pmList.toArray(new String[0])); + if (nameSet != null && nameSet.size() > 0) { + AlertDialog dialog = new AlertDialog.Builder(MainActivity.this) + .setTitle("警告") + .setMessage("请前往设置中手动授予" + nameSet.toString() + "权限,否则功能无法正常运行!") + .setNegativeButton("退出", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + finish(); + } + }) + .setPositiveButton("去设置", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + goToAppSetting(); + } + }) + .create(); + dialog.setCancelable(false); + dialog.setCanceledOnTouchOutside(false); + dialog.show(); + } + } + + @Override + public void onPermissionsDenied(String[] permissions, int[] grantResults, ArrayList pmList) { + Set nameSet = PermissionUtil.getPermissionsNameByChinese(pmList.toArray(new String[0])); + if (nameSet != null && nameSet.size() > 0) { + //重新请求权限 + AlertDialog dialog = new AlertDialog.Builder(MainActivity.this) + .setTitle("提示") + .setMessage(nameSet.toString() + "权限为应用必要权限,请授权") + .setPositiveButton("确定", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + String[] sList = pmList.toArray(new String[0]); + //重新申请权限,通过权限名的方式申请多组权限 + PermissionUtil.requestByPermissionName(MainActivity.this, sList, 10000, permissionsListener); + } + }) + .create(); + dialog.setCancelable(false); + dialog.setCanceledOnTouchOutside(false); + dialog.show(); + } + } + + @Override + public void onPermissionsSucceed() { + } + }; private void showHint() { boolean isShowHint = PreferencesUtils.getBoolean(this, "show_hint", true); if (isShowHint) { @@ -1037,7 +1146,7 @@ public class MainActivity extends BaseActivity implements OnAdasListener, OnAdas runOnUiThread(new Runnable() { @Override public void run() { - showToastCenter("收到车机基础信息请求:" + base.toString()); + showToastCenter("收到车机基础信息请求:" + base.toString(R.id.rb_all)); } }); } diff --git a/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/PermissionUtil.java b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/PermissionUtil.java new file mode 100644 index 0000000000..f50e46beda --- /dev/null +++ b/app_ipc_monitoring/src/main/java/com/zhidao/adas/client/utils/PermissionUtil.java @@ -0,0 +1,434 @@ +package com.zhidao.adas.client.utils; + + +import android.Manifest; +import android.app.Activity; +import android.content.Context; +import android.content.pm.PackageManager; +import android.os.Build; +import android.util.Log; + +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * author:chenjs + */ +public class PermissionUtil { + private static final String TAG = PermissionUtil.class.getSimpleName(); + private static final boolean LOG_FLAG = true;//日志标识 + + //日历 + private static final String[] Group_Calendar = { + Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR + }; + //照相机 + private static final String[] Group_Camera = { + Manifest.permission.CAMERA + }; + //通讯录 + private static final String[] Group_Contacts = { + Manifest.permission.WRITE_CONTACTS, Manifest.permission.GET_ACCOUNTS, + Manifest.permission.READ_CONTACTS + }; + //定位 + private static final String[] Group_Location = { + Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION + }; + //麦克风 + private static final String[] Group_Microphone = { + Manifest.permission.RECORD_AUDIO + }; + //电话 + private static final String[] Group_Phone = { + Manifest.permission.READ_PHONE_STATE, Manifest.permission.CALL_PHONE, + Manifest.permission.READ_CALL_LOG, Manifest.permission.WRITE_CALL_LOG, + Manifest.permission.ADD_VOICEMAIL, Manifest.permission.USE_SIP, + Manifest.permission.PROCESS_OUTGOING_CALLS + }; + //传感器 + private static final String[] Group_Sensors = { + Manifest.permission.BODY_SENSORS + }; + //短信 + private static final String[] Group_Sms = { + Manifest.permission.READ_SMS, Manifest.permission.SEND_SMS, + Manifest.permission.RECEIVE_SMS, Manifest.permission.RECEIVE_MMS, + Manifest.permission.RECEIVE_WAP_PUSH + }; + //存储 + private static final String[] Group_Storage = { + Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE + }; + private static Map m_PermissionGroupList = null; + private static Map m_PermissionsMappingList = null; + + static { + initMap(); + } + + /** + * 通过权限组名来申请一组权限 + * + * @param context + * @param permissionGroupName + * @param requestCode + * @param listener + */ + public static void requestByGroupName(Activity context, String permissionGroupName, int requestCode, OnPermissionsListener listener) { + requestByGroupName(context, new String[]{permissionGroupName}, requestCode, listener); + } + + /** + * 通过权限组名来申请多组权限 + * + * @param context Activity上下文 + * @param pgNameArray 多个要申请的权限组名称 + * @param requestCode 请求码 + * @param listener 回调接口 + */ + public static void requestByGroupName(Activity context, String[] pgNameArray, int requestCode, OnPermissionsListener listener) { + showLog("requestByPermissionGroup"); + try { + //如果操作系统SDK级别在23之上(android6.0),就进行动态权限申请 + if (Build.VERSION.SDK_INT >= 23 && pgNameArray != null) { + String[] permissionsList = getAppPermissionsList(context);//应用权限列表 + ArrayList targetList = new ArrayList<>(); + if (permissionsList == null || permissionsList.length == 0) { + showLog("获得权限列表为空"); + return; + } + + for (String groupName : pgNameArray) { + ArrayList tmpPermissionList = isPermissionDeclared(permissionsList, groupName); + if (tmpPermissionList == null) {//未找到 + showLog("未找到[" + groupName + "]中的权限"); + continue; + } + + for (int i = 0; i < tmpPermissionList.size(); i++) { + //判断是否拥有权限 + int nRet = ContextCompat.checkSelfPermission(context, tmpPermissionList.get(i)); + if (nRet != PackageManager.PERMISSION_GRANTED) { + targetList.add(tmpPermissionList.get(i)); + } + } + } + + if (targetList.size() > 0) { + showLog("进行以下权限申请:" + targetList.toString()); + String[] sList = targetList.toArray(new String[0]); + ActivityCompat.requestPermissions(context, sList, requestCode); + } else { + showLog("全部权限都已授权"); + if (listener != null) { + listener.onPermissionsOwned(); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 通过权限名来申请一组权限 + * + * @param context + * @param permission + * @param requestCode + * @param listener + */ + public static void requestByPermissionName(Activity context, String permission, int requestCode, OnPermissionsListener listener) { + requestByPermissionName(context, new String[]{permission}, requestCode, listener); + } + + /** + * 通过权限名来申请多组权限 + * + * @param context Activity上下文 + * @param permissionArray 多个要申请的权限名称 + * @param requestCode 请求码 + * @param listener 回调接口 + */ + public static void requestByPermissionName(Activity context, String[] permissionArray, int requestCode, OnPermissionsListener listener) { + showLog("requestPermissions"); + try { + //如果操作系统SDK级别在23之上(android6.0),就进行动态权限申请 + if (Build.VERSION.SDK_INT >= 23 && permissionArray != null) { + ArrayList targetList = new ArrayList<>(); + for (String strPermission : permissionArray) { + //判断是否拥有权限 + int nRet = ContextCompat.checkSelfPermission(context, strPermission); + if (nRet != PackageManager.PERMISSION_GRANTED) { + targetList.add(strPermission); + } + } + + if (targetList.size() > 0) { + showLog("进行以下权限申请:" + targetList.toString()); + String[] sList = targetList.toArray(new String[0]); + ActivityCompat.requestPermissions(context, sList, requestCode); + } else { + showLog("全部权限都已授权"); + if (listener != null) { + listener.onPermissionsOwned(); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 针对申请权限时的用户操作进行处理 + * + * @param context + * @param permissions 申请的权限 + * @param grantResults 各权限的授权状态 + * @param listener 回调接口 + * @param controlFlag 控制标识,用于判断当响应禁止列表后,是否继续处理可再申请列表(避免出现同时处理禁止列表和可再申请列表,互相干扰,比如弹出两个提示框) + */ + public static void onRequestPermissionsResult(Activity context, String[] permissions, int[] grantResults, OnPermissionsListener listener, boolean controlFlag) { + try { + ArrayList requestList = new ArrayList<>();//可再申请列表 + ArrayList banList = new ArrayList<>();//禁止列表 + for (int i = 0; i < permissions.length; i++) { + if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { + showLog("[" + permissions[i] + "]权限授权成功"); + } else { + boolean nRet = ActivityCompat.shouldShowRequestPermissionRationale(context, permissions[i]); + //Log.i(TAG,"shouldShowRequestPermissionRationale nRet="+nRet); + if (nRet) {//允许重新申请 + requestList.add(permissions[i]); + } else {//禁止申请 + banList.add(permissions[i]); + } + } + } + + do { + //优先对禁止列表进行判断 + if (banList.size() > 0) { + if (listener != null) { + listener.onPermissionsForbidden(permissions, grantResults, banList); + } + if (!controlFlag) {//对禁止列表处理后,且控制标识为false,则跳过对可再申请列表的处理 + break; + } + } + if (requestList.size() > 0) { + if (listener != null) { + listener.onPermissionsDenied(permissions, grantResults, requestList); + } + } + if (banList.size() == 0 && requestList.size() == 0) { + showLog("权限授权成功"); + if (listener != null) { + listener.onPermissionsSucceed(); + } + } + } while (false); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 判断权限状态 + * + * @param context + * @param permission 权限名 + * @return + */ + public static boolean checkPermission(Context context, String permission) { + try { + //如果操作系统SDK级别在23之上(android6.0),就进行动态权限申请 + if (Build.VERSION.SDK_INT >= 23) { + int nRet = ContextCompat.checkSelfPermission(context, permission); + showLog("checkSelfPermission nRet=" + nRet); + return nRet == PackageManager.PERMISSION_GRANTED; + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 获得当前应用清单中的权限列表 + * + * @param context 应用上下文 + * @return + */ + public static String[] getAppPermissionsList(Context context) { + try { + PackageManager packageManager = context.getApplicationContext().getPackageManager(); + String packageName = context.getApplicationContext().getPackageName(); + String[] array = packageManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS).requestedPermissions; + return array; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * 判断权限列表中是否声明了指定权限组中的权限 + * + * @param permissionList 权限列表 + * @param permissionGroup 权限组名 + * @return 存在则返回找到的权限组权限,否则返回null + */ + public static ArrayList isPermissionDeclared(String[] permissionList, String permissionGroup) { + try { + if (permissionList != null && permissionGroup != null) { + String[] pmGroup = m_PermissionGroupList.get(permissionGroup); + if (pmGroup != null) { + ArrayList arrayList = new ArrayList<>(); + //遍历 + for (int i = 0; i < pmGroup.length; i++) { + String strPermission = pmGroup[i]; + for (int j = 0; j < permissionList.length; j++) { + if (strPermission.equals(permissionList[j])) {//找到指定权限组中的权限 + arrayList.add(strPermission); + break; + } + } + } + if (arrayList.size() == 0) { + return null; + } + return arrayList; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + /** + * 获得传入的权限名列表对应的中文名称 + * + * @param permissionList 权限名列表 + * @return 集合 + */ + public static Set getPermissionsNameByChinese(String[] permissionList) { + try { + if (permissionList != null) { + HashSet nameSet = new HashSet<>();//确保集合元素不重复 + String tmpName; + for (String strPermission : permissionList) { + tmpName = m_PermissionsMappingList.get(strPermission); + if (tmpName != null) { + nameSet.add(tmpName); + } + } + return nameSet; + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + private static void initMap() { + if (m_PermissionGroupList == null) { + m_PermissionGroupList = new HashMap<>(); + m_PermissionGroupList.put(Manifest.permission_group.CALENDAR, Group_Calendar); + m_PermissionGroupList.put(Manifest.permission_group.CAMERA, Group_Camera); + m_PermissionGroupList.put(Manifest.permission_group.CONTACTS, Group_Contacts); + m_PermissionGroupList.put(Manifest.permission_group.LOCATION, Group_Location); + m_PermissionGroupList.put(Manifest.permission_group.MICROPHONE, Group_Microphone); + m_PermissionGroupList.put(Manifest.permission_group.PHONE, Group_Phone); + m_PermissionGroupList.put(Manifest.permission_group.SENSORS, Group_Sensors); + m_PermissionGroupList.put(Manifest.permission_group.SMS, Group_Sms); + m_PermissionGroupList.put(Manifest.permission_group.STORAGE, Group_Storage); + } + + if (m_PermissionsMappingList == null) { + m_PermissionsMappingList = new HashMap<>(); + //日历 + for (String strPermission : Group_Calendar) { + m_PermissionsMappingList.put(strPermission, "日历"); + } + //照相机 + for (String strPermission : Group_Camera) { + m_PermissionsMappingList.put(strPermission, "摄像头"); + } + //通讯录 + for (String strPermission : Group_Contacts) { + m_PermissionsMappingList.put(strPermission, "通讯录"); + } + //定位 + for (String strPermission : Group_Location) { + m_PermissionsMappingList.put(strPermission, "位置"); + } + //麦克风 + for (String strPermission : Group_Microphone) { + m_PermissionsMappingList.put(strPermission, "麦克风"); + } + //电话 + for (String strPermission : Group_Phone) { + m_PermissionsMappingList.put(strPermission, "电话"); + } + //传感器 + for (String strPermission : Group_Sensors) { + m_PermissionsMappingList.put(strPermission, "传感器"); + } + //短信 + for (String strPermission : Group_Sms) { + m_PermissionsMappingList.put(strPermission, "短信"); + } + //存储 + for (String strPermission : Group_Storage) { + m_PermissionsMappingList.put(strPermission, "存储"); + } + } + } + + private static void showLog(String str) { + if (LOG_FLAG) { + Log.i(TAG, str); + } + } + + public interface OnPermissionsListener { + /** + * 权限都已拥有时的处理 + */ + void onPermissionsOwned(); + + /** + * 权限被禁止时的处理 + * + * @param permissions 申请的全部权限 + * @param grantResults 各权限的授权状态 + * @param pmList 禁止申请的权限列表 + */ + void onPermissionsForbidden(String[] permissions, int[] grantResults, ArrayList pmList); + + /** + * 权限被拒绝时的处理 + * + * @param permissions + * @param grantResults + * @param pmList 可再申请的权限列表 + */ + void onPermissionsDenied(String[] permissions, int[] grantResults, ArrayList pmList); + + /** + * 权限申请成功时的处理 + */ + void onPermissionsSucceed(); + } +}