Android6.0+安装APP时申请权限
Android 6.0动态权限申请
习惯了在安装APP时弹出权限申请对话框,但是在android 6.0以后同样的代码就不弹出了。找了下资料,动态权限申请步骤如下:
步骤1
和之前一样,首先要在AndroidManifest中填写你要申请的权限。
比如申请摄像头权限:
<uses-permission android:name="android.permission.CAMERA" />
步骤2
在需要申请摄像头权限的代码里加入如下代码:
public void requestCameria() {
// checkSelfPermission 判断是否已经申请了此权限
if (ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
//如果应用之前请求过此权限但用户拒绝了请求,shouldShowRequestPermissionRationale将返回 true。
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
} else {
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA,}, 1);
}
}
}
步骤3
还需要回调函数onRequestPermissionsResult中作申请成功失败的处理:
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1) {
for (int i = 0; i < permissions.length; i++) {
if (grantResults[i] == PERMISSION_GRANTED) {
Toast.makeText(this, "" + "权限" + permissions[i] + "申请成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "" + "权限" + permissions[i] + "申请失败", Toast.LENGTH_SHORT).show();
}
}
}
}
效果如下:
RxPermissions申请权限
动态权限申请好是好,但是用户已经习惯了在安装的时候一次性申请全部权限,改变用户的习惯有点难,又要求用安装时一次性申请的方法,用RxPermissions可以实现,不多bb,实现原理可以去百度,这里的实现步骤如下:
步骤1:
和上面一样,在AndroidManifest设置要申请的权限,不然会报错:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_VIDEO" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
以上分别是摄像头,麦克风,位置,文件读写的权限。
步骤2:
编写申请对话框,代码如下:
package com.walklake.dialog;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.walklake.xmapplication.R;
import java.lang.reflect.Field;
/**
* @author czh
* @date 2019-07-22-18:52
*/
public class PermissionDialog extends DialogFragment implements View.OnClickListener {
private View mView;
private TextView mTitleTip;
private String titleText;
private OperateListener operateListener;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setStyle(DialogFragment.STYLE_NORMAL, R.style.DialogFragment_style);
setCancelable(false);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.permission_dialog, null);
mTitleTip = (TextView) mView.findViewById(R.id.title_tip);
mTitleTip.setText(titleText);
mView.findViewById(R.id.setting_permission).setOnClickListener(this);
mView.findViewById(R.id.cancel_set).setOnClickListener(this);
return mView;
}
@Override
public void onDestroyView() {
super.onDestroyView();
}
public PermissionDialog setTitle(String text) {
titleText = text;
return this;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.setting_permission:
if (operateListener != null) {
dismiss();
operateListener.onConfirm();
}
break;
case R.id.cancel_set:
if (operateListener != null) {
dismiss();
operateListener.onCancel();
}
break;
default:
break;
}
}
public PermissionDialog setOperateListener(OperateListener operateListener) {
this.operateListener = operateListener;
return this;
}
/***
*
* @param manager
* @param tag
*/
@Override
public void show(FragmentManager manager, String tag) {
try {
Field mDismissed = this.getClass().getSuperclass().getDeclaredField("mDismissed");
Field mShownByMe = this.getClass().getSuperclass().getDeclaredField("mShownByMe");
mDismissed.setAccessible(true);
mShownByMe.setAccessible(true);
mDismissed.setBoolean(this, false);
mShownByMe.setBoolean(this, true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
FragmentTransaction ft = manager.beginTransaction();
ft.add(this, tag);
ft.commitAllowingStateLoss();
}
public interface OperateListener {
/**
* 取消设置
*/
void onCancel();
/**
* 设置
*/
void onConfirm();
}
}
以上这段代码需要在res/layout里增加一个permission_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layoutRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#16686868"
android:gravity="center"
android:orientation="vertical"
android:padding="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="30dp"
android:layout_marginStart="30dp"
android:layout_marginRight="30dp"
android:layout_marginEnd="30dp"
android:background="#424242"
android:orientation="vertical"
android:padding="15dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start|center_vertical"
android:minHeight="60dp"
android:text="@string/permission_request"
android:textColor="@android:color/white" />
<TextView
android:id="@+id/title_tip"<color name="transparent">#00000000</color>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:text="在设置-应用-超级看看-权限"
android:textColor="@android:color/white" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|right"
android:orientation="horizontal">
<TextView
android:id="@+id/cancel_set"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="15dp"
android:text="@string/common_cancel"
android:textColor="@android:color/white" />
<TextView
android:id="@+id/setting_permission"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="15dp"
android:paddingLeft="15dp"
android:paddingStart="15dp"
android:text="@string/common_skip"
android:textColor="@color/theme_color" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
还有在styles.xml里添加以下这一段:
<resources>
<style name="DialogFragment_style" parent="@android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">false</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:background">@android:color/transparent</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:backgroundDimAmount">0.6</item>
</style>
</resources>
colors.xml里添加用到的color:
<color name="transparent">#00000000</color>
#00000000
步骤3:
在strings.xml里添加这一段:
<string name="all_permission">Authorize SD Card Read and Write Rights, Location (Used for Fast Configuration to Acquire WiFi) Rights, Camera Rights and Recording (Used for Interview) Rights</string>
然后在mainactivity的oncreate里加入以下代码:
rxPermissions = new RxPermissions(this);
checkPermission(getString(R.string.all_permission), Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO);
其中checkPermission方法的代码如下:
private boolean checkPermission(final String permissionTitle, final String... permission) {
try{
final boolean[] result = new boolean[1];
rxPermissions.requestEach(permission).subscribe(new io.reactivex.functions.Consumer<Permission>() {
@Override
public void accept(final Permission permission) throws Exception {
if (permission.granted) {
result[0] = true;
permissionGranted(permission);
} else if (permission.shouldShowRequestPermissionRationale) {
result[0] = false;
if (mPermissionDialog == null) {
mPermissionDialog = new PermissionDialog();
}
if (!mPermissionDialog.isAdded()) {
mPermissionDialog.setTitle(permissionTitle);
mPermissionDialog.setOperateListener(new PermissionDialog.OperateListener() {
@Override
public void onCancel() {
result[0] = false;
permissionResult(false,permission);
}
@Override
public void onConfirm() {
permissionResult(true,permission);
result[0] = true;
}
});
mPermissionDialog.show(getSupportFragmentManager(), "mPermissionDialog");
}
} else {
// Need to go to the settings
if (mPermissionDialog == null) {
mPermissionDialog = new PermissionDialog();
}
if (!mPermissionDialog.isAdded()) {
mPermissionDialog.setTitle(permissionTitle);
mPermissionDialog.setOperateListener(new PermissionDialog.OperateListener() {
@Override
public void onCancel() {
result[0] = false;
permissionResult(false,permission);
}
@Override
public void onConfirm() {
permissionResult(true,permission);
result[0] = true;
}
});
mPermissionDialog.show(getSupportFragmentManager(), "mPermissionDialog");
}
}
}
});
return result[0];
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private void permissionGranted(Permission permission) {
}
private void permissionResult(boolean isSuccess,Permission permission){
}
运行效果:
参考博客: