android 10(Q)权限动态申请(包含自定义Dialog样式(title可设置图片)):照相机权限、定位权限、读写存储权限、读手机信息权限、悬浮窗权限、安装未知来源应用权限

一,自定义Dialog样式

  • 1,drawable 中准备一个Dialog背景样式bg_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#ffffff" />
    <stroke
        android:width="0.8dp"
        android:color="#ffffff" />
    <!-- 圆角 -->
    <corners android:radius="6dp" />
</shape>
  • 2,styles.xml中添加Dialog样式
 <style name="CustomDialog" parent="android:style/Theme.Dialog">
        <!--背景颜色及和透明程度-->
        <item name="android:windowBackground">@android:color/transparent</item>
        <!--是否去除标题 -->
        <item name="android:windowNoTitle">true</item>
        <!--是否去除边框-->
        <item name="android:windowFrame">@null</item>
        <!--是否浮现在activity之上-->
        <item name="android:windowIsFloating">true</item>
        <!--是否模糊-->
        <item name="android:backgroundDimEnabled">true</item>
    </style>
  • 3,在layout中新建common_dialog_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minWidth="260dp"
        android:layout_centerInParent="true"
        android:paddingTop="16dp"
        android:background="@drawable/bg_dialog"
        android:orientation="vertical">
        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:layout_marginBottom="16dp"
            android:gravity="center"
            android:text="消息提示"
            android:visibility="visible"
            android:textColor="#333333"
            android:textSize="18sp" />
        <ImageView
            android:id="@+id/image"
            android:layout_gravity="center"
            android:maxHeight="150dp"
            android:maxWidth="150dp"
            android:layout_marginBottom="10dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:visibility="visible"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView
            android:id="@+id/message"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center|left"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:lineSpacingExtra="3dp"
            android:lineSpacingMultiplier="1.2"
            android:textSize="14dp"
            android:textColor="#999999"
            android:text="提示消息提示消息提示消息提示消息提示消息提示消息提示消息提示消息" />

        <View
            android:layout_width="match_parent"
            android:layout_height="1px"
            android:layout_marginTop="16dp"
            android:background="#E4E4E4" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:id="@+id/negtive"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:paddingTop="16dp"
                android:paddingBottom="16dp"
                android:layout_weight="1"
                android:background="@null"
                android:gravity="center"
                android:singleLine="true"
                android:text="@string/Reject_and_Exit"
                android:textColor="#999999"
                android:textSize="16sp" />

            <View
                android:id="@+id/column_line"
                android:layout_width="1px"
                android:layout_height="match_parent"
                android:background="#E4E4E4" />

            <Button
                android:id="@+id/positive"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginRight="10dp"
                android:layout_weight="1"
                android:paddingTop="16dp"
                android:paddingBottom="16dp"
                android:background="@null"
                android:gravity="center"
                android:singleLine="true"
                android:text="@string/To_add_permissions"
                android:textColor="#02704B"
                android:textSize="16sp" />
        </LinearLayout>
    </LinearLayout>
</RelativeLayout>

Dialog布局效果如下:
在这里插入图片描述

  • 4 ,编写对应的java类CommonDialog.java
package mlab.android.speedgame.ui;

import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import mlab.android.speedgame.R;


/**
 * description:自定义dialog
 */

public class CommonDialog extends Dialog {
    /**
     * 显示的图片
     */
    private ImageView imageIv ;

    /**
     * 显示的标题
     */
    private TextView titleTv ;

    /**
     * 显示的消息
     */
    private TextView messageTv ;

    /**
     * 确认和取消按钮
     */
    private Button negtiveBn ,positiveBn;

    private Context context;
    /**
     * 按钮之间的分割线
     */
    private View columnLineView ;
    public CommonDialog(Context context) {
        super(context, R.style.CustomDialog);
        this.context = context;
    }

    /**
     * 都是内容数据
     */
    private String message;
    private String title;
    private String positive,negtive ;
    private int imageResId = -1 ;

