一、RxPermission
1、背景
从Android6.0开始,权限分为一般权限和危险权限。危险权限除了需要再manifest中配置以外,还必须在相应功能使用前动态申请并得到用户授权。
图片.png
2、系统重要方法
1. ContextCompat.checkSelfPermission
检查应用是否具有某个危险权限。如果应用具有此权限,方法将返回 PackageManager.PERMISSION_GRANTED,并且应用可以继续操作。如果应用不具有此权限,方法将返回 PackageManager.PERMISSION_DENIED,且应用必须明确向用户要求权限。
2. ActivityCompat.requestPermissions
应用可以通过这个方法动态申请权限,调用后会弹出一个对话框提示用户授权所申请的权限。
3. ActivityCompat.shouldShowRequestPermissionRationale
如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don't ask again 选项,此方法将返回 false。如果设备规范禁止应用具有该权限,此方法也会返回 false。
4. onRequestPermissionsResult
当应用请求权限时,系统将向用户显示一个对话框。当用户响应时,系统将调用应用的 onRequestPermissionsResult() 方法,向其传递用户响应,处理对应的场景。
3、例子
public class DemoActivity extends AppCompatActivity {
private static final int REQUEST_CALL_PHONE = 100;
private static final int REQUEST_ALL = 101;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
findViewById(R.id.button1).setOnClickListener(v -> {
test1();
});
findViewById(R.id.button2).setOnClickListener(v -> {
test2();
});
}
private void test1() {
int callPhoneState = ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE);
if (callPhoneState == PackageManager.PERMISSION_GRANTED) {
callPhone();
} else {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.CALL_PHONE
}, REQUEST_CALL_PHONE);
}
}
private void test2() {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CALL_PHONE, Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_ALL);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull @org.jetbrains.annotations.NotNull String[] permissions, @NonNull @org.jetbrains.annotations.NotNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (REQUEST_CALL_PHONE == requestCode) {
if (permissions[0] == Manifest.permission.CALL_PHONE && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
callPhone();
}
} else if (REQUEST_ALL == requestCode) {
if (permissions.length == grantResults.length) {
boolean allGranted = true;
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
allGranted = false;
break;
}
}
if (allGranted) {
callPhone();
}
}
}
}
private void callPhone() {
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:18600955495"));
startActivity(intent);
}
}
4、RxPermission
1. 基本信息
This library allows the usage of RxJava with the new Android M permission model.
https://github.com/tbruyelle/RxPermissions
2.依赖
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
dependencies {
implementation 'com.github.tbruyelle:rxpermissions:0.12'
implementation "io.reactivex.rxjava3:rxjava:3.0.8"
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
}
3.例子
package com.xianbing.permissiondemo;
import android.Manifest;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.tbruyelle.rxpermissions3.Permission;
import com.tbruyelle.rxpermissions3.RxPermissions;
import io.reactivex.rxjava3.functions.Consumer;
public class DemoActivity2 extends AppCompatActivity {
final RxPermissions rxPermissions = new RxPermissions(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo2);
findViewById(R.id.button1).setOnClickListener(v -> {
demo1();
});
findViewById(R.id.button2).setOnClickListener(v -> {
demo2();
});
findViewById(R.id.button3).setOnClickListener(v -> {
demo3();
});
findViewById(R.id.button4).setOnClickListener(v -> {
demo4();
});
}
private void demo1() {
rxPermissions.request(Manifest.permission.CALL_PHONE).subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean granted) throws Throwable {
Log.i("Simon", "demo1 request CALL_PHONE aBoolean: " + granted);
}
});
}
private void demo2() {
//同时请求多个权限,只有同意了,才会回调true
rxPermissions
.request(Manifest.permission.CALL_PHONE,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
.subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean granted) throws Throwable {
Log.i("Simon", "demo2 request CALL_PHONE android WRITE_EXTERNAL_STORAGE aBoolean: " + granted);
if (granted) {
//所有权限都授予
// All requested permissions are granted
} else {
//至少一个权限没有被授予
// At least one permission is denied
}
}
});
}
private void demo3() {
//每一个权限的请求结果都会回调
rxPermissions
.requestEach(Manifest.permission.CALL_PHONE,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
.subscribe(new Consumer<Permission>() {
@Override
public void accept(Permission permission) throws Throwable {
Log.i("Simon", "demo3 requestEach permission: " + permission);
if (permission.granted) {
//权限被授予
// `permission.name` is granted !
} else if (permission.shouldShowRequestPermissionRationale) {
//权限被决绝,并且没有选中"不再询问"
// Denied permission without ask never again
} else {
//权限被决绝,并且选中"不再询问"
// Denied permission with ask never again
// Need to go to the settings
}
}
});
}
private void demo4() {
rxPermissions
.requestEachCombined(Manifest.permission.CALL_PHONE,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
.subscribe(permission -> { // will emit 1 Permission object
Log.i("Simon", "demo4 requestEachCombined permission: " + permission);
if (permission.granted) {
//所有权限都同意授予
// All permissions are granted !
} else if (permission.shouldShowRequestPermissionRationale) {
//至少有一个权限被拒绝,但并没有选择"不再询问"
// At least one denied permission without ask never again
} else {
//至少一个权限被拒绝,并且选择"不再询问"
// At least one denied permission with ask never again
// Need to go to the settings
}
});
}
}
二、RxLifeCycle
1、RxLifeCycle是什么
Lifecycle handling APIs for Android apps using RxJava
This library allows one to automatically complete sequences based on a second lifecycle stream.
This capability is useful in Android, where incomplete subscriptions can cause memory leaks.
https://github.com/trello/RxLifecycle
2、使用
1.依赖
implementation 'com.trello.rxlifecycle4:rxlifecycle:4.0.2'
// If you want to bind to Android-specific lifecycles
implementation 'com.trello.rxlifecycle4:rxlifecycle-android:4.0.2'
// If you want pre-written Activities and Fragments you can subclass as providers
implementation 'com.trello.rxlifecycle4:rxlifecycle-components:4.0.2'
2.例子
public class DemoActivity3 extends RxAppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo3);
findViewById(R.id.button).setOnClickListener(v -> {
test();
});
}
private void test() {
Observable.interval(1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(new Observer<Long>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull Long aLong) {
Log.i("Simon", "test onNext: " + aLong);
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
});
}
}
修改的地方:
1、AppCompatActivity改为RxAppCompatActivity
2、新增: .compose(bindUntilEvent(ActivityEvent.DESTROY))
网友评论