Search code examples
androidimagecordovacordova-3cordova-plugins

Unable to set image source when accessing image from gallery-Android


Iam using cordova 3.4. When i capture an image and set it,its working fine but when I try to access on image from gallery I get the url

content://com.android.providers.media.documents/document/image%4A463

and I get image load error in my image tag.I know this is a know bug going around and I have refered stack questions such as Unable to load image when selected from the gallery on Android 4.4 (KitKat) using PhoneGap Camera Plugin

I cannot use the rough work around mentioned where URI is set manually like content://media/external/images/media/ because we focus devices with internal built in storage such as Moto

Also can you please confirm that this issue has been fixed in cordova 3.5.Because I require permission from my officials for download and I must make sure it is achievable .Can somebody please help

UPDATE:

app.directive('upload', function() {
return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {
        elm.on('click', function() {
            navigator.camera.getPicture(
                    function(imageURI) {
                        scope.$apply(function() {
                            alert(imageURI);
                               ctrl.$setViewValue(imageURI);
                        });
                        window.resolveLocalFileSystemURI(imageURI, function(fileEntry)                                                                       {
                             //                                                   ctrl.$setViewValue(imageURI);
                            alert("inside local file" + imageURI);
                            alert("Inside local file system");
                            fileEntry.file(function(fileObj) {
                                alert("hai");
                                var options = new FileUploadOptions();
                                options.fileKey = "file";
                                options.fileName = fileObj.name;
                                options.mimeType = fileObj.type;
                                var ft = new FileTransfer();
                                // var url = fileUploadUrl;
                                // ft.upload(imageUri, encodeURI(url), success,                 failure, options);
                            });
                        });
                    },
                    function(err) {
                        ctrl.$setValidity('error', false);
                    }, {quality: 50,
                destinationType: Camera.DestinationType.FILE_URI,
                  sourceType: Camera.PictureSourceType.PHOTOLIBRARY
            }
            );
        });
    }
};
       });

My HTML:

  <img
                    ng-src="{{onepic}}" 
                    width="250" 
                    height="390" 
                    alt="error"/>

I set value for onepic in my controller inside watch function.So when directive returns a URI it will be automatically set in onepic.Please specify any alternative solution or if Iam doing anything wrong ,Iam new to angularjs


Solution

  • Try this..

    In Camera Plugin there is one FileHelper.java File, Replace the plugin getRealPath with my this my method.

    For more details you can follow this -> https://issues.apache.org/jira/browse/CB-5398

    FileHelper.java

        @SuppressWarnings("deprecation")
        public static String getRealPath(String uriString, CordovaInterface cordova) {
            String realPath = null;
    
    
            final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
    
            // DocumentProvider
            if (isKitKat) {
            Cursor cursor =  cordova.getActivity().getContentResolver().query(Uri.parse(uriString), null, null, null, null);
            cursor.moveToFirst();
            String document_id = cursor.getString(0);
            document_id = document_id.substring(document_id.lastIndexOf(":")+1);
            cursor.close();
    
            cursor = cordova.getActivity().getContentResolver().query( 
            android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
            null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
            cursor.moveToFirst();
            String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            realPath = path;
            cursor.close();
            }else{
    
            if (uriString.startsWith("content://")) {
                String[] proj = { _DATA };
                Cursor cursor = cordova.getActivity().managedQuery(Uri.parse(uriString), proj, null, null, null);
                int column_index = cursor.getColumnIndexOrThrow(_DATA);
                cursor.moveToFirst();
                realPath = cursor.getString(column_index);
                if (realPath == null) {
                    LOG.e(LOG_TAG, "Could get real path for URI string %s", uriString);
                }
            } else if (uriString.startsWith("file://")) {
                realPath = uriString.substring(7);
                if (realPath.startsWith("/android_asset/")) {
                    LOG.e(LOG_TAG, "Cannot get real path for URI string %s because it is a file:///android_asset/ URI.", uriString);
                    realPath = null;
                }
            } else {
                realPath = uriString;
            }
    
            }
            return realPath;
        }
    

    In CameraLauncher.java Class therer is one method processResultFromGallery

    private void processResultFromGallery
    

    Find this code:

        if (this.targetHeight == -1 && this.targetWidth == -1 &&
                    (destType == FILE_URI || destType == NATIVE_URI) && !this.correctOrientation){
    
            this.callbackContext.success(uri.toString());
        }
    

    And replace with this:

        if (this.targetHeight == -1 && this.targetWidth == -1 &&
                    (destType == FILE_URI || destType == NATIVE_URI) && !this.correctOrientation) {
    
                String s    =FileHelper.getRealPath(uri.toString(), cordova);
                Log.i("test","<<<<ifURI::::::"+s +"URI::::" + uri.toString());
                this.callbackContext.success(s);
    
         }