判斷手機是否開啟許可權 若無跳轉到手機設定介面
如題···就記錄一下程式碼
- 這個類是封裝的判斷是否有許可權的Rx類,可以直接用。
import android.annotation.TargetApi; import android.app.Activity; import android.app.FragmentManager; import android.os.Build; import android.support.annotation.NonNull; import android.text.TextUtils; import java.util.ArrayList; import java.util.List; import io.reactivex.Observable; import io.reactivex.ObservableSource; import io.reactivex.ObservableTransformer; import io.reactivex.functions.Function; import io.reactivex.subjects.PublishSubject; /** * author:luck */ public class RxPermissions { public static final String TAG = "RxPermissions"; public static final Object TRIGGER = new Object(); public RxPermissionsFragment mRxPermissionsFragment; public RxPermissions(@NonNull Activity activity) { mRxPermissionsFragment = getRxPermissionsFragment(activity); } private RxPermissionsFragment getRxPermissionsFragment(Activity activity) { RxPermissionsFragment rxPermissionsFragment = null; try { rxPermissionsFragment = findRxPermissionsFragment(activity); boolean isNewInstance = rxPermissionsFragment == null; if (isNewInstance) { rxPermissionsFragment = new RxPermissionsFragment(); FragmentManager fragmentManager = activity.getFragmentManager(); fragmentManager .beginTransaction() .add(rxPermissionsFragment, TAG) .commitAllowingStateLoss(); fragmentManager.executePendingTransactions(); } } catch (Exception e) { e.printStackTrace(); } return rxPermissionsFragment; } private RxPermissionsFragment findRxPermissionsFragment(Activity activity) { return (RxPermissionsFragment) activity.getFragmentManager().findFragmentByTag(TAG); } public void setLogging(boolean logging) { mRxPermissionsFragment.setLogging(logging); } /** * Map emitted items from the source observable into {@code true} if permissions in parameters * are granted, or {@code false} if not. * <p> * If one or several permissions have never been requested, invoke the related framework method * to ask the user if he allows the permissions. */ @SuppressWarnings("WeakerAccess") public <T> ObservableTransformer<T, Boolean> ensure(final String... permissions) { return new ObservableTransformer<T, Boolean>() { @Override public ObservableSource<Boolean> apply(Observable<T> o) { return request(o, permissions) // Transform Observable<Permission> to Observable<Boolean> .buffer(permissions.length) .flatMap(new Function<List<Permission>, ObservableSource<Boolean>>() { @Override public ObservableSource<Boolean> apply(List<Permission> permissions) throws Exception { if (permissions.isEmpty()) { // Occurs during orientation change, when the subject receives onComplete. // In that case we don't want to propagate that empty list to the // subscriber, only the onComplete. return Observable.empty(); } // Return true if all permissions are granted. for (Permission p : permissions) { if (!p.granted) { return Observable.just(false); } } return Observable.just(true); } }); } }; } /** * Map emitted items from the source observable into {@link Permission} objects for each * permission in parameters. * <p> * If one or several permissions have never been requested, invoke the related framework method * to ask the user if he allows the permissions. */ @SuppressWarnings("WeakerAccess") public <T> ObservableTransformer<T, Permission> ensureEach(final String... permissions) { return new ObservableTransformer<T, Permission>() { @Override public ObservableSource<Permission> apply(Observable<T> o) { return request(o, permissions); } }; } /** * Request permissions immediately, <b>must be invoked during initialization phase * of your application</b>. */ @SuppressWarnings({"WeakerAccess", "unused"}) public Observable<Boolean> request(final String... permissions) { return Observable.just(TRIGGER).compose(ensure(permissions)); } /** * Request permissions immediately, <b>must be invoked during initialization phase * of your application</b>. */ @SuppressWarnings({"WeakerAccess", "unused"}) public Observable<Permission> requestEach(final String... permissions) { return Observable.just(TRIGGER).compose(ensureEach(permissions)); } private Observable<Permission> request(final Observable<?> trigger, final String... permissions) { if (permissions == null || permissions.length == 0) { throw new IllegalArgumentException("RxPermissions.request/requestEach requires at least one input permission"); } return oneOf(trigger, pending(permissions)) .flatMap(new Function<Object, Observable<Permission>>() { @Override public Observable<Permission> apply(Object o) throws Exception { return requestImplementation(permissions); } }); } private Observable<?> pending(final String... permissions) { for (String p : permissions) { if (!mRxPermissionsFragment.containsByPermission(p)) { return Observable.empty(); } } return Observable.just(TRIGGER); } private Observable<?> oneOf(Observable<?> trigger, Observable<?> pending) { if (trigger == null) { return Observable.just(TRIGGER); } return Observable.merge(trigger, pending); } @TargetApi(Build.VERSION_CODES.M) private Observable<Permission> requestImplementation(final String... permissions) { List<Observable<Permission>> list = new ArrayList<>(permissions.length); List<String> unrequestedPermissions = new ArrayList<>(); // In case of multiple permissions, we create an Observable for each of them. // At the end, the observables are combined to have a unique response. for (String permission : permissions) { mRxPermissionsFragment.log("Requesting permission " + permission); if (isGranted(permission)) { // Already granted, or not Android M // Return a granted Permission object. list.add(Observable.just(new Permission(permission, true, false))); continue; } if (isRevoked(permission)) { // Revoked by a policy, return a denied Permission object. list.add(Observable.just(new Permission(permission, false, false))); continue; } PublishSubject<Permission> subject = mRxPermissionsFragment.getSubjectByPermission(permission); // Create a new subject if not exists if (subject == null) { unrequestedPermissions.add(permission); subject = PublishSubject.create(); mRxPermissionsFragment.setSubjectForPermission(permission, subject); } list.add(subject); } if (!unrequestedPermissions.isEmpty()) { String[] unrequestedPermissionsArray = unrequestedPermissions.toArray(new String[unrequestedPermissions.size()]); requestPermissionsFromFragment(unrequestedPermissionsArray); } return Observable.concat(Observable.fromIterable(list)); } /** * Invokes Activity.shouldShowRequestPermissionRationale and wraps * the returned value in an observable. * <p> * In case of multiple permissions, only emits true if * Activity.shouldShowRequestPermissionRationale returned true for * all revoked permissions. * <p> * You shouldn't call this method if all permissions have been granted. * <p> * For SDK < 23, the observable will always emit false. */ @SuppressWarnings("WeakerAccess") public Observable<Boolean> shouldShowRequestPermissionRationale(final Activity activity, final String... permissions) { if (!isMarshmallow()) { return Observable.just(false); } return Observable.just(shouldShowRequestPermissionRationaleImplementation(activity, permissions)); } @TargetApi(Build.VERSION_CODES.M) private boolean shouldShowRequestPermissionRationaleImplementation(final Activity activity, final String... permissions) { for (String p : permissions) { if (!isGranted(p) && !activity.shouldShowRequestPermissionRationale(p)) { return false; } } return true; } @TargetApi(Build.VERSION_CODES.M) void requestPermissionsFromFragment(String[] permissions) { mRxPermissionsFragment.log("requestPermissionsFromFragment " + TextUtils.join(", ", permissions)); mRxPermissionsFragment.requestPermissions(permissions); } /** * Returns true if the permission is already granted. * <p> * Always true if SDK < 23. */ @SuppressWarnings("WeakerAccess") public boolean isGranted(String permission) { return !isMarshmallow() || mRxPermissionsFragment.isGranted(permission); } /** * Returns true if the permission has been revoked by a policy. * <p> * Always false if SDK < 23. */ @SuppressWarnings("WeakerAccess") public boolean isRevoked(String permission) { return isMarshmallow() && mRxPermissionsFragment.isRevoked(permission); } boolean isMarshmallow() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; } void onRequestPermissionsResult(String permissions[], int[] grantResults) { mRxPermissionsFragment.onRequestPermissionsResult(permissions, grantResults, new boolean[permissions.length]); } }
使用也是相當的簡單,
對於實現做一下程式碼的書寫。
初始:
private RxPermissions rxPermissions; oncreate初始化· rxPermissions = new RxPermissions(this);
引用:
private void checkLocation1() { //檢測是否可 (基站)獲取位置資訊 rxPermissions.request(Manifest.permission.ACCESS_COARSE_LOCATION) .subscribe(new Observer<Boolean>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(Boolean aBoolean) { if (aBoolean) {//aBoolean返回檢測的結果。true為包含 checkLocation2();//這是檢測下一個許可權·· } else { showToast(getString(R.string.request_permission_location)); getAppDetailSettingIntent();//沒有許可權跳轉設定介面開啟 } } @Override public void onError(Throwable e) { } @Override public void onComplete() { } }); }
上述部分介紹了某一許可權的單獨判斷,如果想要更多的許可權判斷的話,在onNext中boolean判斷方法中書寫。 此處再類推一個方法,checkLocation2()
//同上 private void checkLocation2() { rxPermissions.request(Manifest.permission.ACCESS_FINE_LOCATION) .subscribe(new Observer<Boolean>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(Boolean aBoolean) { if (aBoolean) { checkWritePermission();//同上 } else { showToast(getString(R.string.request_permission_location)); getAppDetailSettingIntent();//同上 } } @Override public void onError(Throwable e) { } @Override public void onComplete() { } }); }
設定介面跳轉,
只能跳轉部分手機,另外一些定製手機需要單獨處理。
/** * 這個地方還需要進一步測試。 */ // TODO: 很多不同的手機,還需要單獨的處理 private void getAppDetailSettingIntent(){ Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if(Build.VERSION.SDK_INT >= 9){ intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); intent.setData(Uri.fromParts("package", getPackageName(), null)); } else if(Build.VERSION.SDK_INT <= 8){ intent.setAction(Intent.ACTION_VIEW); intent.setClassName("com.android.settings","com.android.settings.InstalledAppDetails"); intent.putExtra("com.android.settings.ApplicationPkgName", getPackageName()); } startActivity(intent); }
詳細程式碼,見github
ofollow,noindex">https://github.com/BINBINXIAO/RxPermisson