Aside: CordovaWebView allows you to use the PhoneGap/Cordova component in a larger Android application. Extending the DroidGap class is no longer necessary if you are providing your own Activity that embeds a CordovaWebView. However, you can continue to extend the DroidGap class to give yourself a leg up.
As a result of removing those methods Plugins who were dependent on them being implemented by CordovaInterface ctx member of the Plugin class were left wondering what do I need to do to get my Plugin to compile with PhoneGap 1.9.0.
Well we are sorry for that, it could have and should have been handled better. When PhoneGap 2.0.0 drops we are changing ctx from a CordovaInterface to a LegacyContext class. LegacyContext is a new class that we've introduced that bridges the old CordovaInterface API to the new CordovaInterface API. This means that any Plugin that worked in 1.8.1 should continue to work in 2.0.0 without modification.
This doesn't mean that LegacyContext will be around forever. In fact the class is already deprecated. We will be publishing an Plugin upgrade guide to help developers update their Plugins to the new API. I'll also be going through my plugins (ChildBrowser, TTS, VideoPlayer) and updating the repo to have 1.8.1 and 1.9.0 versions of the Plugins for people to reference. The ctx member from the Plugin class will be going away in a couple of point releases as it has been replaced by a cordova member which is an instance of CordovaInterface.
For those of you who want to get a jump start on updating your plugins here is a brief guide.
- ctx.getContext() replaced with cordova.getContext()
- ctx.startActivity() replaced with cordova.getActivity().startActivity()
- ctx.getSystemService() replaced with cordova.getActivity().getSystemService()
- ctx.getAssets() replaced with cordova.getActivity().getAssets()
- ctx.runOnUiThread() replaced with cordova.getActivity().runOnUiThread()
- ctx.getApplicationContext() replaced with cordova.getActivity().getApplicationContext()
- ctx.getPackageManager() replaced with cordova.getActivity().getPackageManager()
- ctx.getSharedPreferences() replaced with cordova.getActivity().getSharedPreferences()
- ctx.unregisterActivity() replaced with cordova.getActivity().unregisterActivity()
- ctx.getResources() replaced with cordova.getActivity().getResources()
- import com.phonegap.api.* replaced with import org.apache.cordova.api.*
Hi, first post here.
ReplyDeleteI would like to thank you for phonegap, a easy way to make apps for android with no idea of java, yet...
Is extending DroidGap going to be depecrated?
PD: My english sux ;)
thanks Simon :) really helpful!
ReplyDeleteFor video player in android only we can play the files from SDcard and Youtube, Not able to play the video file from Assets! May be I have to programmatically move the file to sdcard or any solutions for that?
@Joan
ReplyDeleteNo, DroidGap is not being deprecated. The LegacyContext class will be deprecated once we get the Plugins updated to the new API.
@Subrahmanya
ReplyDeleteThe latest version of the VideoPlayer copies the file out of assets and onto the SD Card so the video can be player. So, yes you should be able to package a video in the assets folder and have it played by the Plugin.
Replacing ctx.getContext() with cordova.getContext() still gives deprecated warning - "The method getContext() from the type CordovaInterface is deprecated". Any suggestions? Thank you.
ReplyDelete@Darrin
ReplyDeleteDon't worry about that one. We put getContext back in the interface but the deprecation log needs to get removed.
Thanks Simon :) I tried with updated VideoPlay.java got some Error !!!
ReplyDeleteMore Info code: http://paste.org/51757
Full code: http://goo.gl/Zf4DV
droidRuntime(8734): FATAL EXCEPTION: Thread-21
07-16 06:30:36.993: E/AndroidRuntime(8734): java.lang.StackOverflowError
07-16 06:30:36.993: E/AndroidRuntime(8734): at android.util.Log.d(Log.java:137)
07-16 06:30:36.993: E/AndroidRuntime(8734): at org.apache.cordova.api.LOG.d(LOG.java:91)
07-16 06:30:36.993: E/AndroidRuntime(8734): at org.apache.cordova.DroidGap.getContext(DroidGap.java:943)
07-16 06:30:36.993: E/AndroidRuntime(8734): at org.apache.cordova.DroidGap.getContext(DroidGap.java:944)
07-16 06:30:36.993: E/AndroidRuntime(8734): at org.apache.cordova.DroidGap.getContext(DroidGap.java:944)
@Subrahmanya
ReplyDeleteYup, that is that is a bug in 1.9.0 that has been fixed in 2.0.0. Use getActivity in the mean time.
Hi Simon :)Error While running new android_asset VideoPlayer.java (updated to Phonegap 1.9) sample with android_asset videoplay!!
ReplyDeleteMore Info code: http://paste.org/51757
Full code: http://goo.gl/Zf4DV
droidRuntime(8734): FATAL EXCEPTION: Thread-21
07-16 06:30:36.993: E/AndroidRuntime(8734): java.lang.StackOverflowError
07-16 06:30:36.993: E/AndroidRuntime(8734): at android.util.Log.d(Log.java:137)
07-16 06:30:36.993: E/AndroidRuntime(8734): at org.apache.cordova.api.LOG.d(LOG.java:91)
07-16 06:30:36.993: E/AndroidRuntime(8734): at org.apache.cordova.DroidGap.getContext(DroidGap.java:943)
07-16 06:30:36.993: E/AndroidRuntime(8734): at org.apache.cordova.DroidGap.getContext(DroidGap.java:944)
07-16 06:30:36.993: E/AndroidRuntime(8734): at org.apache.cordova.DroidGap.getContext(DroidGap.java:944)
K thanks
ReplyDeleteSimon,
ReplyDeleteI tried to use ctx.getContext() and ignoring the deprecated warning but I get the following error:
at org.apache.cordova.DroidGap.getContext(DroidGap.java:944)
@Subrahmanya and @Darren
ReplyDeleteYes, that stack overflow exception is being caused by a circular reference in 1.9.0. Honestly, 2.0.0 RC1 is out now and 2.0.0 is out Friday and it'll be much better than trying to patch 1.9.0 right now.
Okay, I will try RC1 and see what happens. Thank you!
ReplyDeleteHi Simon, I am now using 2.0.0 RC1 and I get the following error when I call window.plugins.childBrowser.showWebPage():
ReplyDelete07-16 12:08:08.267: I/Web Console(11555): Error: Status=2 Message=Class not found at file:///android_asset/www/cordova-2.0.0rc1.js:994
Simon,
ReplyDeleteI determined why I was getting the "Class not found at file..." error. It was because I named my childBrowser plugin with "cordova" instead of "phonegap". I thought I would need to change all name references to cordova but this was not the case here. Therefore, in my plugins.xml file I now have this and it works.
phonegap 2.0.0 does not work with Android Barcodescanner plugin. Generates an error "barcodescanner module not found in cordova 2.0.0.
ReplyDeleteAny ideas? Worked on previous versions of IOS.
Simon,
ReplyDeleteAre you going to update the BarcodeScanner plugin too? I came over from your old post:
http://simonmacdonald.blogspot.ca/2011/12/installing-barcode-plugin-for-phonegap.html
Thanks,
George
@George
ReplyDeleteMy plan is to give all the plugins a look see on 2.0.0 as soon as possible. I can't think of a reason why it wouldn't work but I may have missed a backwards compatibility point on that plugin.
@Howard
ReplyDeleteI'm confused are you talking about the Android Barcode Scanner or the iOS one? You mention both.
I am talking about the Android Barcode Scanner plugin. I thought it waas important that you know that I have this code running on older versions on IOS. Sothat it is clear the problem is encountered on Android using 2.0.0. I can not use 1.9.0 because of another problem. Thanks!
ReplyDelete@Howard
ReplyDeleteLike I told George in an earlier comment I hope to get a chance to look at it this week.
Thanks!
ReplyDeleteI would appredciate it if you let me kow when you have something that works on 2.0.0.
I aalso use the Barcodescanner and have similar problems which are probably related.
Thanks!
Hi Simon,
ReplyDeleteI am new to Android and I want to get childBrowser in my app.In my eclipse I have Android4.0.3 vesion.I installed MDS Applaud to the eclipse and followed the link http://www.youtube.com/watch?v=84jmuXS8GJI but the proble i when I run the project I am getting the error ctx cannot be resolved..Please help me simon to resolve this..
Thank you and regards
Ashwini
Hi,
ReplyDeleteSo with the switch to 2.0.0 from the CordovaCtx to LegacyContext did we lose the ability to start services in Plugins? Legacy ctx does not have the startService() or bindService() calls available...
Thanks.
@broody
ReplyDeleteCrap, no that is missing from the interface. I can add it for 2.1.0 but in the meantime you'll need to use cordova.getActivity().startService/bindService.
@Ashwini
ReplyDeleteTake a look at some of my other posts which include an updated ChildBrowser plugin for 2.0.0.
Hi Simon,
ReplyDeleteWe have implemented the Phone Gap Android Push Notification using GCM, and referred from https://github.com/marknutter/GCM-Cordova
with Phone Gap 1.7.0 version. Now if I want to port it to 1.9.0 getting this below error, I read your blog where you mentioned that we need to change ctx. to cordova. but still the same error comes, Is the Phone gap 1.9.0 is stable version ?
What all modification we have to do for working in 1.9.0.
Error : “FATAL EXCEPTION : Thread-19, at org.apache.cordova.DroidGap.getContext(DroidGap.java)”
Warm Regards
MohammedIrfan
@Zhakaasssss
ReplyDeleteSwitch to getActivity. There is a bug in 1.9.0 that getContext will cause a stack overflow error.
Hi, i am newbie to phonegap I am working on Plugins for android i was trying with the localNotification plugin...
ReplyDeleteIts having a class Alarm and with constructor
public AlarmHelper(Context context) {
this.ctx = context;
}
now from i am creating an object for the class and passing LegaacyContext of Cordova as an argument but the constructor of Alarm is having Context of Android API
alarm = new AlarmHelper(this.ctx);
@MD SIRAJUDDIN NOORUDDIN
ReplyDeleteWhat's the question?
Hi Simon Mac Donald,
ReplyDeletemy question is how to get the plugin result into our app web components such as Html ?
@MD SIRAJUDDIN NOORUDDIN
ReplyDeleteYou are not providing enough info. Regardless, check out the plugin development guide:
http://docs.phonegap.com/en/2.0.0/guide_plugin-development_index.md.html#Plugin%20Development%20Guide
In phonegap 2.0 how to display a wait cursor for java file of my plugin.Previously i was doing that...
ReplyDeletedroidGap.spinnerStart("","Loading");.
But i think they have remove this method.
@Disasters
ReplyDeleteWell that method is still there and it is public so I'm not sure why it wouldn't work for you as long as you have a reference to the DroidGap class. You could switch to using the JavaScript alternatives:
navigator.notification.activityStart(title, message);
navigator.notification.activityStop();
I also noticed that ctx.getContentResolver() should be changed to cordova.getActivity().getContentResolver()
ReplyDeleteAndroid 4.0.3
ReplyDeleteZebracrossing 2.1
Cordova 2.0.0
In BarcodeScanner I use Zxing
IntentIntegrator tintegrator = new IntentIntegrator(tempact);
Which works great but I have to pass in the Activity so that
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
Method will execute on return from Zxing scanning
Problem is that BarcodeScanner is a Java class extends Plugin but it's not an Activity. I want the Zxing IntentIntegrator to come back to BarcodeScanner Class so that I can execute the Encode and this.success just like is in the Plugin Class. When I put in my MainActivity to IntentIntegrator, it works to come back there in onActivityResutls but can't get back to Plugin to execute success.
@guitar99
ReplyDeleteYou need to use the following code from your Plugin to get an activity:
this.cordova.getActivity();
but you can see how to call an activity from a plugin using:
this.cordova.startActivityForResult();
in:
https://github.com/phonegap/phonegap-plugins/blob/master/Android/BarcodeScanner/2.0.0/src/com/phonegap/plugins/barcodescanner/BarcodeScanner.java
I tried the barcode demo app and it is not working. this is the error "Cannot read property 'barcodeScanner' of undefined"
ReplyDeleteIts working on samsung galaxy y running android gingerbread but not working in samsung galaxy tab running android froyo.
What should I do to make it work in android froyo?
@reineskye25
ReplyDeleteI don't have a 2.2 device but it is working in the froyo emulator.
Hi Simon :)
ReplyDeleteI am new to phonegap development. I m trying to implement a video module using cordova 2.1.0.. Here i can hear the sound from my video but not able to view it. Can u plss help me out.
here is the code which i m using..
var video = document.getElementById('example_video_1'); video.addEventListener('click',function(){
video.play(); },false);
Thanks in advance :)
@vinutha v
ReplyDeleteWhat version of Android are you using? There are many problems with the video tag on Android. Did you read my many posts on the subject on this blog? Also, if you hear the audio but not the video you are probably trying to play an unsupported video type. See this table:
https://developer.android.com/guide/appendix/media-formats.html#core
hi Simon,
ReplyDeleteIn phonegap local notification plugin for android cancelAll is not working.
https://github.com/phonegap/phonegap-plugins/tree/master/Android/LocalNotification
i am using cordovo 2.1
any idea..??
@Amit Kumar
ReplyDeleteSorry, I haven't used it in awhile. You should ask the plugin owner/originator.
Hi Simon, Thanks a lot for your very useful Tutorials and great efforts.
ReplyDeleteI'm using the Android Local Notifaction plugin now, but I have a problem with this line:
public PluginResult execute(String action, JSONArray optionsArr, CallbackContext callBackId) {
I can't change it to public boolean execute(String action, JSONArray data, CallbackContext callbackContext) {
as it shows an error with return type If I did that, so is there a solution ?
Hi Simon, I need your help on get phone number from Andorid PhoneGap, I have tried some options on your blog, but no luck, Plz find sending code and Error,
ReplyDeleteLet me know your Suggestions,
Thanks in Advance.
==========================
This is my CODE
==========================
package com.vasu.sms;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import android.telephony.TelephonyManager;
import android.util.Log;
import org.apache.cordova.api.*;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.apache.cordova.api.PluginResult.Status;
/**
* @author Guy Vider
*
*/
public class MyPhoneNumberPlugin extends Plugin {
@Override
public PluginResult execute(String action, JSONArray data, String callbackId) {
Log.d("MyPhoneNumberPlugin", "Plugin called");
PluginResult result = null;
try {
JSONObject number = getMyPhoneNumber();
Log.d("MyPhoneNumberPlugin", "Returning "+ number.toString());
result = new PluginResult(Status.OK, number);
}
catch (Exception ex) {
Log.d("MyPhoneNumberPlugin", "Got Exception "+ ex.getMessage());
result = new PluginResult(Status.ERROR);
}
return result;
}
private JSONObject getMyPhoneNumber() throws JSONException {
Log.d("MyPhoneNumberPlugin", "at getMyPhoneNumber");
JSONObject result = new JSONObject();
TelephonyManager tm = (TelephonyManager) cordova.getSystemService(Context.TELEPHONY_SERVICE);
String number = tm.getLine1Number();
if(number.equals("") || number == null) {
Log.d("MyPhoneNumberPlugin", "We're on a non-phone device. Returning a hash of the UDID");
number = md5(tm.getDeviceId()).substring(0, 10);
}
Log.d("MyPhoneNumberPlugin", "Phone number=" + number);
result.put("phoneNumber", number);
return result;
}
private String md5(String s) {
try {
// Create MD5 Hash
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
digest.update(s.getBytes());
byte messageDigest[] = digest.digest();
// Create Hex String
StringBuffer hexString = new StringBuffer();
for (int i=0; i<messageDigest.length; i++)
hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
Log.d("MyPhoneNumberPlugin", e.getMessage());
}
return "";
}
}
======================
This is Error
======================
The method getSystemService(String) is undefined for the type CordovaInterface
@Rana Mahdy
ReplyDeleteIt is not sufficient to just change the method signature. You need to go through and replace everywhere you return a PluginResult with a call to sendPluginResult. For example:
callbackContext.sendPluginResult(new PluginResult(status, result));
Then you need to return a boolean variable that in most cases should be true to say that the action was valid.
@Vasu Nanguluri
ReplyDeleteLots of people seem to be asking for this functionality so I'm going to do a full blog post on it.
To answer your question, change:
TelephonyManager tm = (TelephonyManager) cordova.getSystemService(Context.TELEPHONY_SERVICE);
to:
TelephonyManager tm = (TelephonyManager) cordova.getActivity().getSystemService(Context.TELEPHONY_SERVICE);
Hi, i'm trying to install the LibraryProject of Barcode Plugin for PhoneGap Android.
ReplyDeleteeclipse give an error in the BeepManager.java file
"beep cannot be resolved or is not a field" line 97 Java Problem
how to solve it?
Thanks
Hi. I wrote a simple plugin to call a function in my MainActivity. But it never gets called. I use this to do it from my plugin.java file
ReplyDeleteMainActivity ma = (MainActivity)this.cordova.getActivity();
ma.customFunctionCalled();
Is that the right way to get a handle on the MainActivity objext? I debugged it and it doesnt get past the first line above. Using cordova 2.1.
@detoxnet
ReplyDeleteThere is no reason why that shouldn't work. I just did a quick test with 2.3.0rc2 and it worked great for me.
@Pozz
ReplyDeleteI haven't ever seen that error and there is no field called "beep" in BeepManager.java so I'm having a hard time figuring out where it could be coming from.
Hi simon ,
ReplyDeleteI am using 2.4.0 , trying to implement the PushPlugin via Eclipse for Andriod. When I build the project I get the following error :
The method getContext() is undefined for the type CordovaInterfac PushPlugin.java
Any suggestion would be very much appriciated
@Lori Azrad
ReplyDeleteThe API has changed somewhat. I think you are looking for:
this.cordova.getActivity().getApplicationContext()
Hi Simon,
ReplyDeleteI am creating a share plugin with the help of this url:
https://github.com/libbybaldwin/phonegap-plugins/tree/master/Android/ChildBrowser
I am using phonegap 2.9 version and have made changes according to that in ChildBrowser.java file however still getting errorslike one of in this line
intent = new Intent().setClass(this.ctx, org.apache.cordova.DroidGap.class);
Error: ctx cannot be resolved or is not a field
What should I use to replace this.ctx .
Please reply soon, thanks in advance.
@Nitin Ajmani
ReplyDeleteIt's right there in the post.
this.ctx becomes this.cordova or this.cordova.getContext() depending on what you need.
Hi Simon,
ReplyDeleteI have implemented this.cordova and this.cordova.getContext() in place of this.ctx however it is not working.
I am a beginner to Android Applications and I want to implement Share button functionality to my Phonegap Android App however I am not successful in many attempts.
I am using Phonegap 2.9.0 and Android Developer Tools version Build: v21.1.0-569685 .
Can you please help me to add share button functionality for Facebook, Twitter, Gmail, SMS etc using phonegap.
Your help is really appreciated.
Thank You.
@Nitin Ajmani
ReplyDeleteCheck out this blog post:
http://teusink.blogspot.com/2013/04/phonegap-android-share-plugin.html
Hello Simon,
ReplyDeleteI started using PhoneGap 3 days back and I am so liking it. I am planning to integrate my PhoneGap app with Databse.com and luckily they have some very nice blogs out on there on the web for the same.
I am using cordova 1.7.0 and as I got childBrowser.java in my source folder, I get several errors reading 'cordova cannot be resolved or is not a
field'. Wondering why would this happen and no substantial posts for these on the web. Please help
@supriya hirurkar
ReplyDeleteMake sure you are using the right version of ChildBrowser.java with your version of PhoneGap. We broke the plugin api along the way so different versions of the ChildBrowser were needed.