android 6.0 权限设置详解

从Android 6.0版本开始,在安装应用时,该应用无法取得任何权限。 相反,在使用应用的过程中,若某个功能需要获取某个权限,系统会弹出一个对话框,显式地由用户决定是否将该权限赋予应用。 只有得到了用户的许可,该功能才可以被使用。

新的权限机制更好的保护了用户的隐私,Google将权限分为两类,一类是Normal Permissions,这类权限一般不涉及用户隐私,是不需要用户进行授权的,比如手机震动、访问网络等;另一类是Dangerous Permission,一般是涉及到用户隐私的,需要用户进行授权,比如读取sdcard、访问通讯录等。

1、Normal级别的权限只需要在AndroidManifest中声明就好,安装时就授权,不需要每次使用时都检查权限,而且用户不能取消以上授权

2、其他级别的权限在编译在Android M(即targetSdkVersion大于等于23时候)版本时候,不仅需要在AndroidManifest中声明,还得在运行的时候需要动态申请,而且还可以随时取消授权。

  • 先在AndroidManifest中声明
  • 再在运行的时候动态申请
  •  

权限流程

  在API 23中,权限满足的标准流程:

 

但这里有个问题,那就是在系统授权弹窗环节,提醒框会有个不再提示的复选框,如果用户点击不太提示,并拒绝授权,那么再下次授权的时候,系统授权弹窗的提示框就不会在提示,所以我们很有必要需要自定义权限弹窗提示框,那么流程图就变成如下了。

 

我们来看具体的代码:

第一步检查权限是否可用:

动态权限的核心工作流程:checkSelfPermission检查是否已被授予——>requestPermissions申请权限——>自动回调onRequestPermissionsResult——shouldShowRequestPermissionRationale。无论什么框架变出花来都离不开这个基本的流程。

我们来看代码:

复制代码

/***
     * 
     * 检查访问外置sdk的权限是否可以
     * */

    public void checkstatus(){
        if (Build.VERSION.SDK_INT >= 23) {
            //我是在Fragment里写代码的,因此调用getActivity
            //如果不想判断SDK,可以使用ActivityCompat的接口来检查和申请权限
            int hasReadContactsPermission = checkSelfPermission(
                    Manifest.permission.WRITE_EXTERNAL_STORAGE);

            if (hasReadContactsPermission != PackageManager.PERMISSION_GRANTED) {
                

                //这里就会弹出系统权限对话框
              requestPermissions( new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        ASK_READ_CONTACTS_PERMISSION);

                return;
            }
        } else {
           //权限可用
        }
    }

复制代码

 

此时,点击按键调用Activity的requestPermissions时,将会弹出对话框,类似于下图所示(不同设备商有不同的定制): 

 

 

无论选择的是“允许”还是“拒绝”,系统都将回调Activity.onRequestPermissionsResult()方法, 
并将选择的结果传到方法的第三个参数中。

此时的处理代码示例如下:

private static final int ASK_READ_CONTACTS_PERMISSION = 100;

复制代码

/**
     *
     * 当用户操作了权限的按钮的时候会调用该函数
     * */
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case ASK_READ_CONTACTS_PERMISSION:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //用户点击了运行权限

                } else {
                    //用户拒绝了权限
                    Toast.makeText(this,
                            "READ_CONTACTS Denied",
                            Toast.LENGTH_SHORT)
                            .show();
                    //跳转到权限的设置界面,提示用户开启权限的设置
                    goToAppSettings();

                }
                return;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

复制代码

这里如果用户选择了拒绝权限这里跳转到设置页面提示用户开启权限。

这里有一个很关键的地方,弹出系统权限对话框的时候,有有一个不再提示权限对话框的勾,当用户如果勾选了,在第二次调用requestPermissions申请权限的时候,是不会在弹出系统系统权限的对话框的,

如上图所示,每当系统申请权限时,弹出的对话框会有一个类似于“拒绝后不再询问”的勾选项。 
若用户打了勾,并选择拒绝,那么下次程序调用Activity.requestPermissions()方法时,将不会弹出对话框,权限也不会被赋予

所以要实现下面的功能,第一次启动app的时候,如果用户勾选了不再提示,禁止了开启权限,在第二次进行app的时候,我们也应该提示用户权限被禁止,如何实现了

此时应调用Activity.shouldShowRequestPermissionRationale()方法,示例代码如下:

复制代码

