Android提示用户获取相应手机权限

Android 专栏收录该内容
9 篇文章 0 订阅

一,简介

Android 6.0 为了保护用户隐私,将一些权限的申请放在了应用运行的时候去申请, 比如以往的开发中,开发人员只需要将需要的权限在清单文件中配置即可,安装后用户可以在设置中的应用信息中看到:XX应用以获取****权限。用户点击可以选择给应用相应的权限。此前的应用权限用户可以选择允许、提醒和拒绝。在安装的时候用户是已经知道应用需要的权限的。但是这样存在一个问题,就是用户在安装的时候,应用需要的权限十分的多(有些开发者为了省事,会请求一些不必要的权限或者请求全部的权限),这个时候用户在安装应用的时候也许并没有发现某些侵犯自己隐私的权限请求,安装之后才发现自己的隐私数据被窃取。其实Android6.0 动态权限一方面是为了广大用户考虑,另一方面其实是Google为了避免一些不必要的官司。下面就说一下Android6.0对权限的分割:

二,一些权限知识

下面是对权限的总结:(此处内容摘抄自:http://blog.csdn.net/u011200604/article/details/52874599)


首先是大家感兴趣的危险权限

这类权限需要在需要的时候,需要我们动态申请,比如:当我们需要打开相机拍摄照片的时候需要我们通过代码的方式在需要的地方去申请权限。Android6.0中权限问题中我们需要注意的是:

1:由于权限API的问题,我们的Actiivty最好是AppCompatActivity类型的,也就是说在你的BaseActivity需要继承AppCompatActivity

2:权限是分组的,同一组的权限申请其中一个,同组的权限就全部都申请了

 

特殊权限 组:

CALENDAR 日历

CAMERA 相机

CONTACTS 联系人

LOCATION 定位

MICROPHONE 麦克相关,比如录音

PHONE 手机状态

SENSORS 传感器

SMS 短信

STORAGE 存储权限

 

具体的权限分组情况如下表:

以下是需要单独申请的权限,共分为9组,每组只要有一个权限申请成功了,就默认整组权限都可以使用了。  
group:android.permission-group.CONTACTS
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
 
group:android.permission-group.PHONE
permission:android.permission.READ_CALL_LOG
permission:android.permission.READ_PHONE_STATE
permission:android.permission.CALL_PHONE
permission:android.permission.WRITE_CALL_LOG
permission:android.permission.USE_SIP
permission:android.permission.PROCESS_OUTGOING_CALLS
permission:com.android.voicemail.permission.ADD_VOICEMAIL
 
group:android.permission-group.CALENDAR
permission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR
 
group:android.permission-group.CAMERA
permission:android.permission.CAMERA
 
group:android.permission-group.SENSORS
permission:android.permission.BODY_SENSORS
 
group:android.permission-group.LOCATION
permission:android.permission.ACCESS_FINE_LOCATION
permission:android.permission.ACCESS_COARSE_LOCATION
 
group:android.permission-group.STORAGE
permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE
 
group:android.permission-group.MICROPHONE
permission:android.permission.RECORD_AUDIO
 
group:android.permission-group.SMS
permission:android.permission.READ_SMS
permission:android.permission.RECEIVE_WAP_PUSH
permission:android.permission.RECEIVE_MMS
permission:android.permission.RECEIVE_SMS
permission:android.permission.SEND_SMS
permission:android.permission.READ_CELL_BROADCASTS


普通权限的总结:

ACCESS_LOCATION_EXTRA_COMMANDS	定位权限
 
ACCESS_NETWORK_STATE	网络状态权限
 
ACCESS_NOTIFICATION_POLICY	通知 APP通知显示在状态栏
 
ACCESS_WIFI_STATE	WiFi状态权限
 
BLUETOOTH	使用蓝牙权限
 
BLUETOOTH_ADMIN	控制蓝牙开关
 
BROADCAST_STICKY	粘性广播
 
CHANGE_NETWORK_STATE	改变网络状态
 
CHANGE_WIFI_MULTICAST_STATE	改变WiFi多播状态,应该是控制手机热点(猜测)
 
CHANGE_WIFI_STATE	控制WiFi开关,改变WiFi状态
 
DISABLE_KEYGUARD	改变键盘为不可用
 
EXPAND_STATUS_BAR	扩展bar的状态
 
GET_PACKAGE_SIZE	获取应用安装包大小
 
INTERNET	网络权限
 
KILL_BACKGROUND_PROCESSES	杀死后台进程
 
MODIFY_AUDIO_SETTINGS	改变音频输出设置
 
NFC	支付
 
READ_SYNC_SETTINGS	获取手机设置信息
 
READ_SYNC_STATS	数据统计
 
RECEIVE_BOOT_COMPLETED	监听启动广播
 
REORDER_TASKS	创建新栈
 
REQUEST_INSTALL_PACKAGES	安装应用程序
 
SET_TIME_ZONE	允许应用程序设置系统时间区域
 
SET_WALLPAPER	设置壁纸
 
SET_WALLPAPER_HINTS	设置壁纸上的提示信息,个性化语言
 
TRANSMIT_IR	红外发射
 
USE_FINGERPRINT	指纹识别
 
VIBRATE	震动
 
WAKE_LOCK	锁屏
 
WRITE_SYNC_SETTINGS	改变设置
 
SET_ALARM	设置警告提示
 
INSTALL_SHORTCUT	创建快捷方式
 
UNINSTALL_SHORTCUT	删除快捷方式
 
以上这些只是普通权限,我们开发的时候,正常使用就行了,需要的权限在清单文件配置即可

三,demo

1,效果,分两种情况,

第一种:点击允许



第二种:点击拒绝,并再次点击拒绝+不在询问

   


2,代码:

视图层:

permission.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:layout_marginTop="200dp"
        android:id="@+id/btn_get2"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:onClick="get"
        android:text="读取手机内存"/>

</LinearLayout>

权限:

   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

testPermission.java

public class testPermission extends Activity {


    private static final int REQUEST_EXTERNAL_STORAGE = 1;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.permission);

    }

    public void get(View v){

        String[] permissions;
       //读取内存权限
                permissions = new String[]{
                        Manifest.permission.READ_EXTERNAL_STORAGE
                };
                if (checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) {
                    //如果已经获得权限
                    String   dir= Environment.getExternalStorageDirectory().getAbsolutePath();
                    Intent intent=new Intent(testPermission.this,FileManager.class);
                    intent.putExtra("dir",dir);
                    intent.putExtra("title","文件管理");
                    startActivity(intent);

                    }else{
                    //否则去获取权限
                    getPermission(Manifest.permission.READ_EXTERNAL_STORAGE,permissions);
                }

    }


    //检查某个权限是否已经获得
    private boolean checkPermission(String permission){
        //检查权限(NEED_PERMISSION)是否被授权 PackageManager.PERMISSION_GRANTED表示同意授权
        if (ActivityCompat.checkSelfPermission(this, permission)
                == PackageManager.PERMISSION_GRANTED)
            return true;
        else
            return false;
    }

    //获取权限
    private void getPermission(String permission,String [] permissions) {

        //申请权限
        ActivityCompat.requestPermissions(
                this,
                permissions,
                REQUEST_EXTERNAL_STORAGE);

        //用户已经拒绝过一次,再次弹出权限申请对话框需要给用户一个解释
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission))
            Toast.makeText(this, "请开通相关权限,否则无法正常使用本应用!", Toast.LENGTH_SHORT).show();

    }



    /**
     * 一个或多个权限请求结果回调
     *
     * @param requestCode
     * @param permissions
     * @param grantResults
     *//当点击了不在询问,但是想要实现某个功能,必须要用到权限,可以提示用户,引导用户去设置
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        boolean hasAllGranted = true;
        for (int i = 0; i < grantResults.length; ++i) {
            if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                hasAllGranted = false;
                //在用户已经拒绝授权的情况下,如果shouldShowRequestPermissionRationale返回false则
                // 可以推断出用户选择了“不在提示”选项,在这种情况下需要引导用户至设置页手动授权
                if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) {
                    //解释原因,并且引导用户至设置页手动授权
                    new AlertDialog.Builder(this)
                            .setMessage("\r\n" +
                                    "获取相关权限失败:xxxxxx,将导致部分功能无法正常使用,需要到设置页面手动授权")
                            .setPositiveButton("去授权", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    //引导用户至设置页手动授权
                                    Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                    Uri uri = Uri.fromParts("package", getApplicationContext().getPackageName(), null);
                                    intent.setData(uri);
                                    startActivity(intent);
                                }
                            })
                            .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    //引导用户手动授权,权限请求失败
                                    Toast.makeText(testPermission.this,"权限获取失败",Toast.LENGTH_SHORT).show();
                                }
                            }).setOnCancelListener(new DialogInterface.OnCancelListener() {
                        @Override
                        public void onCancel(DialogInterface dialog) {
                            //引导用户手动授权,权限请求失败
                        }
                    }).show();

                } else {
                    //权限请求失败,但未选中“不再提示”选项
                }
                break;
            }
        }
        if (hasAllGranted) {

        }
    }

}

