Copying resource to android platform


#1

Hi,

I added some images I want to add to android platform only. I’ve added the following lines under <platform name="android"> in my config.xml:

<resource-file src="resources/android/ic_stat_push_android/drawable-hdpi.png" target="platforms/android/res/drawable-hdpi/ic_stat_push_android.png" />

However I can’t seem to get it to copy. What do I need to run for the resource to be copied?


#2

Is your cordova-android@6.2.1 or greater? Also, the location of the file needs to be relative to config.xml.


#3

“cordova-android”: “^6.2.3”, and the paths are relative to the config.xml file


#4

For anyone who encounters this issue, this is the solution I ended up using.

  1. create a file named android_custom_resources.js:

     var fs = require('fs');
     var path = require('path');
    
     var sourceDir = 'resources/android/custom';
     var platformDir = 'platforms/android';
     var resourceDirs = [
     'res/drawable-ldpi',
     'res/drawable-mdpi',
     'res/drawable-mdpi-v11',
     'res/drawable-hdpi',
     'res/drawable-hdpi-v11',
     'res/drawable-xhdpi',
     'res/drawable-xhdpi-v11',
     'res/drawable-xxhdpi',
     'res/drawable-xxhdpi-v11',
     'res/drawable-xxxhdpi',
     'res/drawable-xxxhdpi-v11'
      ];
    
      module.exports = function(ctx) {
       if (ctx.opts.platforms.indexOf('android') < 0) {
         return;
       }
    
     var Q = ctx.requireCordovaModule('q');
     var deferred = Q.defer();
     var androidPlatformDir = path.join(ctx.opts.projectRoot, platformDir);
     var customResourcesDir = path.join(ctx.opts.projectRoot, sourceDir);
    
     function copy(src, dest) {
       var deferred = Q.defer();
    
       fs.stat(src, function(err, stats) {
         if (err || !stats.isFile()) {
           return deferred.reject(err);
         }
    
         fs.stat(path.dirname(dest), function(err, stats) {
           if (err || !stats.isDirectory()) {
             return deferred.reject(err);
           }
    
         var rs = fs.createReadStream(src);
    
         rs.on('error', function(err) {
           console.error(err.stack);
           deferred.reject(err);
         });
    
         var ws = fs.createWriteStream(dest);
    
         ws.on('error', function(err) {
           console.error(err.stack);
           deferred.reject(err);
         });
    
         ws.on('close', function() {
           deferred.resolve();
         });
    
         rs.pipe(ws);
       });
     });
    
     return deferred.promise;
     }
    
      fs.stat(customResourcesDir, function(err, stats) {
        if (err || !stats.isDirectory()) {
          return deferred.resolve();
       }
    
     fs.readdir(customResourcesDir, function(err, files) {
       var copies = [];
       for (var i in files) {
         var innerDir = path.join(customResourcesDir, files[i]);
         var innerFiles = fs.readdirSync(innerDir);
         for (var k in innerFiles){
           var innerFilePath = path.join(innerDir, innerFiles[k]);
           var innerDestPath = path.join(androidPlatformDir, 'res', files[i], innerFiles[k]);
    
           copies.push([innerFilePath, innerDestPath]);
         }
       }
    
       copies.map(function(args) {
         return copy.apply(copy, args);
       });
    
       Q.all(copies).then(function(r) {
         deferred.resolve();
       }, function(err) {
         console.error(err.stack);
         deferred.reject(err);
          });
        });
      });
    
      return deferred.promise;
     }
    
  2. place it in a folder in your root project directory (in my case I called it package_hooks and reference it from your config.xml

     <hook src="package_hooks/android_custom_resources.js" type="after_prepare" />
    

this script assumes that inside your <project root>/resources/android/custom directory, files are placed in the folders named the same as the ones you expect them to be copied to. For example, if I have a file <my project>/resources/android/custom/drawable-xxhdpi/myfile.png, it will be copied to:
<my project>/platforms/android/res/drawable-xxhdpi/myfile.png

It will surely break if you have files in the /custom directory itself, but otherwise it did the job for me and I hope it helps someone else looking for a temporary solution.


#5

I would file an issue with Apache Cordova.