zoukankan      html  css  js  c++  java
  • Android——华为手机(G9)调用Camera需要手动申请权限

    1. 背景

    Environment.getExternalStorageDirectory()是Android 2.x时代的产物,那时Android主流设备只有很小的内置存储器,然后都会外置一张sd卡,那时这个方法返回的就是外置sd卡的根路径。

    但随着Android进入4.x时代,大部分Android设备都已经内置一个较大存储卡,甚至不提供外置存储卡插槽了,此时Environment.getExternalStorageDirectory()返回的路径其实是由内置存储卡虚拟出来的一个目录,用户在这一目录下有全部权限。

    按理说Android应该继续提供其他的方法来返回其他的外置存储卡的路径,但这一次Android却没有,因为Android系统开发者们发现之前直接允许程序任意访问sd卡的做法导致sd卡上垃圾文件的不可管理性,尤其在程序被卸载后,由于不知道那些文件是由这一程序创建的,所以无法关联删除,因此Android 4.0并不给程序开发者提供外置存储卡的路径,而是提供了诸如getExternalFilesDirs()和getExternalCacheDirs()这样的方法,直接给开发者提供一个限制内的存储文件的空间,这个空间是与程序关联的,因此在卸载程序时这两个目录下的文件也会被关联删除。

     

    2.问题一

    在AndroidManifest里写入了相机权限,读写权限,但华为手机调用Camera失败,无法写入手机内存等。

    原因:Android系统从6.0版本开始增加了一种运行时权限,Camera正好属于运行时权限,这种权限的授权不像6.0以前的Android系统可以安装APP的时候就一次性授权。所以需要在代码里手动申请权限。某些程序在华为G9上一测试就崩掉的原因:程序在运行中请求camera.open()时实际上程序并未获得操作Camera的权限,所以camera.open()会一直打开失败。对于运行时权限不清楚的可以百度搜索Android6.0运行时权限。

     

    问题二

    华为G9手机Environment.getExternalStorageDirectory()得到的是什么?

    答:从手机上自带的文件管理器来看,上面有两个存储位置,一个是内部存储,是华为G9内置的SD卡;一个是SanDisk SD 卡,这个是自己买的然后安装上去的。那么,用Environment.getExternalStorageDirectory()得到的是哪个内存里的路径呢?该方法得到的是/storage/emulated/0是内部存储,也就是华为G9内置的SD卡,当然这是我经过测试后得到的,如下图所示。

    问题三

    使用ContextCompat和ActivityCompat报错

    原因:因为这两个是sdk19以上版本v4包新加的,所以要导入V4包,最好是导入最新的版本,步骤file->project structure->dependencies->右边“+”号然后添加v4包即可。

    代码部分就只写最主要的吧,最底下有源码地址

    MainActivity.java

    public class MainActivity extends Activity {
        public static final int TAKE_PHOTO = 1;
        public static final int CROP_PHOTO = 2;
        private static final String IMAGE_FILE_NAME = "head_image.jpg";// 头像文件
        private static final int CODE_CAMERA_REQUEST = 0xa1;//拍照请求码
        private static String[] PERMISSIONS_STORAGE = {
    //            Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,//写权限
                Manifest.permission.CAMERA//照相权限
        };
        private Button btn;
        private ImageView img;
        private Uri imageUri;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            btn = (Button) findViewById(R.id.take_photo);
            img = (ImageView) findViewById(R.id.picture);
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //用intent调用相机
                    Intent intentFromCapture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    //判断sd卡是否可用
                    if (SDCardUtils.isSDCardEnable()){
                        //ContentValues与HashMap类似,但ContentValues只能保存数据类型,不能保存对象类型
                        ContentValues values = new ContentValues();
                        //key-value形式
                        values.put(MediaStore.Images.Media.TITLE,IMAGE_FILE_NAME);
                        //EXTRA_OUTPUT用于存储所请求的图像或视频的解析Uri
                        imageUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),IMAGE_FILE_NAME));
                        intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
                    }
                    //
                    startActivityForResult(intentFromCapture,CODE_CAMERA_REQUEST);
                }
            });
    
    
            //用于判断SDK版本是否大于23
            if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
                //检查权限
                int i = ContextCompat.checkSelfPermission(this,PERMISSIONS_STORAGE[0]);
                //如果权限申请失败,则重新申请权限
                if(i!= PackageManager.PERMISSION_GRANTED){
                    //重新申请权限函数
                    startRequestPermission();
                    Log.e("这里","权限请求成功");
                }
            }
        }
    
        /**
         * 重新申请权限函数
         */
        private void startRequestPermission(){
            //321为请求码
            ActivityCompat.requestPermissions(this,PERMISSIONS_STORAGE,321);
        }
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (requestCode==CODE_CAMERA_REQUEST&&resultCode==RESULT_OK){
                try {
                    Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
                    img.setImageBitmap(bitmap);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    }

     源码地址:http://download.csdn.net/detail/u013293125/9737050

  • 相关阅读:
    在线JS代码调试网址
    NVM在windows系统下载及安装
    浏览器【插件】【扩展】下载安装
    JavaScript 秘密花园
    HTTP 协议
    移动端:zepto框架
    移动端:移动端事件
    移动端:移动端页面布局
    移动端:Flex弹性盒布局
    移动端:自适应和响应式布局
  • 原文地址:https://www.cnblogs.com/ityizhainan/p/6283328.html
Copyright © 2011-2022 走看看