Cumplimiento de Android Obtención de permisos de dispositivos

1. Información general

Probablemente el año pasado, recibí un informe de los departamentos relevantes que decían que la aplicación muestra con frecuencia cuadros emergentes de solicitud de permiso. Al principio no entendía bien las frecuentes ventanas emergentes, pero luego, después de mirar algunas aplicaciones de renombre, agregaron procesamiento para solicitar permisos del dispositivo. Probablemente se vea así, como los permisos de almacenamiento de lectura del dispositivo,

El primero es así antes del procesamiento. Cuando use permisos de almacenamiento, se abrirá un cuadro emergente de permiso. Cuando haga clic para denegar el uso, aparecerá un cuadro emergente para abrir permisos cuando vuelva a usar los permisos de almacenamiento. El primer enfoque ya sería incompatible con el cumplimiento de la seguridad.

El segundo método es que cuando use el permiso de almacenamiento, aparecerá un cuadro emergente para abrir el permiso. Cuando haga clic en Denegar, aparecerá otro cuadro emergente cuando use el permiso de almacenamiento nuevamente, lo que le permitirá vaya al sistema para abrir el permiso de la aplicación. Además, al solicitar el permiso, se agregará un cuadro emergente de descripción del permiso. El segundo enfoque es coherente con el cumplimiento de la seguridad. Como se muestra en la siguiente imagen (red de origen de la imagen, infracción y eliminación)

2. Date cuenta 

1. Implementar ideas

 2.Código

1. Clase de herramienta y devolución de llamada

 import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.provider.Settings;
import androidx.core.content.ContextCompat;
import com.tbruyelle.rxpermissions2.RxPermissions;
import com.wangyi.Utils.ChatConstant;
import com.widget.ConfimDialog;
import com.widget.PermissionsDescriptionDialog;
import java.util.ArrayList;
import java.util.List;
 
public class PermissionsUtlis {
    /**
     * 判断是否缺少权限,利用SP存储记录
     */
    public static boolean lacksPermissionNew(Context mContext, String permission) {
        
        if (SpUtil.getBoolean(mContext, ChatConstant.APP_WRITE_EXTERNAL, true)) {
            PermissionsDescriptionDialog.getInstance()
                    .setTitle("存储权限使用说明")
                    .setContent("XX正在申请读取您的存储权限,缓存并同步本地内容,同时保障服务流畅。拒绝或取消不影响您使用XX其他服务。")
                    .show(mContext);
            SpUtil.putBoolean(mContext, ChatConstant.APP_WRITE_EXTERNAL, false);
            return true;
        }
        return !(ContextCompat.checkSelfPermission(mContext, permission) ==
                PackageManager.PERMISSION_DENIED);
    }

    public static void cunChuPermissisons(Context context, String permission, PermissisonsListener permissisonsListener) {
        if (lacksPermissionNew(context, permission)) {
            RxPermissions rxPermissions = new RxPermissions((Activity) context);
            rxPermissions.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    .subscribe(aBoolean -> {
                        PermissionsDescriptionDialog.getInstance().hide();
                        if (aBoolean) {
                            permissisonsListener.Permissisons(true);
                        } else {
                            PermissionsUtlis.cunChuPermissisons(context);
                        }

                    });
        } else {
            PermissionsUtlis.cunChuPermissisons(context);
        }


    }

    public static void cunChuPermissisons(Context context) {
        ConfimDialog.getInstance().setTitle("XX需要申请存储权限")
                .setContent("XX正在申请读取您的存储权限同时保障服务流畅。拒绝或取消不影响您使用XX其他服务。")
                .setTvCancel("取消")
                .setTvConfim("去设置")
                .setOperateListener(new ConfimDialog.OnOperateListener() {
                    @Override
                    public void onSure() {
                        //引导用户至设置页手动授权
                        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                        Uri uri = Uri.fromParts("package", "com.包名", null);
                        intent.setData(uri);
                        context.startActivity(intent);

                    }

                    @Override
                    public void onCancel() {

                    }
                }).show(context);
    }
 
     
}
 
 
public interface PermissisonsListener {
    void Permissisons(boolean flag);
}

2. Marco y diseño emergente

package com.widget;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;

 


public class PermissionsDescriptionDialog {
    private static PermissionsDescriptionDialog minstance;
    public static Dialog dialog;
    private static Handler handler = new Handler(Looper.getMainLooper());
    private String content = "";
    private boolean flag;
    private String title;

    private OnOperateListener operateListener;

    public static PermissionsDescriptionDialog getInstance() {
        minstance = new PermissionsDescriptionDialog();
        return minstance;
    }

    public void show(final Context context) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (dialog != null && dialog.isShowing()) {
                    dialog.dismiss();
                }
                dialog = new Dialog(context, R.style.MyDialogStyle);

