【问题标题】:Cordova-plugin-camera not working with Android version 8Cordova-plugin-camera 不适用于 Android 版本 8
【发布时间】:2018-11-09 10:36:25
【问题描述】:

我正在使用 cordova-plugin-camera 来访问 Android 中的相机。在我将 Target SDK 版本更改为 API 26:Android 8.0 (Oreo) 之前,这一切正常,以便能够上传到现在需要此版本或更高版本的 Google Play 商店。

我得到的错误是

file:///data/user/0/{mypackage}/cache/Capture.jpg 通过 ClipData.Item.getUri() 暴露在应用之外

我认为这是由于应用程序从 Android Nougat 访问文件系统的方式发生了变化 - 请参阅 android.os.FileUriExposedException: file:///storage/emulated/0/test.txt exposed beyond app through Intent.getData()

我已尝试根据https://github.com/ionic-team/ng-cordova/issues/1381 使用不同版本的cordova、cordova android 和相机插件解决问题,但在每种情况下,只要我将TargetSDK 更改为26,我都会在Android 8 手机上遇到相同的错误。

我已将以下内容添加到我的 AndroidManifest.xml 文件中

            <provider android:authorities="com.okappy.okappy.provider" android:exported="false" android:grantUriPermissions="true" android:name="android.support.v4.content.FileProvider">
        <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/camera_provider_paths" />
    </provider>

我已经检查过我有一个带有以下内容的 camera_provider_paths.xml

    <paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>

我也尝试在 cordova/camera/CordovaURI.java 中编辑以下行以强制忽略 fileUri,但没有任何区别

    public Uri getCorrectUri()
{
    /*if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        return androidUri;
    else
        return fileUri;
    */
    return androidUri;

}

我有以下版本

  • 8.1.2 (cordova-lib@8.1.1)

  • 安卓 7.1.2

  • cordova-plugin-camera 4.0.3

  • cordova-plugin-console 1.0.3
  • cordova-plugin-file 6.0.1

我正在使用 Compile SDK 版本 28.0.3、MinumumSDK 版本 21 和 TargetSDK 版本 26。

提前感谢您的帮助

【问题讨论】:

    标签: android cordova cordova-plugins


    【解决方案1】:

    问题在于我们的代码而不是插件 - view issue on github

    我们使用以下代码

    function captureImage() {
        navigator.device.capture.captureImage(captureImageSuccess, captureImageError, {limit: 1});
    }
    
    function captureImageSuccess(mediaFiles) {
        uploadFile(mediaFiles[0]);
    }
    
    function uploadFile(mediaFile,fileType) { //#F333
        var win = function (r) {
    }
    
    var options = new FileUploadOptions();
        ImageURL=mediaFile.fullPath;
        options.fileName = (fileType)? mediaFile.name : mediaFile.file; //#F333
        options.mimeType = "multipart/form-data";
        var params = new Object();
        params.fileName = 'AndroidPhoneUpload';
        params.imageType = (fileType)?fileType:'Picture';   //#F333
        var printName = prompt("Add a title","");  //#F644
        if (printName){
            params.printedName = printName;
        }
        window.resolveLocalFileSystemURL(ImageURL, function(fileEntry) {
            fileEntry.file(function(fileObj) {
                params.fileSize = ""+fileObj.size;
            });
        });
        options.params = params;
        var ft = new FileTransfer();
        ft.upload(ImageURL, encodeURI("uploadURL"),win,fail,options);
    }
    

    我们已将 captureImage 函数替换为以下 addImage 函数

    function setOptions(srcType) {
        var options = {
            quality: 50,
            limit: 1,
            destinationType: Camera.DestinationType.FILE_URI,
            // In this app, dynamically set the picture source, Camera or photo gallery
            sourceType: srcType,
            encodingType: Camera.EncodingType.JPEG,
            mediaType: Camera.MediaType.PICTURE,
            allowEdit: false,
            correctOrientation: true  
        }
        return options;
    }
    
    function addImage() {
    
      var srcType = Camera.PictureSourceType.CAMERA;
      var options = setOptions(srcType);
    
      navigator.camera.getPicture(function cameraSuccess(imageUri) {
            var options = new FileUploadOptions();
            options.fileKey="file";
    
            options.fileName="test";
            options.mimeType="multipart/form-data";
    
            var params = new Object();
            params.fileName = 'AndroidPhoneUpload';
            params.imageType = 'Picture';
            var printName = prompt("Add a title","");
            if (printName){
                params.printedName = printName;
            }
            options.params = params;
            navigator.notification.alert("Your media is being uploaded.", null, "Add media");
    
            var ft = new FileTransfer();
            ft.upload(imageUri, encodeURI("uploadURL"), win, fail, options);
    
        }, function captureImageError(error) {
            console.debug("Unable to obtain picture: " + error, "app");
        }, options);
    }
    

    为了进一步澄清,我认为问题是因为我们使用相机拍摄图像,然后尝试从存储中上传媒体文件,这导致新版本的 Android 出现权限问题。

    【讨论】:

    • 具体是什么问题?我看不出你的代码有什么区别。
    • 我有同样的问题,但使用 Ionic v1... 我应该如何更改 Ionic v1 的相机插件代码?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-27
    • 2017-03-03
    相关资源
    最近更新 更多