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。