Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Phonegap Plugin Activity Import Layout

I'm developing a Cordova Plugin that has an Activity, and I need to access the application R.layout from this activity so I can call setContentView.

I'm currently doing this by making an import com.example.hello.R and then on the onCreate method I callsetContentView(R.layout.mysurfaceview)`:

The problem is that my plugin will only work if the application name is com.example.hello, but I need to install my plugin on different applications without manually making the imports.

Is there a way to make a generic import, something like import <appName>.R, or any other ways to do that?

like image 639
Bruno Avatar asked Nov 14 '13 13:11

Bruno


3 Answers

You could call the application's resource pool at runtime and refer to the identifier by name using the Resources.getIdentifier() function. This function needs the resource name, type, and package name. For example:

 String package_name = getApplication().getPackageName();
 Resources resources = getApplication().getResources();
 setContentView(resources.getIdentifier("my_activity_layout", "layout", package_name));

where "my_activity_layout" is the name of the layout xml file. You can also refer to strings, drawables, and other resources in the same fashion. Once you have that bit of code in your activity, you can designate your activity layout file as a source file in your plugin.xml file and set it to be copied into the res/layout folder.

<source-file src="path/to/your/layout/file.xml" target-dir="res/layout"/>

Check out the Phonegap Plugin Specification if you have any other questions about using the source-file designation.

like image 170
budoudoh Avatar answered Sep 23 '22 14:09

budoudoh


I would use a cordova CLI hook to modify the java import statement at build time, perhaps by parsing the name of the package out of the AndroidManifest or config.xml.

I don't believe there's a way to do a wildcard package import like you are asking about.

like image 24
mooreds Avatar answered Sep 23 '22 14:09

mooreds


Thanks to mooreds's answer, You can create an after_plugin_install hook in your plugin like below

#!/usr/bin/env node
/*
A hook to add R.java to the draw activiy in Android platform.
*/


var fs = require('fs');
var path = require('path');

var rootdir = process.argv[2];

function replace_string_in_file(filename, to_replace, replace_with) {
    var data = fs.readFileSync(filename, 'utf8');
    var result = data.replace(to_replace, replace_with);
    fs.writeFileSync(filename, result, 'utf8');
}

var target = "stage";
if (process.env.TARGET) {
    target = process.env.TARGET;
}

    var ourconfigfile = path.join( "plugins", "android.json");
    var configobj = JSON.parse(fs.readFileSync(ourconfigfile, 'utf8'));
  // Add java files where you want to add R.java imports in the following array

    var filestoreplace = [
        "platforms/android/src/in/co/geekninja/plugin/SketchActivity.java"
    ];
    filestoreplace.forEach(function(val, index, array) {
        if (fs.existsSync(val)) {
          console.log("Android platform available !");
          //Getting the package name from the android.json file,replace with your plugin's id
          var packageName = configobj.installed_plugins["in.co.geekninja.Draw"]["PACKAGE_NAME"];
          console.log("With the package name: "+packageName);
          console.log("Adding import for R.java");
            replace_string_in_file(val,"package in.co.geekninja.plugin;","package in.co.geekninja.plugin;\n\nimport "+packageName+".R;");

        } else {
            console.log("No android platform found! :(");
        }
    });

And add the following line between <platform name="android"> ... </platform> tag

<hook type="after_plugin_install" src="hooks/after_plugin_install/hook-add-r-import.js" />
like image 44
insomniac Avatar answered Sep 23 '22 14:09

insomniac