6

I'm trying to make a phone call from my index.html in phonegap using a native method from MainActivity.

I'm using phonegap 3.0 and android 4.3 platform. I tried the second answer on this post but it is not working for this versions.

I would like to know what is the best approach to get through this?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
nramirez
  • 5,230
  • 2
  • 23
  • 39

2 Answers2

11

You can create a custom plugin to call any method from the native side. Create a separate JavaScript file, say customplugin.js, and put this into it:

var CustomPlugin = {};

CustomPlugin.callNativeMethod = function() {
    cordova.exec(null, null, "CustomPlugin", "callNativeMethod", []);
};

Now on the native Java side, create a new class and name it CustomPlugin.java, then add this:

package com.yourpackage;

import org.apache.cordova.CordovaWebView;
import org.apache.cordova.api.CallbackContext;
import org.apache.cordova.api.CordovaInterface;
import org.apache.cordova.api.CordovaPlugin;

import com.yourpackage.MainActivity;

public class CustomPlugin extends CordovaPlugin
{
    private static final String TAG   = "CustomPlugin";

    private CallbackContext callbackContext = null;
    private MainActivity activity = null;

    /** 
     * Override the plugin initialise method and set the Activity as an 
     * instance variable.
     */
    @Override
    public void initialize(CordovaInterface cordova, CordovaWebView webView) 
    {
        super.initialize(cordova, webView);

        // Set the Activity.
        this.activity = (MainActivity) cordova.getActivity();
    }

    /**
     * Here you can delegate any JavaScript methods. The "action" argument will contain the
     * name of the delegated method and the "args" will contain any arguments passed from the
     * JavaScript method.
     */
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException 
    {
        this.callbackContext = callbackContext;

        Log.d(TAG, callbackContext.getCallbackId() + ": " + action);

        if (action.equals("callNativeMethod")) 
        {
            this.callNativeMethod();
        }
        else
        {
            return false;
        }

        return true;
    }

    private void callNativeMethod()
    {
        // Here we simply call the method from the Activity.
        this.activity.callActivityMethod();
    }
}

Make sure you map the plugins in the config.xml file by adding this line:

...
<feature name="CustomPlugin">
    <param name="android-package" value="com.yourpackage.CustomPlugin" />
</feature>
...

Now to call the plugin from your index.html you can simply call your JavaScript method:

CustomPlugin.callNativeMethod();

Using this method will allow you to set up many custom methods conveniently. For more information check the PhoneGap plugin development guide here.

kieranroneill
  • 849
  • 7
  • 9
  • Thanks @suprnova your answer is helpful maybe it work for previous version but I notice i'm using the last version of phonegap (3.0) and I coded this but is not working. I got this error exec() call to unknown plugin, I found something similar here http://stackoverflow.com/questions/17974301/phonegap-3-plugin-exec-call-to-unknown-plugin – nramirez Sep 04 '13 at 17:56
  • 1
    You're right, this will not work with PhoneGap 3.0, but I think it is because the plugin mapping I used in the previous answer is deprecated. However, I have updated my answer with the PhoneGap 3.0 mapping. Essentially, the '` element in the config.xml is deprecated, you must use the element `` instead. – kieranroneill Sep 05 '13 at 08:56
  • Yes! I'm on it! As soon as I get the solution to this question I'll post the answer! – nramirez Sep 05 '13 at 12:44
  • 1
    Perfect. I don't know why but i was putting my element in ~/android/www/config.xml and didn't work, then I moved it to ~/android/res/xml/config.xml and works perfectly. Thanks @suprnova – nramirez Sep 05 '13 at 19:45
  • @suprnova why do you need the separate `callNativeMethod()`? can't you just call it from the execute method? thanks btw for the solution:) – benka Nov 12 '13 at 16:40
  • 1
    @benka you are right, you can indeed just call it from the `execute()` method. The only reason I have the `callNativeMethod()` is just so you can use the `execute()` method to delegate to other methods. So, in the `if-else` statement you can add more clauses for other methods. If you are just calling one method, it is probably worth just using the `execute()` method. – kieranroneill Nov 13 '13 at 14:35
2

After completing everything from the above answer, you will also need to add the plugin in res/xml/config.xml to make it work

<plugin name="PluginName" value="com.namespace.PluginName"/>

before the </plugins> tag