/***
     *
     * 检查访问外置sdk的权限是否可以
     * */

    public void checkstatus(){
        if (Build.VERSION.SDK_INT >= 23) {
            //我是在Fragment里写代码的,因此调用getActivity
            //如果不想判断SDK,可以使用ActivityCompat的接口来检查和申请权限
            int hasReadContactsPermission = checkSelfPermission(
                    Manifest.permission.WRITE_EXTERNAL_STORAGE);

            if (hasReadContactsPermission != PackageManager.PERMISSION_GRANTED) {
                //判断是否点击过“拒绝并不再提示”,若点击了,则应用自己弹出一个Dialog
                if (!shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                    showMessageOKCancel("You need to allow access to Contacts",  new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    //这里就会弹出对话框
                                    if (Build.VERSION.SDK_INT >= 23){
                                        Log.d("123456","on2222222");
                                        requestPermissions( new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
                                                ASK_READ_CONTACTS_PERMISSION);
                                    }

                                }
                            });
                    return;
                }

                //这里就会弹出对话框
              requestPermissions( new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        ASK_READ_CONTACTS_PERMISSION);

                return;
            }

            //高版本中检查是否有运行时权限,具有权限时才调用
            //getPhoneNumberAndDial();
        } else {
            //在AndroidManifest.xml中仍然声明使用"android.permission.READ_CONTACTS"
            //在低版本中直接调用该函数
            //getPhoneNumberAndDial();
        }
    }

复制代码

此时,应用第一次申请权限及用户勾选了“不再询问”复选框时,均会弹出类似如下的对话框: 

 

1、若第一次申请时点击OK,将会弹出权限申请的界面;

2、第二次进入app,用户勾选过“拒绝后不再询问时”,点击OK不会再次拉起申请界面,但是会调用requestPermissions函数,回调同时onRequestPermissionsResult中收到的结果为PackageManager.PERMISSION_DENIED,此时提醒用户到设置界面去开启权限

复制代码

private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
        new AlertDialog.Builder(this)
                .setMessage(message)
                .setPositiveButton("OK", okListener)
                .setNegativeButton("Cancel", null)
                .create()
                .show();
    }

复制代码

 

跳转至应用设置页

复制代码

/**
     * 应用设置页
     */
    private void goToAppSettings() {
        Intent myAppSettings = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName()));
        myAppSettings.addCategory(Intent.CATEGORY_DEFAULT);
//        myAppSettings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivityForResult(myAppSettings, 5);
    }

复制代码

5.  用户在应用设置页设置完权限后回到应用,判断是否已获得权限

复制代码

