Android对6.0及以上的版本做了更强的权限控制。如打电话这种需要动态申请。我推荐使用github上start最多的PermissionsDispatcher作为权限管理。
一,使用的Androidstudio版本为3.5.3
二,使用的permissionsdispatcher版本为3.2.0
github地址为:https://github.com/permissions-dispatcher/PermissionsDispatcher
基本步骤如下: AndroidManifest 1.将以下行添加到AndroidManifest.xml:
2.仓库地址: repositories { jcenter() maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local/' } } 3.添加依赖 dependencies { implementation "org.permissionsdispatcher:permissionsdispatcher:${latest.version}" annotationProcessor "org.permissionsdispatcher:permissionsdispatcher-processor:${latest.version}" }
4.添加代码: package com.***.***.module.my.active; import permissions.dispatcher.NeedsPermission; import permissions.dispatcher.OnNeverAskAgain; import permissions.dispatcher.OnPermissionDenied; import permissions.dispatcher.RuntimePermissions; @RuntimePermissions public class EstablishActiveActivity extends BaseActivity implements EstablishActiveContract.View, View.OnClickListener { private static final String TAG = EstablishActiveActivity.class.getSimpleName(); @Inject StandardDialog mStandardDialog; @BindView(R.id.head_title) TextView mHeadTitle; protected String[] locationPermissions = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}; private static final int GPS_REQUEST_CODE = 2000; private double longitude; private double latitude; @Override protected int getContentViewID() { return R.layout.activity_establish_active; } @Override protected void injectDagger() { activityComponent().inject(this); } @Override protected void initViewsAndEvents() { mActivePresenter.attachView(this); mHeadTitle.setText(getString(R.string.establish_create_active)); }
@OnClick(R.id.establish_exercise_location_layout) public void onViewClicked(View view) { switch (view.getId()) { case R.id.establish_exercise_location_layout: SoftInputManager.closeSoftInput(this, mTvLocation); if (!checkPermissions(mContext, locationPermissions)) {//是否有定位权限 EstablishActiveActivityPermissionsDispatcher.getLocationWithPermissionCheck(this); return; } if (!isGPSOpen(mContext)) {//是否打开GPS mStandardDialog.show(); mStandardDialog.setTitle(getString(R.string.permission_title)); mStandardDialog.setContent(getString(R.string.permission_location)); mStandardDialog.setOk(getString(R.string.goto_set)); mStandardDialog.setCancel(getString(R.string.cancel)); mStandardDialog.setOnDialogClickListener(new StandardDialog.OnDialogClickListener() { @Override public void btnOkClick() { //跳转GPS设置界面 Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); startActivityForResult(intent, GPS_REQUEST_CODE); } @Override public void btnCancelClick() { } }); return; } MapPointActivity.actionStart(this); break; } } /** * 权限操作 定位权限 * 相关操作在@NeedsPermission,@OnPermissionDenied,@OnNeverAskAgain中都有 */ //获取权限 @NeedsPermission({Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}) void getLocation() {//同意权限 } //拒绝权限 @OnPermissionDenied({Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}) void getLocationDenied() { if (!mStandardDialog.isShowing()) { mStandardDialog.show(); mStandardDialog.setTitle(getString(R.string.permission_title)); mStandardDialog.setContent(getString(R.string.permission_location)); mStandardDialog.setOk(getString(R.string.goto_set)); mStandardDialog.setCancel(getString(R.string.cancel)); mStandardDialog.setOnDialogClickListener(new StandardDialog.OnDialogClickListener() { @Override public void btnOkClick() { JumpPermissionUtil.SystemConfig(EstablishActiveActivity.this); } @Override public void btnCancelClick() { } }); } } //不在提醒权限 @OnNeverAskAgain({Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}) void externalLocationNever() { if (!mStandardDialog.isShowing()) { mStandardDialog.show(); mStandardDialog.setTitle(getString(R.string.permission_title)); mStandardDialog.setContent(getString(R.string.permission_location)); mStandardDialog.setOk(getString(R.string.goto_set)); mStandardDialog.setCancel(getString(R.string.cancel)); mStandardDialog.setOnDialogClickListener(new StandardDialog.OnDialogClickListener() { @Override public void btnOkClick() { JumpPermissionUtil.SystemConfig(EstablishActiveActivity.this); } @Override public void btnCancelClick() { } }); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); // 注意:将权限处理委托给生成的方法。 EstablishActiveActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults); } }
/** * 检查权限是否开启 */ public static boolean checkPermissions(Context context, String[] permissions) { for (String permission : permissions) { if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { return false; } } return true; } /** * 判断GPS是否开启,GPS或者AGPS开启一个就认为是开启的 * * @return true 表示开启 */ public static boolean isGPSOpen(final Context context) { LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); if (locationManager != null) { // 通过GPS卫星定位,定位级别可以精确到街(通过24颗卫星定位,在室外和空旷的地方定位准确、速度快) boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); // 通过WLAN或移动网络(3G/2G)确定的位置(也称作AGPS,辅助GPS定位。主要用于在室内或遮盖物(建筑群或茂密的深林等)密集的地方定位) boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); if (gps || network) { return true; } } return false; }
4.EstablishActiveActivityPermissionsDispatcher类需要如下图操作才可以对应生成,规则是当前类名+PermissionsDispatcher。