如题···就记录一下代码
- 这个类是封装的判断是否有权限的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
https://github.com/BINBINXIAO/RxPermisson
网友评论