    /**
     * 底部是否只有一个按钮
     */
    private boolean isSingle = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.common_dialog_layout);
        //按空白处不能取消动画
        setCanceledOnTouchOutside(false);
        //初始化界面控件
        initView();
        //初始化界面数据
        refreshView();
        //初始化界面控件的事件
        initEvent();
    }

    /**
     * 初始化界面的确定和取消监听器
     */
    private void initEvent() {
        //设置确定按钮被点击后,向外界提供监听
        positiveBn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if ( onClickBottomListener!= null) {
                    onClickBottomListener.onPositiveClick();
                }
            }
        });
        //设置取消按钮被点击后,向外界提供监听
        negtiveBn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if ( onClickBottomListener!= null) {
                    onClickBottomListener.onNegtiveClick();
                }
            }
        });
    }

    /**
     * 初始化界面控件的显示数据
     */
    private void refreshView() {
        //如果用户自定了title和message
        if (!TextUtils.isEmpty(title)) {
            titleTv.setText(title);
            titleTv.setVisibility(View.VISIBLE);
        }else {
            titleTv.setVisibility(View.GONE);
        }
        if (!TextUtils.isEmpty(message)) {
            messageTv.setText(message);
        }
        //如果设置按钮的文字
        if (!TextUtils.isEmpty(positive)) {
            positiveBn.setText(positive);
        }else {
            positiveBn.setText(context.getResources().getString(R.string.To_add_permissions));
        }
        if (!TextUtils.isEmpty(negtive)) {
            negtiveBn.setText(negtive);
        }else {
            negtiveBn.setText(context.getResources().getString(R.string.Reject_and_Exit));
        }

        if (imageResId!=-1){
            imageIv.setImageResource(imageResId);
            imageIv.setVisibility(View.VISIBLE);
        }else {
            imageIv.setVisibility(View.GONE);
        }
        /**
         * 只显示一个按钮的时候隐藏取消按钮,回掉只执行确定的事件
         */
        if (isSingle){
            columnLineView.setVisibility(View.GONE);
            negtiveBn.setVisibility(View.GONE);
        }else {
            negtiveBn.setVisibility(View.VISIBLE);
            columnLineView.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public void show() {
        super.show();
        refreshView();
    }

    /**
     * 初始化界面控件
     */
    private void initView() {
        negtiveBn = (Button) findViewById(R.id.negtive);
        positiveBn = (Button) findViewById(R.id.positive);
        titleTv = (TextView) findViewById(R.id.title);
        messageTv = (TextView) findViewById(R.id.message);
        imageIv = (ImageView) findViewById(R.id.image);
        columnLineView = findViewById(R.id.column_line);
    }

    /**
     * 设置确定取消按钮的回调
     */
    public OnClickBottomListener onClickBottomListener;
    public CommonDialog setOnClickBottomListener(OnClickBottomListener onClickBottomListener) {
        this.onClickBottomListener = onClickBottomListener;
        return this;
    }
    public interface OnClickBottomListener{
        /**
         * 点击确定按钮事件
         */
        public void onPositiveClick();
        /**
         * 点击取消按钮事件
         */
        public void onNegtiveClick();
    }

    public String getMessage() {
        return message;
    }

    public CommonDialog setMessage(String message) {
        this.message = message;
        return this ;
    }

    public String getTitle() {
        return title;
    }

    public CommonDialog setTitle(String title) {
        this.title = title;
        return this ;
    }

    public String getPositive() {
        return positive;
    }

    public CommonDialog setPositive(String positive) {
        this.positive = positive;
        return this ;
    }

    public String getNegtive() {
        return negtive;
    }

    public CommonDialog setNegtive(String negtive) {
        this.negtive = negtive;
        return this ;
    }

    public int getImageResId() {
        return imageResId;
    }

    public boolean isSingle() {
        return isSingle;
    }

    public CommonDialog setSingle(boolean single) {
        isSingle = single;
        return this ;
    }

    public CommonDialog setImageResId(int imageResId) {
        this.imageResId = imageResId;
        return this ;
    }

}

5,部分string.xml资源

<string name="To_add_permissions">去添加 权限</string>
<string name="Reject_and_Exit">拒绝则 退出</string>

6,调用自定义Dialog

CommonDialog dialog = new CommonDialog( mActivity);
                dialog.setMessage(str)
                        .setTitle(mActivity.getApplication().getString(R.string.following_permissions))
                        .setSingle(false).setOnClickBottomListener(new CommonDialog.OnClickBottomListener() {
                    @RequiresApi(api = Build.VERSION_CODES.M)
                    @Override
                    public void onPositiveClick() {
                        dialog.dismiss();
                        mActivity.requestPermissions(permissions,requestCode);
                    }

                    @Override
                    public void onNegtiveClick() {
                        dialog.dismiss();
                        // 若拒绝了所需的权限请求,则退出应用
                        mActivity.finish();
                        System.exit(0);
                    }
                }).show();

二,权限动态申请

  • 1,针对照相机权限(CAMERA),定位权限(ACCESS_FINE_LOCATION)(ACCESS_COARSE_LOCATION),读手机信息权限(READ_PHONE_STATE),读写存储权限(READ_EXTERNAL_STORAGE)(WRITE_EXTERNAL_STORAGE),准备一个工具类PermissionUtils.java
package mlab.android.speedgame.utils;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import java.util.ArrayList;
import java.util.List;

import mlab.android.speedgame.R;
import mlab.android.speedgame.ui.CommonDialog;

//申请权限的工具类
public class PermissionUtils {
    private Activity mActivity;
    private int mReqCode;
    private CallBack mCallBack;

    //定义一个回调接口
    public static interface CallBack{
        //接受
        void grantAll(Activity mActivity);
        //拒绝
        void denied();
    }

    //定义一个构造函数
    public PermissionUtils(Activity activity) {
        this.mActivity = activity;
    }

    //定义请求权限的方法
    @RequiresApi(api = Build.VERSION_CODES.M)
    public void request(List<String> needPermissions, int reqCode, CallBack callBack){

        mReqCode=reqCode;
        mCallBack=callBack;

        //因为6.0之后才需要动态权限申请
        if (Build.VERSION.SDK_INT < 23){
            //6.0之前是默认获取全部权限
            callBack.grantAll(mActivity);
            return;
        }

        //判空,并抛出异常
        if (mActivity==null){
            throw  new IllegalArgumentException("activity is null.");
        }


        //将需要申请的权限,因为有些权限已经赋予
        List<String> reqPermission =new ArrayList<>();
        for (String permission:needPermissions){
            if (mActivity.checkSelfPermission(permission)!= PackageManager.PERMISSION_GRANTED){
                reqPermission.add(permission);
            }
        }

        //如果没有要授予的权限,则直接返回
        if (reqPermission.isEmpty()){
            callBack.grantAll(mActivity);
            return;
        }

        //真正开始申请
        mActivity.requestPermissions(reqPermission.toArray(new String[]{}),reqCode);

    }

    //处理权限返回的回调
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

        if (requestCode==mReqCode){
            boolean grantAll = true;
            String str = "";//定位,获取手机信息,读写手机存储,后台弹出界面,显示悬浮窗

            //遍历每一个授权结果
            for (int i = 0; i < grantResults.length; i++) {

                if (grantResults[i]!=PackageManager.PERMISSION_GRANTED){
                    grantAll=false;
                    if(("android.permission.ACCESS_COARSE_LOCATION".equals(permissions[i]) ||
                            "android.permission.ACCESS_FINE_LOCATION".equals(permissions[i])) &&
                            !str.contains(mActivity.getApplication().getString(R.string.Positioning_authority))){
                        str += mActivity.getApplication().getString(R.string.Positioning_authority) + " ";
                    }
                    if("android.permission.READ_PHONE_STATE".equals(permissions[i])){
                        str += mActivity.getApplication().getString(R.string.Access_to_mobile_phone_information) + " ";
                    }
                    if("android.permission.WRITE_EXTERNAL_STORAGE".equals(permissions[i])){
                        str += mActivity.getApplication().getString(R.string.Read_write_cell_phone_storage_permission) + " ";
                    }
                    if("android.permission.CAMERA".equals(permissions[i])){
                        str += mActivity.getApplication().getString(R.string.Camera_permission) + " ";
                    }
                }
                Log.d("xmmm",i + permissions[i]);
            }
            if(str != ""){
                CommonDialog dialog = new CommonDialog( mActivity);
                dialog.setMessage(str)
                        .setTitle(mActivity.getApplication().getString(R.string.following_permissions))
                        .setSingle(false).setOnClickBottomListener(new CommonDialog.OnClickBottomListener() {
                    @RequiresApi(api = Build.VERSION_CODES.M)
                    @Override
                    public void onPositiveClick() {
                        dialog.dismiss();
                        mActivity.requestPermissions(permissions,requestCode);
                    }

                    @Override
                    public void onNegtiveClick() {
                        dialog.dismiss();
                        // 若拒绝了所需的权限请求,则退出应用
                        mActivity.finish();
                        System.exit(0);
                    }
                }).show();
            }

            if (grantAll){
                mCallBack.grantAll(mActivity);
            }else {
                mCallBack.denied();
            }
        }
    }
}
  • 2,关于动态申请悬浮窗权限(SYSTEM_ALERT_WINDOW),准备一个工具类FloatTool.java
