Friday, October 21, 2016

Read and Write permission for storage and gallery - open failed: EACCES (Permission denied) Cordova

After Android OS upgrade to Marshmallow(6.0), permission has categorized into two sections "Normal and Dangerous Permissions". On this version on wards, users have to grant permission when the app is running but not at the time of app installation via play store. Also app developers have to request permission on "Dangerous Permission" at the time of using device resources such as Camera, Location, Gallery, External Storage.

Normal permissions do not directly risk the user's privacy. If your app lists a normal permission in its manifest, the system grants the permission automatically.

Dangerous permissions can give the app access to the user's confidential data. If your app lists a normal permission in its manifest, the system grants the permission automatically. If you list a dangerous permission, the user has to explicitly give approval to your app.
(Reference: Android API)


Let's create a sample Ionic project using Visual Studio 2015 to see how it is get done beginning of Marshmallow(API Level 23).

Step 01:- Create a Iconic tab template

Step 02:- Install File, FileTransfer, Permission plugins

cordova plugin add cordova-plugin-file
cordova plugin add cordova-plugin-file-transfer
cordova plugin add cordova-plugin-android-permissions@0.10.0

Please refer more details for the API urls listed below:

  • file (https://github.com/apache/cordova-plugin-file)
  • file-transfer (https://github.com/apache/cordova-plugin-file-transfer)
  • permissions (https://github.com/NeoLSN/cordova-plugin-android-permission)
Step 03:- Add a button to your UI and create a method in your control.

angular.module('starter.controllers', ['ionic'])

.controller('DashCtrl', function ($scope, $ionicPlatform) {

    $scope.downloadFile = function () {

        $ionicPlatform.ready(function () {
       // File for download
       var url = "http://www.gajotres.net/wp-content/uploads/2015/04/logo_radni.png";

       // File name only
       var filename = url.split("/").pop();

       // Save location
        var targetPath = cordova.file.externalRootDirectory + 'Download/' + filename;

       var fileTransfer = new FileTransfer();
       var uri = encodeURI(url);
       var trustHosts = true
       var options = {};


            fileTransfer.download(
                uri,
                targetPath,
                function (entry) {
                    console.log("download complete: " + entry.toURL());
                },
                function (error) {
                    console.log("download error source " + error.source);
                    console.log("download error target " + error.target);
                    console.log("download error code" + error.code);
                },
                trustHosts,
                options
            );
        });
    };
})

If you run this code without requesting permission for external storage, it will throw  open failed: EACCES (Permission denied) error message.

Step 04:-  Let's modify the code to request permission for storage.

Note: Go through the API documentation for more details.

//var permissions = cordova.plugins.permissions;
//permissions.hasPermission(permission, successCallback, errorCallback);
//permissions.requestPermission(permission, successCallback, errorCallback);
//permissions.requestPermissions(permissions, successCallback, errorCallback);


var permissions = cordova.plugins.permissions;
permissions.hasPermission(permissions.READ_EXTERNAL_STORAGE, checkPermissionCallback, null);

        function checkPermissionCallback(status) {
            if (!status.hasPermission) {
                var errorCallback = function () {
                    console.warn('Storage permission is not turned on');
                }
                permissions.requestPermission(
                  permissions.READ_EXTERNAL_STORAGE,
                  function (status) {
                      if (!status.hasPermission) {
                          errorCallback();
                      } else {
                          // continue with downloading/ Accessing operation 
                          $scope.downloadFile();
                      }
                  },
                  errorCallback);
            }
        }

11 comments:

  1. Thanks a lot man.....you just save me 1 hour of fixing this....

    ReplyDelete
  2. Thanks dear author. This post is very useful to me.

    The Android users are increasing daily and I hope this recovery tool may help the smartphone users which are suffering from data loss and media files deletion from them.

    I would like to recommend you the android data lost users to use Android Data Recovery Software to get easily and in just a few steps they will get back their all lost data from LeMax, Realme, Samsung, Blu Dash, Xiaomi, Huawei, ZTE, Lenovo, Motorola, Oppo, OnePlus, and much more mobile phones also.

    ReplyDelete
  3. keep up the good work. This is an Awesome post. this to helpful, I have reading here all post. I am impressed. Thank you.
    Reactjs Training in Chennai |
    Best Reactjs Training Institute in Chennai |
    Reactjs course in Chennai

    ReplyDelete
  4. You should be a piece of a challenge for probably the best website on the web. I will suggest this site!

    best interiors

    ReplyDelete
  5. Thank you for your post. This is excellent information. It is amazing and wonderful to visit your site. For more info:- Cordova App Development

    ReplyDelete