private String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == 5){
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
                //检查该权限是否已经获取
                int i = ContextCompat.checkSelfPermission(this, permissions[0]);
                // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝
                if (i != PackageManager.PERMISSION_GRANTED) {
                    goToAppSettings();
                }else {
                    Toast.makeText(this, "权限获取成功", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }

复制代码

相当的经典。

我们来看整个activity的代码:

复制代码

package application.weiyuan.com.download_demo;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.opengl.Visibility;
import android.os.Build;
import android.os.Parcelable;
import android.os.SystemClock;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RemoteViews;
import android.widget.TextView;
import android.widget.Toast;

import com.download.bean.FileInfo;
import com.download.com.download.utils.DownLoadApplication;
import com.download.com.download.utils.runtimepermissions.PermissionsManager;
import com.download.com.download.utils.runtimepermissions.PermissionsResultAction;
import com.download.constants.Constant;
import com.download.services.DownLoadService;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import static com.download.com.download.utils.DownLoadApplication.context;

public class MainActivity extends Activity  {

    private static final String TAG = Constant.TAG + " MainActivity";
    private static final int ASK_READ_CONTACTS_PERMISSION = 100;
    private TextView mTvFileName;
    private ProgressBar mPbDownLoad;
    private Button mBtnStart;
    private Button mBtnStop;
    private ListView mLv_show;
    DownLoadAdapter adapter = null;
    Notification notification;
    private Button btn_main_update;
    private NotificationManager mNotificationManager = null;

/*private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i(TAG, "onReceive: " );
            if(intent.getAction().equals(Constant.UPDATE_PROGRESSBAR)){
                int progress = intent.getIntExtra("finished",0);
                int id = intent.getIntExtra("file_id",0);
                adapter.updateProgress(id,progress);
                //更新通知栏的进度
                notification.contentView.setTextViewText(R.id.tv_notification_progress,""+progress+"%");
                notification.contentView.setProgressBar(R.id.pb_notification_download, 100, progress, false);
                mNotificationManager.notify(id, notification);
                Log.i(TAG, "onReceive: finished:" + progress);

            }
            if(intent.getAction().equals(Constant.Finished_PROGRESSBAR)){
                 FileInfo fileInfo = intent.getParcelableExtra("fileInfo");
                adapter.updateProgress(fileInfo.getFileId(),0);
                Toast.makeText(MainActivity.this, fileInfo.getFileName()+"文件下载完成", Toast.LENGTH_SHORT).show();
                //更新通知栏显示文件已经下载成功
                notification.contentView.setTextViewText(R.id.tv_notification_progress,"密码卡管家下载完成,点击安装");
                notification.contentView.setViewVisibility(R.id.pb_notification_download, View.GONE);
                notification.contentView.setViewVisibility(R.id.tv_notification_name, View.GONE);
                //点击安装目录
                File apkFile = new File(Constant.DOWNLOAD_FILE_PATH+File.separator+fileInfo.getFileName());
                if (!apkFile.exists()) {
                    return;
                }
                Intent i = new Intent(Intent.ACTION_VIEW);
                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                i.setDataAndType(Uri.parse("file://" + apkFile.toString()), "application/vnd.android.package-archive");
                PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 0, i, PendingIntent.FLAG_ONE_SHOT);
                notification.contentIntent = pendingIntent;
                mNotificationManager.notify(fileInfo.getFileId(), notification);
               // notification.contentView.setProgressBar(R.id.pb_notification_download, 100, progress, false);
                installApk(fileInfo);

            }
            if(intent.getAction().equalsIgnoreCase(Constant.NOTIFICATION_DOWNLOAD_START)){
                // 下载开始的时候启动通知栏
                Parcelable parcelable= intent.getParcelableExtra("fileInfo");
                FileInfo fileInfo = (FileInfo)parcelable;
                 notification = new Notification();
                notification.when = System.currentTimeMillis();
                notification.icon = R.mipmap.ic_launcher;
                notification.flags = Notification.FLAG_AUTO_CANCEL;
               *//* Intent i = new Intent(MainActivity.this, MainActivity.class);
                PendingIntent pd = PendingIntent.getActivity(i, 0, intent, PendingIntent.FLAG_NO_CREATE);
                notification.contentIntent = pd;*//*
                Intent  i= new Intent(MainActivity.this, MainActivity.class);
                PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
                notification.contentIntent = pendingIntent;

                // 设置远程试图RemoteViews对象
                RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.notification_2);
                remoteViews.setTextViewText(R.id.tv_notification_name, "密码卡管家正在下载中...");
                // 设置Notification的视图
                notification.contentView = remoteViews;
                // 发出Notification通知
                mNotificationManager.notify(fileInfo.getFileId(), notification);


            }
        }
    };*/
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        //requestPermissions();
        checkstatus();
        Log.d("123456","oncreat is called");
        mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
      /*  IntentFilter filter = new IntentFilter();
        filter.addAction(Constant.UPDATE_PROGRESSBAR);
        filter.addAction(Constant.Finished_PROGRESSBAR);
        filter.addAction(Constant.NOTIFICATION_DOWNLOAD_START);
        registerReceiver(broadcastReceiver, filter);*/


         btn_main_update = (Button) findViewById(R.id.btn_main_update);
        btn_main_update.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View v) {
               /* final VersionDialogFragment dialogFragment = VersionDialogFragment.getInstance("2.0.1新版本发布啦", "更多功能等你体验,jsjjjkds" +
                        "sfdkkfskdkfd" +
                        "kskkkl" +
                        "sfkk,dfk" +
                        "sfdk,df","大小:5.06M","详情:1.7.0.1","12122");
                dialogFragment.show(getFragmentManager());*/

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            final UpdateInfo updateInfo = new UpdateService().getUpdateInfo("http://10.12.7.21:8080/UpdateApk/UpdateServlet");
                            PackageManager manager = MainActivity.this.getPackageManager();
                            PackageInfo info = manager.getPackageInfo(MainActivity.this.getPackageName(), 0);
                            final int version = info.versionCode;
                            //判断是否是强制升级
                            if(Integer.parseInt(updateInfo.getServerSupportMinVer())>version){//说明是强制升级
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        final VersionDialogFragment dialogFragment = VersionDialogFragment.getInstance(
                                                updateInfo.getVersionName()+"新版本发布啦",
                                                updateInfo.getUpgradeDetailInfo(),
                                                "大小:"+updateInfo.getFileSize(),
                                                "详情:"+updateInfo.getServerVersion(),
                                                updateInfo.getImageURL(),
                                                updateInfo.getDownload_url());
                                        dialogFragment.show(getFragmentManager(),true);
                                    }
                                });

                            }else{ //判断是否是普通升级
                                if(Integer.parseInt(updateInfo.getVersionCode())> version){
                                    //说明服务器版本是最大的
                                    runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            //判断是否是强制升级
                                            final VersionDialogFragment dialogFragment = VersionDialogFragment.getInstance(
                                                    updateInfo.getVersionName()+"新版本发布啦",
                                                    updateInfo.getUpgradeDetailInfo(),
                                                    "大小:"+updateInfo.getFileSize(),
                                                    "详情:"+updateInfo.getServerVersion(),
                                                    updateInfo.getImageURL(),
                                                    updateInfo.getDownload_url());
                                            dialogFragment.show(getFragmentManager(),false);
                                        }
                                    });
                                }else{
                                    //说明服务器版本是最大的
                                    runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            Toast.makeText(MainActivity.this,"您所使用的已是最新的版本",Toast.LENGTH_LONG).show();
                                        }
                                    });
                                }
                            }


                        } catch (final Exception e) {
                            MainActivity.this.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(MainActivity.this,"获得升级信息失败"+e.toString(),Toast.LENGTH_LONG).show();
                                }
                            });
                        }
                    }
                }).start();
            }
        });




    }

    private void initView() {
      /*  mTvFileName = (TextView)findViewById(R.id.tv_fileName);
        mPbDownLoad = (ProgressBar)findViewById(R.id.pb_download);
        mBtnStart = (Button)findViewById(R.id.btn_start);
        mBtnStop = (Button)findViewById(R.id.btn_stop);
        mPbDownLoad.setMax(100);*/
        List<FileInfo>fileInfos = new ArrayList<>();
        FileInfo fileInfo = new FileInfo(0, "http://ecm.sec-apps.com/download/ecm-professional/EncryptCardManager.apk",
                "EncryptCardManager.apk", 0, 0);
        fileInfos.add(fileInfo);
        mLv_show = (ListView)findViewById(R.id.lv_show);
       adapter = new DownLoadAdapter(fileInfos,MainActivity.this);
        mLv_show.setAdapter(adapter);


    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            "android.permission.READ_EXTERNAL_STORAGE",
            "android.permission.WRITE_EXTERNAL_STORAGE" };


    public static void verifyStoragePermissions(Activity activity) {

        try {
            //检测是否有写的权限
            int permission = ActivityCompat.checkSelfPermission(activity,
                    "android.permission.WRITE_EXTERNAL_STORAGE");
            if (permission != PackageManager.PERMISSION_GRANTED) {
                // 没有写的权限,去申请写的权限,会弹出对话框
                ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE,REQUEST_EXTERNAL_STORAGE);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 下载完成点击安装apk
     * */
    private void installApk(FileInfo fileInfo) {
        File apkFile = new File(Constant.DOWNLOAD_FILE_PATH+File.separator+fileInfo.getFileName());
        if (!apkFile.exists()) {
            return;
        }
        Intent i = new Intent(Intent.ACTION_VIEW);
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.setDataAndType(Uri.parse("file://" + apkFile.toString()), "application/vnd.android.package-archive");
        DownLoadApplication.getGlobalContext().startActivity(i);
    }

    /**
     * android 6.0以上检查下载所需的网络和sd卡的访问权限
     * 当
     * */
    private  void  requestPermissions(){
        PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(this, PERMISSIONS_STORAGE, new PermissionsResultAction() {
            @Override
            public void onGranted() {
                Log.d("123456","1110");
            }

            @Override
            public void onDenied(String permission) {
                Log.d("123456","on");
            }
        });


    }


    /***
     *
     * 检查访问外置sdk的权限是否可以
     * */

    public void checkstatus(){
        if (Build.VERSION.SDK_INT >= 23) {
            //我是在Fragment里写代码的,因此调用getActivity
            //如果不想判断SDK,可以使用ActivityCompat的接口来检查和申请权限
            int hasReadContactsPermission = checkSelfPermission(
                    Manifest.permission.WRITE_EXTERNAL_STORAGE);

            if (hasReadContactsPermission != PackageManager.PERMISSION_GRANTED) {
                //判断是否点击过“拒绝并不再提示”,若点击了,则应用自己弹出一个Dialog
                if (!shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                    showMessageOKCancel("You need to allow access to Contacts",  new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    //这里就会弹出对话框
                                    if (Build.VERSION.SDK_INT >= 23){
                                        Log.d("123456","on2222222");
                                        requestPermissions( new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
                                                ASK_READ_CONTACTS_PERMISSION);
                                    }

                                }
                            });
                    return;
                }

                //这里就会弹出对话框
              requestPermissions( new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        ASK_READ_CONTACTS_PERMISSION);

                return;
            }

            //高版本中检查是否有运行时权限,具有权限时才调用
            //getPhoneNumberAndDial();
        } else {
            //在AndroidManifest.xml中仍然声明使用"android.permission.READ_CONTACTS"
            //在低版本中直接调用该函数
            //getPhoneNumberAndDial();
        }
    }
    /**
     *
     * 当用户操作了权限的按钮的时候会调用该函数
     * */
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case ASK_READ_CONTACTS_PERMISSION:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //用户点击了运行权限

                } else {
                    //用户拒绝了权限
                    Toast.makeText(this,
                            "READ_CONTACTS Denied",
                            Toast.LENGTH_SHORT)
                            .show();
                    //跳转到权限的设置界面,提示用户开启权限的设置
                    goToAppSettings();

                }
                return;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }


    private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
        new AlertDialog.Builder(this)
                .setMessage(message)
                .setPositiveButton("OK", okListener)
                .setNegativeButton("Cancel", null)
                .create()
                .show();
    }


    /**
     * 应用设置页
     */
    private void goToAppSettings() {
        Intent myAppSettings = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName()));
        myAppSettings.addCategory(Intent.CATEGORY_DEFAULT);