package mlab.android.speedgame.utils;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;

import androidx.annotation.RequiresApi;

import mlab.android.speedgame.R;
import mlab.android.speedgame.ui.CommonDialog;
/**
 * FloatTool.java:应用悬浮窗权限请求
 * AndroidMainifest.xml中添加: <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
 * 用法:
 * 1、请求悬浮窗权限:FloatTool.RequestOverlayPermission(this);
 * 2、处理悬浮窗权限请求结果:FloatTool.onActivityResult(requestCode, resultCode, data, this);
 */
public class FloatTool
{
    public static boolean CanShowFloat = false;

    private static final int REQUEST_OVERLAY = 5004;

    /** 动态请求悬浮窗权限 */
    public static void RequestOverlayPermission(Activity Instatnce)
    {
        if (Build.VERSION.SDK_INT >= 23)
        {
            if (!Settings.canDrawOverlays(Instatnce))
            {
                String ACTION_MANAGE_OVERLAY_PERMISSION = "android.settings.action.MANAGE_OVERLAY_PERMISSION";
                Intent intent = new Intent(ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + Instatnce.getPackageName()));

                Instatnce.startActivityForResult(intent, REQUEST_OVERLAY);
            }
            else
            {
                CanShowFloat = true;
            }
        }
    }

    /** 浮窗权限请求,Activity执行结果,回调函数 */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static void onActivityResult(int requestCode, int resultCode, Intent data, final Activity Instatnce)
    {
        // Toast.makeText(activity, "onActivityResult设置权限!", Toast.LENGTH_SHORT).show();
        if (requestCode == REQUEST_OVERLAY)		// 从应用权限设置界面返回
        {
            if(resultCode == Activity.RESULT_OK)
            {
                CanShowFloat = true;		// 设置标识为可显示悬浮窗
            }
            else
            {
                CanShowFloat = false;

                if (!Settings.canDrawOverlays(Instatnce))	// 若当前未允许显示悬浮窗,则提示授权
                {
                    CommonDialog dialog = new CommonDialog(Instatnce);
                    dialog.setMessage(Instatnce.getApplication().getString(R.string.Suspended_window))
                            .setTitle(Instatnce.getApplication().getString(R.string.Suspended_window_permission_not_authorized))
                            .setSingle(false).setOnClickBottomListener(new CommonDialog.OnClickBottomListener() {
                        @Override
                        public void onPositiveClick() {
                            dialog.dismiss();
                            FloatTool.RequestOverlayPermission(Instatnce);
                        }

                        @Override
                        public void onNegtiveClick() {
                            dialog.dismiss();
                            // 若拒绝了所需的权限请求,则退出应用
                            Instatnce.finish();
                            System.exit(0);
                        }
                    }).show();
                }
            }
        }
    }
}
  • 3,写一个Activity作为APP进入的首Activity进行权限申请SplashActivity