                View view = View.inflate(context, R.layout.alert_permissons_dialog, null);
                dialog.setContentView(view);
                initView(view);
                dialog.setCancelable(false);
                Window window = dialog.getWindow(); //得到对话框
                // window.setWindowAnimations(R.style.dialogWindowAnim); //设置窗口弹出动画
                WindowManager.LayoutParams lp = window.getAttributes();
                if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {//横屏
                    lp.width = getScreenHeight(context) / 20 * 17;
                } else {
                    lp.width = getScreenWidth(context) / 20 * 17;
                }
                window.setGravity(Gravity.TOP);
                window.setAttributes(lp);
                dialog.show();
            }
        });
    }

    private void initView(View view) {
        TextView tvTvitle = view.findViewById(R.id.tv_tvitle);
        if (!TextUtils.isEmpty(title)) {
            tvTvitle.setText(title);
            tvTvitle.setVisibility(View.VISIBLE);
        } else {
            tvTvitle.setVisibility(View.GONE);
        }
        TextView tvContent = (TextView) view.findViewById(R.id.tv_content);
        tvContent.setText(content);
    }

    public void hide() {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (null == dialog)
                    return;
                if (dialog != null && dialog.isShowing()) {
                    dialog.dismiss();
                    dialog = null;
                }
            }
        });
    }

    public void hideDelayed(long delayMillis) {
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (null == dialog)
                    return;
                if (dialog != null && dialog.isShowing()) {
                    dialog.dismiss();
                    dialog = null;
                }
            }
        }, delayMillis);
    }



    public PermissionsDescriptionDialog setContent(String content) {
        this.content = content;
        return minstance;
    }
    public PermissionsDescriptionDialog setTitle(String title) {
        this.title = title;

        return minstance;
    }
    public PermissionsDescriptionDialog setContent(String content, boolean flag) {
        this.content = content;
        this.flag = flag;
        return minstance;
    }





    public PermissionsDescriptionDialog setOperateListener(OnOperateListener operateListener) {
        this.operateListener = operateListener;
        return minstance;
    }

    public interface OnOperateListener {
        void onSure();

        void onCancel();
    }

    /**
     * 获取屏幕分辨率宽
     */
    public static int getScreenWidth(Context context) {
        DisplayMetrics dm = new DisplayMetrics();
        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm);
        Log.i("widthPixels", dm.widthPixels + "");
        return dm.widthPixels;

    }

    /**
     * 获取屏幕分辨率高
     */
    public static int getScreenHeight(Context context) {
        DisplayMetrics dm = new DisplayMetrics();
        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(dm);
        return dm.heightPixels;
    }

}

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/popub_delete" android:paddingTop="30dp" android:paddingBottom="30dp">
<TextView android:id="@+id/tv_tvitle" android:layout_width="match_parent" android:gravity="left" android:layout_height="wrap_content" android:textSize="16sp" android:layout_marginLeft="20dp" android:textStyle="bold" android:textColor="#212832" tools:text="存储权限使用说明"/>
<TextView android:id="@+id/tv_content" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="@+id/tv_tvitle" android:layout_marginLeft="20dp" android:layout_marginTop="@dimen/px20" android:layout_marginRight="20dp" android:text="权限说明。。。。。。。。。。。" android:textColor="#333333" android:textSize="@dimen/font32"/>
</RelativeLayout>
<stylename="MyDialogStyle">
<itemname="android:windowBackground">@android:color/transparent</item>
<itemname="android:windowFrame">@null</item>
<itemname="android:windowNoTitle">true</item>
<itemname="android:windowIsFloating">true</item>
<itemname="android:windowIsTranslucent">true</item>
<itemname="android:windowContentOverlay">@null</item>
<item
name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<itemname="android:backgroundDimEnabled">true</item>
</style>

3. Solicite ir al sistema para abrir la aplicación. La idea principal

 public static void cunChuPermissisons(Context context) {
        ConfimDialog.getInstance().setTitle("XX需要申请存储权限")
                .setContent("XX正在申请读取您的存储权限,,缓存并同步本地内容,同时保障服务流畅。拒绝或取消不影响您使用XX其他服务。")
                .setTvCancel("取消")
                .setTvConfim("去设置")
                .setOperateListener(new ConfimDialog.OnOperateListener() {
                    @Override
                    public void onSure() {
                        //引导用户至设置页手动授权,写好对应的包名
                        Intent intent = new 
                        Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                        Uri uri = Uri.fromParts("package", "com.包名", null);
                        intent.setData(uri);
                        context.startActivity(intent);

                    }

                    @Override
                    public void onCancel() {

                    }
                }).show(context);
    }

4. Llamada de función

 PermissionsUtlis.cunChuPermissisons(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE, new PermissisonsListener() {
                    @Override
                    public void Permissisons(boolean flag) {
                        if (flag) {
                            //TODO 实现你需要的逻辑
                        }

                    }
                });

5. Componentes de terceros utilizados

 Dirección de github de la biblioteca RxPermissions: https://github.com/tbruyelle/RxPermissions

Cada desarrollador espera brindar una mejor experiencia a los usuarios, siempre que se garantice la privacidad del usuario. En el futuro, también publicaremos algunas otras soluciones que regresan a problemas de seguridad, como vulnerabilidades y seguridad de la información y otros artículos relacionados. Algunos cuadros emergentes no están escritos en detalle y se pueden mejorar combinando su propio código.

Supongo que te gusta

Origin blog.csdn.net/u012941592/article/details/126832043
Recomendado
Clasificación