//        myAppSettings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivityForResult(myAppSettings, 5);
    }
    private String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == 5){
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
                //检查该权限是否已经获取
                int i = ContextCompat.checkSelfPermission(this, permissions[0]);
                // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝
                if (i != PackageManager.PERMISSION_GRANTED) {
                    goToAppSettings();
                }else {
                    Toast.makeText(this, "权限获取成功", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
}

转载于:https://my.oschina.net/u/1177694/blog/907922

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Anroid6.0权限问题 apk22之后Android把一些涉及用户个人信息的权限都做了默认没有权限处理,需要用户确认才可以: 用户不需要在安装软件的时候一次性授权所有申请的权限,而是可以在软件的使用过程中再对某一项权限申请进行授权。举例说明:一款相机应用在运行时申请了地理位置定位权限,就算我拒绝了这个权限,我仍然可以使用这款应用的其他功能,不用像6.0之前无法安装它。 解决办法: ● 投机取巧 如果我们不想使用6.0或者7.0的新特性,那么我们把targetSdkVersion设置22,就可以很好的避开动态配置运行时权限。而targetSdkVersion设置为22,并不影响其在Android 6.0或7.机制上使用,因为高版本兼容低版本。 解决办法:(简单到没朋友) AndroidAcp ● Acp 为 Android check permission 缩写,此库简化Android 6.0 系统复杂的权限操作而编写。 特点 ● 支持批量权限申请,不需要重写 onRequestPermissionsResult 方法,Activity 与 Fragment 中用法一致,一句话搞定。 ● 处理权限拒绝,或勾选不再询问,导致不能正常使用功能的提示框,支持跳转设置权限界面开启权限,所有提示框文字可自定义。 ● #使用Gradle构建时添加一下依赖即可: compile 'com.mylhyl:acp:1.1.7' 怎麽用? Acp.getInstance(this).request(new AcpOptions.Builder() .setPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE , Manifest.permission.READ_PHONE_STATE , Manifest.permission.SEND_SMS) /*以下为自定义提示语、按钮文字 .setDeniedMessage() .setDeniedCloseBtn() .setDeniedSettingBtn() .setRationalMessage() .setRationalBtn()*/ .build(), new AcpListener() { @Override public void onGranted() { writeSD(); getIMEI(); } @Override public void onDenied(List permissions) { makeText(permissions.toString() + "权限拒绝"); } }); ***************************** 二維碼的使用: ZXING ● 可打开默认二维码扫描页面 ● 支持对图片Bitmap的扫描功能 ● 支持对UI的定制化操作 ● 支持对条形码的扫描功能 ● 支持生成二维码操作 ● 支持控制闪光灯开关 ● 集成默认的二维码扫描页面 在具体介绍该扫描库之前我们先看一下其具体的使用方式,看看是不是几行代码就可以集成二维码扫描的功能。 ● 在module的build.gradle中执行compile操作 compile 'cn.yipianfengye.android:zxing-library:2.1' ● 1 ● 1 ● 在Application中执行初始化操作 @Override public void onCreate() { super.onCreate(); ZXingLibrary.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值