package mlab.android.speedgame;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;

import android.os.Bundle;
import android.provider.Settings;
import android.view.Window;
import android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;

import java.util.ArrayList;
import java.util.List;

import mlab.android.speedgame.ui.CommonDialog;
import mlab.android.speedgame.utils.FloatTool;
import mlab.android.speedgame.utils.PermissionUtils;

public class SplashActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback{

    private static List<String> sNeedPermissions=new ArrayList<>();

    private PermissionUtils permissionUtils= null;

    //静态块中初始化所需要的权限
    static {
        sNeedPermissions.add(Manifest.permission.ACCESS_COARSE_LOCATION);
        sNeedPermissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
        sNeedPermissions.add(Manifest.permission.ACCESS_NETWORK_STATE);
        sNeedPermissions.add(Manifest.permission.INTERNET);
        sNeedPermissions.add(Manifest.permission.READ_PHONE_STATE);
        sNeedPermissions.add(Manifest.permission.ACCESS_WIFI_STATE);
        sNeedPermissions.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        sNeedPermissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        sNeedPermissions.add(Manifest.permission.CAMERA);
        sNeedPermissions.add(Manifest.permission.CHANGE_WIFI_STATE);
        //sNeedPermissions.add(Manifest.permission.SYSTEM_ALERT_WINDOW);
        //sNeedPermissions.add(Manifest.permission.PACKAGE_USAGE_STATS);
        //sNeedPermissions.add(Manifest.permission.MODIFY_AUDIO_SETTINGS);
        //sNeedPermissions.add(Manifest.permission.BROADCAST_STICKY);
        //sNeedPermissions.add(Manifest.permission.CHANGE_WIFI_MULTICAST_STATE);
        //sNeedPermissions.add(Manifest.permission.GET_ACCOUNTS);
        //sNeedPermissions.add(Manifest.permission.REQUEST_INSTALL_PACKAGES);
        //sNeedPermissions.add(Manifest.permission.WRITE_SETTINGS);
        //sNeedPermissions.add(Manifest.permission.RECEIVE_BOOT_COMPLETED);
        //sNeedPermissions.add(Manifest.permission.WAKE_LOCK);
        //sNeedPermissions.add(Manifest.permission.KILL_BACKGROUND_PROCESSES);
        //sNeedPermissions.add(Manifest.permission.WRITE_SYNC_SETTINGS);
        //sNeedPermissions.add(Manifest.permission.WRITE_CONTACTS);
        //sNeedPermissions.add(Manifest.permission.CHANGE_CONFIGURATION);
        //sNeedPermissions.add(Manifest.permission.BATTERY_STATS);
        //sNeedPermissions.add(Manifest.permission.GET_PACKAGE_SIZE);
        //sNeedPermissions.add(Manifest.permission.BLUETOOTH);
        //sNeedPermissions.add(Manifest.permission.PACKAGE_USAGE_STATS);
        //sNeedPermissions.add(Manifest.permission.READ_CALL_LOG);




    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        /*set it to be no title*/
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        /*set it to be full screen*/
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.a_permission);
        //FloatTool.RequestOverlayPermission(this);
        permissionUtils=new PermissionUtils(this);

