前言
之前有講到PermissionsDispatcher動態(tài)權(quán)限申請
的使用贵试,大叫感興趣的話可參考
PermissionsDispatcher動態(tài)權(quán)限申請
PermissionsDispatcher動態(tài)權(quán)限申請kotlin版
不得不說PermissionsDispatcher
庫還是很厲害的矛缨。然后又看了下其他的權(quán)限庫,發(fā)現(xiàn)RxPermission
用得也比較多儒搭,為了方便使用,我將RxPermission
做了下簡單的封裝PermissionHelper2
择份,下面就來講講它的使用吧履植。
今天涉及內(nèi)容:
- 添加依賴
- PermissionHelper2簡單介紹
- PermissionHelper2在activity中使用
- 效果圖及項目結(jié)構(gòu)圖
- PermissionHelper2及相關(guān)源碼
一. 添加依賴
rxpermissions
借助了rxandroid
和rxjava
進行構(gòu)建,項目中也需要依賴rxandroid
和rxjava
相關(guān)庫陪汽。
在項目app_nodule
對應(yīng)的build.gradle
中添加依賴:
dependencies {
//rxandroid3.x
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
//rxjava3.x
implementation 'io.reactivex.rxjava3:rxjava:3.1.5'
//rxpermissions
implementation 'com.github.tbruyelle:rxpermissions:0.12'
//其他代碼此處忽略
//......
}
二. PermissionHelper2簡單介紹
PermissionHelper2
是一個單例類训唱,其初始化如下:
PermissionHelper2.getInstance()
此類涉及以下常用方法:
/***
* 申請單個權(quán)限
*
* 注: 同意后再申請此權(quán)限則不再彈出提示框
*
* @param permission:權(quán)限,如 Manifest.permission.READ_EXTERNAL_STORAGE
* @param activityOrFragment:FragmentActivity或 Fragment實例
* @return access: true:申請成功 fasle:申請失敗
*/
public void request(String permission, ViewModelStoreOwner activityOrFragment, IPermissionResultListener listener) ;
/***
* 申請單個權(quán)限,獲得詳細信息
*
* @param permission 權(quán)限挚冤,如 Manifest.permission.READ_EXTERNAL_STORAGE
* @param activityOrFragment FragmentActivity或 Fragment實例
*/
public void requestInfo(String permission, ViewModelStoreOwner activityOrFragment, IPermissionResultInfoListener listener)
/***
* 申請多個權(quán)限(返回一個permission對象)
*
* 注: 只要有一個禁止况增,則返回false;全部同意训挡,則返回true
* 某個權(quán)限同意后澳骤,之后再申請此權(quán)限則不再彈出提示框,其他的會繼續(xù)彈出
*
* @param permissions 權(quán)限數(shù)組
* @param activityOrFragment FragmentActivity或 Fragment實例
* @return access: true:申請成功 fasle:申請失敗
*/
public void requestEach(String permissions[], ViewModelStoreOwner activityOrFragment, IPermissionResultListener listener)
/***
* 申請多個權(quán)限,獲得詳細信息(返回多個permission對象)
*
* @param permissions 權(quán)限數(shù)組
* @param activityOrFragment FragmentActivity或 Fragment實例
*/
public void requestEachInfo(String permissions[], ViewModelStoreOwner activityOrFragment, IPermissionResultInfoListener listener)
/***
* 申請多個權(quán)限舍哄,獲取合并后的詳細信息
*
* @param permissions 權(quán)限數(shù)組
* @param activityOrFragment FragmentActivity或 Fragment實例
*/
public void requestEachCombinedInfo(String permissions[], ViewModelStoreOwner activityOrFragment, IPermissionResultInfoListener listener)
/**
* 檢查某個權(quán)限是否被申請
*
* @param permisson 權(quán)限數(shù)組
* @param activityOrFragment FragmentActivity或 Fragment實例
* @return true:有該權(quán)限 fasle:無該權(quán)限
*/
public boolean checkPermission(String permisson, ViewModelStoreOwner activityOrFragment)
三. PermissionHelper2在activity中使用
在使用之前宴凉,需要在Manifast.xml
中添加以下權(quán)限:
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
然后誊锭,為了兼容Android10
權(quán)限申請表悬,需要在Manifast.xml
文件的自定義application
標簽中添加如下屬性:
<application
android:requestLegacyExternalStorage="true" //添加此屬性兼容Android10
//其他代碼省略
//......
>
<activity
.../>
......
</application>
下面以拍照和文件讀寫權(quán)限申請為例,再添加以上所述之外丧靡,Manifast.xml
中需要追加以下三個權(quán)限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
下面給出PermissionHelper2
在MainActivity
中調(diào)用代碼:
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.tbruyelle.rxpermissions3.Permission;
import com.testdemo.util.Util;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView mTv;
private Button mBtn;
private Button mBtn2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
setListener();
}
private void initView() {
mTv = findViewById(R.id.tv_text);
mBtn = findViewById(R.id.btn_test);
mBtn2 = findViewById(R.id.btn_test2);
}
private void initData() {
}
private void setListener() {
mBtn.setOnClickListener(this);
mBtn2.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_test:
//申請單個權(quán)限
String permission = Manifest.permission.CAMERA;
PermissionHelper2.getInstance().requestInfo(permission, MainActivity.this, new PermissionHelper2.IPermissionResultInfoListener() {
@Override
public void checkPermission(Permission permission) {
if (permission.granted) {//All權(quán)限同意后調(diào)用
Util.i("======權(quán)限都通過=======");
toast("====權(quán)限申請成功===");
} else if (permission.shouldShowRequestPermissionRationale) {
//只要有一個選擇:禁止蟆沫,但沒有選擇“以后不再詢問”籽暇,以后申請權(quán)限,會繼續(xù)彈出提示
Util.i(" 拒絕權(quán)限饭庞,并沒有勾選‘不再詢問’,下次點擊會繼續(xù)彈出提示=");
toast("====權(quán)限申請失敗===");
} else {
// but有個問題:去設(shè)置頁面手動開啟權(quán)限后回到app戒悠,回調(diào)不能自動執(zhí)行允許權(quán)限的代碼,
// 即沒辦法自動進入App,需要重啟App才正常舟山,是否可以在onResume()里處理绸狐?
Util.i("======彈框去設(shè)置界面=======");
showAlertDialog("權(quán)限申請",
"需要獲取手機相關(guān)權(quán)限,是否去設(shè)置界面?",
"確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//去設(shè)置界面
goToSetting(MainActivity.this);
}
},
"取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Util.i("========取消了權(quán)限======");
}
});
}
}
});
break;
case R.id.btn_test2:
//申請一組權(quán)限
String permissons[] = {Manifest.permission.CAMERA,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
PermissionHelper2.getInstance().requestEachCombinedInfo(permissons, MainActivity.this, new PermissionHelper2.IPermissionResultInfoListener() {
@Override
public void checkPermission(Permission permission) {
if (permission.granted) {//All權(quán)限同意后調(diào)用
Util.i("======所有權(quán)限申請成功=======");
toast("====所有權(quán)限申請成功===");
} else if (permission.shouldShowRequestPermissionRationale) {
//只要有一個選擇:禁止,但沒有選擇“以后不再詢問”累盗,以后申請權(quán)限寒矿,會繼續(xù)彈出提示
Util.i(" 拒絕權(quán)限,并沒有勾選‘不再詢問’,下次點擊會繼續(xù)彈出提示=");
toast("====部分權(quán)限申請失敗===");
} else {
// but有個問題:去設(shè)置頁面手動開啟權(quán)限后回到app若债,回調(diào)不能自動執(zhí)行允許權(quán)限的代碼符相,
// 即沒辦法自動進入App,需要重啟App才正常,是否可以在onResume()里處理蠢琳?
Util.i("======彈框去設(shè)置界面=======");
showAlertDialog("權(quán)限申請",
"需要獲取手機相關(guān)權(quán)限,是否去設(shè)置界面?",
"確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//去設(shè)置界面
goToSetting(MainActivity.this);
}
},
"取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Util.i("========取消了權(quán)限======");
}
});
}
}
});
break;
default:
break;
}
}
/**
* 含有標題啊终、內(nèi)容、兩個按鈕的對話框
**/
protected AlertDialog showAlertDialog(String title, String message, String positiveText,
DialogInterface.OnClickListener onPositiveClickListener, String negativeText,
DialogInterface.OnClickListener onNegativeClickListener) {
AlertDialog alertDialog = new AlertDialog.Builder(this).setTitle(title).setMessage(message)
.setPositiveButton(positiveText, onPositiveClickListener).setNegativeButton(negativeText, onNegativeClickListener).show();
return alertDialog;
}
protected void toast(String message) {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
}
/***
* 去設(shè)置界面
*/
public static void goToSetting(Context context) {
//go to setting view
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", context.getPackageName(), null);
intent.setData(uri);
context.startActivity(intent);
}
}
四. 效果圖及項目結(jié)構(gòu)圖
五. PermissionHelper2及相關(guān)源碼
在PermissionHelper2
使用前涉及到一個工具類的Util
,下面給出Util
類代碼: