Android开发问题记录之一切问题都是反动派(不是)权限的锅

相机相关的问题,大部分都是权限的问题

  • 开发相机相关的功能的时候,出现了许许多多的问题。有点的会报错,有点不报错也没反应,很多情况下不是代码写的有问题,大部分情况可能只是权限申请的问题。

1.打开相机报错

SecurityException revoked permission android.permission.CAMERA
  • 这个错误比较明显可以看出来是权限申请问题,这个就是高版本android需要动态申请权限。
  • 有的说在AndroidManifest文件添加权限会导致报错,我这里情况是不会,主要还是需要动态申请.
    /**
     * 获取相关权限
     */
    private boolean askPermission() {
        boolean result = false;
        if (Build.VERSION.SDK_INT >= 23) {
            String[] permissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
            for (String permission : permissions) {
                int checkCallPhonePermission = ContextCompat.checkSelfPermission(getActivityContext(), permission);
                if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(getActivityContext(), new String[]{permission}, 0);
                    result = true;
                }
            }
        }
        return result;
    }
  • 我这里没有去监听权限回调,如果没有权限直接不进入接下来的逻辑,每次使用功能判断一下,比较简单无脑。

2.使用MediaMetadataRetriever的setDataSource方法抛出IllegalArgumentException异常

  • 这个功能是截取视频的开头关键帧用来展示
    /**
     * 获取视频关键帧
     *
     * @param filePath
     * @param kind
     * @return
     */
    public static Bitmap createVideoThumbnail(String filePath, int kind) {
        Bitmap bitmap = null;
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        try {
            if (filePath.startsWith("http://")
                    || filePath.startsWith("https://")
                    || filePath.startsWith("widevine://")) {
                retriever.setDataSource(filePath, new Hashtable<String, String>());
            } else {
                retriever.setDataSource(filePath);
            }
            bitmap = retriever.getFrameAtTime(0, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        } catch (RuntimeException ex) {
            ex.printStackTrace();
        } finally {
            try {
                retriever.release();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        if (bitmap == null) {
            return null;
        }

        if (kind == MediaStore.Images.Thumbnails.MINI_KIND) {//压缩图片 开始处
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();
            int max = Math.max(width, height);
            if (max > 512) {
                float scale = 512f / max;
                int w = Math.round(scale * width);
                int h = Math.round(scale * height);
                bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);
            }//压缩图片 结束处
        } else if (kind == MediaStore.Images.Thumbnails.MICRO_KIND) {
            bitmap = ThumbnailUtils.extractThumbnail(bitmap,
                    96,
                    96,
                    ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
        }
        return bitmap;
    }
android:requestLegacyExternalStorage="true" 
  • 经过实验哈,上面这句不加也没问题啊,还是权限申请的问题。

3.获取视频路径总是为null

   case CODE_VIDEO_GALLERY_REQUEST://视频库返回
                if (data.getData() != null) { // 录像或者从视频库选择一个视频
                    Uri uriVideoGallery = data.getData(); // 获得已选择视频的路径对象
                    String realPathVideo = UriUtils.getPath(getActivityContext(), uriVideoGallery);
                    if (realPathVideo == null) return;
                    videoFile = new File(realPathVideo);
                    //保存关键帧图片
                    try {
                        ImageView imageView = currentView.findViewById(R.id.img_pic);
                        setImageToVideo(imageView, createVideoThumbnail(realPathVideo, 1));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                break;
    /**
     * 从Uri获取文件路径,存储路径需要获取
     * android.permission.READ_EXTERNAL_STORAGE权限
     * 适用于MediaStore和其他基于文件的内容提供
     *
     * @param context 上下文对象
     * @param uri     Uri
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public static String getPath(Context context, Uri uri) {
        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // ExternalStorageProvider
            if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {
            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }
  • 上面代码是用来获取获取视频的Uri类型中的文件路径,应为需要操作文件上传啥的。但是每次都是null,然后解决上面问题的时候,添加了动态权限,自然而然的就好了。
  • 所以还是动态权限的锅...

动态权限,害人不浅,你罪大恶极啊。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容