        permissionUtils.request(sNeedPermissions, 100, new PermissionUtils.CallBack() {
            @Override
            public void grantAll(Activity mActivity) {
                if(!Settings.canDrawOverlays(mActivity)){
                    CommonDialog dialog = new CommonDialog( mActivity);
                    dialog.setMessage(mActivity.getApplication().getString(R.string.Suspended_window))
                            .setTitle(mActivity.getApplication().getString(R.string.Suspended_window_permission_not_authorized))
                            .setSingle(false).setOnClickBottomListener(new CommonDialog.OnClickBottomListener() {
                        @Override
                        public void onPositiveClick() {
                            dialog.dismiss();
                            FloatTool.RequestOverlayPermission(mActivity);
                        }

                        @Override
                        public void onNegtiveClick() {
                            dialog.dismiss();
                            // 若拒绝了所需的权限请求,则退出应用
                            mActivity.finish();
                            System.exit(0);
                        }
                    }).show();
                }else{
                    toMainActivity();
                    finish();
                }
            }

            @Override
            public void denied() {
                fileList();
            }
        });
    }


    public void toMainActivity(){
        //进入主Activity
        startActivity(new Intent(SplashActivity.this,MainActivity.class));
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        permissionUtils.onRequestPermissionsResult(requestCode,permissions,grantResults);
    }

    /** Activity执行结果 */
    @RequiresApi(api = Build.VERSION_CODES.M)
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);
        FloatTool.onActivityResult(requestCode, resultCode, data, this);
        if(Settings.canDrawOverlays(this)){
            toMainActivity();
            finish();
        }
    }

}
  • 4,补1:动态申请安装未知来源应用权限(REQUEST_INSTALL_PACKAGES),在MainActivity.java的onCreate()方法中添加以下代码