FileManager.java//当权限获取成功时,跳到此activity;

public class FileManager extends Activity {

    ListView listView;
    TextView title;
    String dir;
    //用存放路劲
    FileAdapter adapter;
    //适配器
    List<File> dateList;
    //File 数据
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.file_manager);

        findVById();
        init();
        //初始化
    }
    private void findVById() {
        listView=(ListView)findViewById(R.id.file_listview);
        title=(TextView)findViewById(R.id.file_title);
    }
    //初始化
    private void init() {

        Intent intent=getIntent();
        //获取Intent的,接收activity传来的值,

        dir= intent.getStringExtra("dir");
        //如果为null,dir的值为 :Environment.getExternalStorageDirectory().getAbsolutePath();
        //这个路劲就是一般打开手机文件管理文件目录的路劲
        if (dir!=null)
            ;
        else
            dir= Environment.getExternalStorageDirectory().getAbsolutePath();

        //获取title:让其显示文件路劲:如Android>data>com......
        if(intent.getStringExtra("title")!=null)
            title.setText(intent.getStringExtra("title"));
        else
            title.setText("文件管理");

        //为listView注册上下文菜单,当长按某一个文件出现菜单:
       this.registerForContextMenu(listView);

        dateList=new ArrayList<>();
        adapter=new FileAdapter(this,getDate());
        listView.setAdapter(adapter);

        //listView 点击事件,当点击的文件为目录时,
        // 把dir的值赋值为:dir+点击的目录,再次跳到此页,既可以达到循环,不要再去新建一个activity在现实:
        // intent.putExtra("dir",dir+"/"+dateList.get(i).getName());
        //intent.putExtra("title",title.getText()+">"+dateList.get(i).getName());

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                if(dateList.get(i).isDirectory())
                {
                    Intent intent=new Intent(FileManager.this,FileManager.class);
                    intent.putExtra("dir",dir+"/"+dateList.get(i).getName());
                    intent.putExtra("title",title.getText()+">"+dateList.get(i).getName());
                    startActivity(intent);
                }
            }
        });
    }



    //为上下文菜单添加菜单项
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.setHeaderTitle("文件操作");
        menu.setHeaderIcon(R.drawable.ic_brightness_high_black_24dp);
        menu.add(1,1,1,"复制");
        menu.add(1,2,1,"粘贴");
        menu.add(1,3,1,"剪切");
        menu.add(1,4,1,"重命名");

    }

    //选中菜单项点击事件,这里就Toast一下,
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case 1:
                Toast.makeText(FileManager.this,"已复制",Toast.LENGTH_SHORT).show();
                break;
            case 2:
                Toast.makeText(FileManager.this,"已粘贴",Toast.LENGTH_SHORT).show();
                break;
            case 3:
                Toast.makeText(FileManager.this,"剪切",Toast.LENGTH_SHORT).show();
                break;
            case 4:
                Toast.makeText(FileManager.this,"重命名",Toast.LENGTH_SHORT).show();
                break;
        }
        return super.onContextItemSelected(item);
    }

    //获取dir下所有的文件
    public List< File> getDate() {

        File file=new File(dir);
        if(file.exists())
        {
            File[] file1=file.listFiles();
            for (File filename :
                    file1) {
                dateList.add(filename);
            }
        }

        return dateList;
    }


    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };
    public void myPermission() {
        int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (permission != PackageManager.PERMISSION_GRANTED) {
            // 没有权限就提示用户
            ActivityCompat.requestPermissions(
                    this,
                    PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE
            );
        }
    }
}



  • 7
    点赞
  • 1
    评论
  • 25
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值