//打开未知来源权限
        boolean haveInstallPermission;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //先获取是否有安装未知来源应用的权限
            haveInstallPermission = getPackageManager().canRequestPackageInstalls();
            if (!haveInstallPermission) {//没有权限
                CommonDialog dialog = new CommonDialog(this);
                dialog.setMessage(this.getApplication().getString(R.string.install_permission))
                        .setTitle(this.getApplication().getString(R.string.following_permissions))
                        .setSingle(true).setOnClickBottomListener(new CommonDialog.OnClickBottomListener() {
                    @RequiresApi(api = Build.VERSION_CODES.M)
                    @Override
                    public void onPositiveClick() {
                        dialog.dismiss();
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                            startInstallPermissionSettingActivity();
                        }
                    }

                    @Override
                    public void onNegtiveClick() {
                        dialog.dismiss();
                        // 若拒绝了所需的权限请求,则退出应用
                        //mActivity.finish();
                        System.exit(0);
                    }
                }).show();
            }
        }
  • 4,补2:在MainActivity.java中添加方法startInstallPermissionSettingActivity()
/**
     * 进入打开位置来源权限页面
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    private void startInstallPermissionSettingActivity() {
        Uri packageURI = Uri.parse("package:" + getPackageName());
        //注意这个是8.0新API
        Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);
        startActivityForResult(intent, 10086);
    }
  • 5,部分String.xml 中文包资源
 <string name="To_add_permissions">去添加 权限</string>
    <string name="Reject_and_Exit">拒绝则 退出</string>
    <string name="Suspended_window_permission_not_authorized">两项权限未授权</string>
    <string name="Suspended_window">请打开后台弹出界面权限与显示悬浮窗权限</string>
    <string name="following_permissions">应用需以下权限,请务必进行授权,否则应用将无法开启</string>
    <string name="Positioning_authority">定位权限</string>
    <string name="Camera_permission">照相机权限</string>
    <string name="Access_to_mobile_phone_information">获取手机信息权限</string>
    <string name="Read_write_cell_phone_storage_permission">读写手机存储权限</string>
    <string name="install_permission">安装应用需要打开未知来源权限,请去设置中开启权限</string>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Android 10 及以上的版本中,权限申请弹框的样式已经由系统进行了重构,并且提供了更多的自定义选项。如果您想要自定义权限申请弹框的样式,可以使用 `PermissionControllerCompat` 类中的 `createPermissionDialog()` 方法来创建一个自定义的弹框。具体的代码可以参考以下示例: ```java AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(title); builder.setMessage(message); builder.setPositiveButton(android.R.string.ok, listener); builder.setNegativeButton(android.R.string.cancel, null); AlertDialog dialog = builder.create(); Window window = dialog.getWindow(); window.setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY); window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN); int width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 300, context.getResources().getDisplayMetrics()); int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 200, context.getResources().getDisplayMetrics()); window.setLayout(width, height); return dialog; ``` 在上述代码中,`context` 参数表示上下文;`title` 和 `message` 分别表示弹框的标题和内容;`listener` 表示点击确定按钮后的回调函数。弹框的样式可以通过设置 `AlertDialog.Builder` 对象来实现,包括标题、内容、按钮等。在最后,调用 `create()` 方法创建 `AlertDialog` 对象,并设置其大小和位置。 需要注意的是,为了在 Android 10 及以上的版本中能够显示弹框,需要将窗口类型设置为 `TYPE_APPLICATION_OVERLAY`,并添加相关的标志位。此外,需要在 AndroidManifest.xml 文件中添加 `android.permission.SYSTEM_ALERT_WINDOW` 权限
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Timothy Cui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值