First if you are unsure about how application preferences are setup on Android go read this tutorial and then come back I'll wait. Oh great, your back. Let's crack on with things.
Functionality
Okay, so the application preferences plugin will provide you with four methods that you can use to interact with the native Android preferences.
get(key, success, fail)
If the key exists in the preferences it will be returned as the single parameter of the success callback that you provide. If the key does not exist the failure callback will be executed with an error object with error.code set to 0 which means no property.
window.plugins.applicationPreferences.get(key, function(value) { console.log("The value is = " + value); }, function(error) { console.log(JSON.stringify(error)); });
set(key, value, success, fail)
If the key exists in the preferences then value will be saved and your the success callback will be executed. If the key does not exist the failure callback will be executed with an error object with error.code set to 0 which again means no property.
window.plugins.applicationPreferences.set(key, value, function(value) { console.log("set correctly"); }, function(error) { console.log(JSON.stringify(error)); });
load(success, fail)
Calling load will have the native side loop through all the preferences creating a JSON object that will be returned as the single parameter of your success callback.
window.plugins.applicationPreferences.load(function(value) { console.log("The object is = " + JSON.stringify(value)); }, function(error) { console.log(JSON.stringify(error)); });
show(activity, success, fail)
Calling show passing in the class name of your PreferenceActivity class will cause the native Android GUI to be shown so your user can interact with the preferences. If the class name you pass in doesn't exists your failure callback will be called with an error object with error.code set to 1 which means no preferences activity.
window.plugins.applicationPreferences.show("com.simonmacdonald.prefs.QuickPrefsActivity");
which brings up a GUI that looks like this:
Installation
Installation of the Plugin follows along the common steps:
- Add the script tag to your html:
<script type="text/javascript" charset="utf-8" src="applicationPreferences.js"/>
- Copy the Java code into your project to the src/com/simonmacdonald/prefs folder.
- Create a preferences file named res/xml/preferences.xml following the Android specification.
- Finally you'll need to create a class that extends PreferenceActivity in order to be able to view/modify the preferences using the native GUI. Refer back to the tutorial I mentioned for more details.
Oh, and I'm pretty sure that Darren McEntee has already included this plugin in his Live Football on TV app which means this plugin is already in the wild.
Enjoy!
Nice! Again: thanks. :)
ReplyDeleteIt wasn't Randy that made it
ReplyDelete@Tue
ReplyDeleteSorry for the incorrect attribution. I looked at the iOS directory when I should have been looking at the iPhone directory. I just fixed up the post to give you credit.
Hi,
ReplyDeleteI'm trying to install this plugin, but I can't run it because of 1 error:
"The method startActivity(Intent) is undefined for the type CordovaInterface"
There are also several warnings:
"The value of the field AppPreferences.LOG_TAG is not used"
The method getContext() from the type CordovaInterface is deprecated
"Map is a raw type. References to generic type Map should be parameterized"
"Iterator is a raw type. References to generic type Iterator should be parameterized"
I'm using Eclipse 4.2 on Fedora
Am I missing anything?
Thanks in advance,
Rafael
@Rafa
ReplyDeleteUpgrade to 2.0.0 and the error should go away. Don't worry about the warnings though.
Hi, Simon,
ReplyDeleteI can´t get started this AppPrefs plugin. I changed to cordova 2.0, set all things like the readme, create a preferences.xml and a QuickPrefsActivity like
package my.package;
import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class QuickPrefsActivity extends PreferenceActivity {
@Override
public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
Eclipse don´t show me any error, but the emulator shows me nothing, too :(
Is there a working example?
Sorry for bad english
Hi, Simon ... it´s running ;) anyway, thanks
ReplyDeleteHi Simon,
ReplyDeleteFirst of all, and knowing that I'm very belated in saying it, thanks a lot for your previous response. Because of several issues (including having to change my OS), I couldn't check it until a few minutes ago.
The error got fixed as you said. But now I'm having another error, this time related with de javascript code. The error is
Result of expression 'window.plugins' [undefined] is not an object at file ...js:196
The referred line is:
function dime_pref(key,defecto) {
window.plugins.applicationPreferences.get(key, function(value) {
console.log("El valor de la preferencia es = " + value);
return value;
}, function(error) {
console.log(JSON.stringify(error));
return defecto
});
}
Of course, your code (cordova.define(...) is previous to that line.
Once again, thank you very much in advance.
@Rafa
ReplyDeleteSomeone did a pull request on my plugin. You should just be able to call appPreferences.get() now. No need for the window.plugins bit.
Simon, thanks for your quick response.
ReplyDeleteI must be doing something wrong. Now I get the error "ReferenceError: Can't find variable: appPreferences"
I'm not much experienced on javascript, so I'm not sure how this works, but I notice that appPreferences is defined inside (more precisely, at the end of them) the following lines:
cordova.define("cordova/plugin/applicationpreferences", function(require, exports, module) {
...
...
var appPreferences = new AppPreferences();
module.exports = appPreferences;
});
Am I missing anything?
Thanks again
@Rafa
ReplyDeleteSorry, I made a mistake. here is the kinda code you want to add to your deviceready handler so you don't need to modify the rest of your html.
if (!window.plugins) {
window.plugins = {};
}
if (!window.plugins.applicationPreferences) {
window.plugins.applicationPreferences = cordova.require("cordova/plugin/applicationpreferences");
}
It worked! Great!
ReplyDeleteThanks a lot.
Using 2.0.0, I put the next code in the ondebiceReady event:
ReplyDeleteif (!window.plugins) {
window.plugins = {};
}
if (!window.plugins.applicationPreferences) {
window.plugins.applicationPreferences = cordova.require("cordova/plugin/applicationpreferences");
}
applicationPreferences.get("enterTimes", function(value) {
console.log("The value is = " + value);
}, function(error) {
console.log(JSON.stringify(error));
});
And i got the error:
module cordova/plugin/applicationpreferences not found at undefined:0
Could you help me please??
Thank you very much!! :D
@52AMANTES
ReplyDeleteMake sure you are using the 2.0.0 applicationPreferences.js file and you are including it as one of your script tags.
Hi, Simon,
ReplyDeleteHere I'm again
I don't know if I declared victory too soon, or made something wrong afterwards...
I have this function:
function dime_pref(key,defecto) {
var valor = ''
window.plugins.applicationPreferences.get(key, function(value) {
console.log("El valor de la preferencia "+ key + " es = " + value);
valor = value;
}, function(error) {
console.log(JSON.stringify(error));
valor = defecto;
});
return valor
}
I call it in this way:
var avance = dime_pref('avance','100')
I see that it seems to work properly because the console log shows the proper value. But that value never gets the variable "avance". What may be wrong in what I'm doing?
I can add that I'm getting also a previous error in console.log:
TypeError: Result of expression 'cordova.exec' [undefined] is not a function. And it points at the line:
cordova.exec(success,fail,"applicationPreferences","get",[key]);
As always, thank you very much.
@Rafa
ReplyDeleteYou are trying to call an asynchronous method in a synchronous way. What is happening is that the get method does not execute before you return valor. You'll need to set the value of avance in the success method of the get.
Hi Simon,
ReplyDeleteThanks for your great information regarding the app prefs.
i want to open the application preferences from the ios app. i need more info about how to implement this method,
the last phongap plugin is not updated with the methods of show and load,
i only can use the set/get methods.
can you please tell me additional information?
thanks
@zaherrrr
ReplyDeleteSorry I did not write the iOS plugin. When I was doing the Android version show/load seemed like good additions. You should add them to the iOS plugin and do a pull request.
You give very useful information iphone android application with that useful function. it is very good stuff but
ReplyDeleteI have this function:
function dime_pref(key,defecto) {
var valor = ''
window.plugins.applicationPreferences.get(key, function(value) {
console.log("El valor de la preferencia "+ key + " es = " + value);
valor = value;
}, function(error) {
console.log(JSON.stringify(error));
valor = defecto;
});
@Jack Smith
ReplyDeleteWhat is the question?
Simon, I've been traveling out of town and so far I have not been able to get back in front of the computer, so I don't remember well if I told you that I needed to get preferences values synchronously, because I would use them the page is being constructed (font size, background-color,...)
ReplyDeleteHow should I do it?
Thank you very much in advance.
@Rafa
ReplyDeleteSorry you are going to need to restructure your code to work with the async call. If you need these values for page construction you may want to:
1) Show a splash screen
2) wait for device ready
3) make a call to get the preferences
4) refresh the page with the preference values
5) hide the splash screen
Im new with phonegap and plugin and I try to use the appPreferences plugin but it keep giving me error: Class Not found.
ReplyDeleteIm new with phonegap and plugin and I try to use the appPreferences plugin but it keep giving me error: Class Not found
I even put the in the config.xml folder :S so I don't know what I'm missing to make it work
@Daniel Caymo
ReplyDeleteHey, blogger won't accept xml in the comment so if you could post your manifest.xml and config.xml to a site like pastebin or gist then link back to it I could probably help.
this is the link: http://pastebin.com/Ks2vyUzD
ReplyDeletehttp://pastebin.com/6uJnTpjz
Thx for replying and sorry If i send a lot of msg in the sametime because I don't know if I send it D: srry I'm really new to asking people in blog for help
@Daniel Caymo
ReplyDeleteThe plugin line in your config.xml is wrong. The value of the plugin line should be:
"com.simonmacdonald.prefs.AppPreferences"
i try that alreadybut it still wouldnt.work ;S that why i change it n i thought it wouldnt matter as long it the path where the.file.is.located
ReplyDelete@Daniel Caymo
ReplyDeleteOh, it matters. The plugin line, the location of the file in the src folder and the package line in the the Java class must all match.
ah ok I try changing it tomorrow and see what happen thx you very for fast reply i let u know tomorrow if there any.change
ReplyDeleteI try to make the changes you told me and it still doesn't work and anw this is the whole application it a small one hope you be able to tell me what I'm doing wrong https://github.com/dandan28/test/down
ReplyDeleteThis is my last question when i compile with eclipse through a virtual machine android the plugin works but when I try compiling it with https://build.phonegap.com/
ReplyDeletebuilds the plugin doesn't work
@Daniel Caymo
ReplyDeleteYeah, that is kinda essential information. You realize that PhoneGap Build does not support a ton of plugins and it does not support the AppPreferences plugin.
Hi,sorry I have another question again, when I try loading the ShowPreferenceAll automatically on body onload"ShowPreferenceAll();" it doesn't work?? because I want to show my Application preferences when my app load right away
ReplyDelete@Daniel Caymo
ReplyDeleteThat's because you are not waiting for the deviceready event. You won't be able to call and PhoneGap plugin or core API until after that event is fired. So listen for the event then show preferences.
Thx Simon it work now :D Thx for all those fast reply :D
ReplyDeleteHi Simon,
ReplyDeleteI am using the 2.2.0 version of your application Preference plugin on Cordova 2.2 version but unfortunately I wasn't able to make it work. Though I don't get any error, I can't go through the success and error callback function after calling "get" method. Do I miss something on this? Thanks.
@Jake Monton
ReplyDeleteProbably. What do you see in "adb logcat"?
Hey Simon,
ReplyDeletehow to get rid of the second application icon, which appears when using that plugin ?
BR
Ray
@ramonbln
ReplyDeleteYou should not see two application icons when you use this plugin. I suspect that you have two LAUNCHER items in your AndroidManifest.xml.
Thanks! After removing the second LAUNCHER-entry, which I copied from your tutorial, the second LauncherIcon is gone :)
ReplyDeleteBR
Ray
Hi Simon,
ReplyDeleteIn my previous posts I had sent you links to codebin pastes that seem to be unreliable. As I mentioned before, thanks for your great preference plugin. It is absolutely helpful in my project. So far I have been able to load the preference activity. But when I try the load function I get the error that it is undefined. I was hoping that you would be able to help me correct this. I am uncertain as to how to reference the preference file if that is the problem. I have included links to pastes on pastebin this time hoping that they are more reliable for your viewing. These are the links:
This is the applicationPreference script:
http://pastebin.com/v8JM6HUP
This is the HTML file:
http://pastebin.com/2RFVZA57
This is the error log after succesfully seen the preferences:
http://pastebin.com/DCeAsgYE
This is the undefined message for the load function:
http://pastebin.com/MCrRC12H
Thanks for your assistance.
Best Regards,
Edward Hanna
hanna.edwardo@gmail.com
@Edwardo Hanna
ReplyDeleteIt is a class cast exception where an Integer is being cast as a String. Try declaring one of your numbers as a string in preferences and it should be okay.
Hi Simon,
ReplyDeleteI got "undefined" result after executing "cordova.exec" at my plugin's javascript file (at "resultTemp" variable).
here is my js file:
(function(cordova){
var DeviceInfo = function() {
};
DeviceInfo.prototype.imeiNumber = function(params, success, fail) {
var resultTemp;
alert("executing ImeiNumber");
resultTemp = cordova.exec(function(args) {
success(args);
}, function(args) {
fail(args);
}, 'DeviceInfo', 'imeiNumber', [params]);
alert(resultTemp);
return resultTemp;
};
DeviceInfo.prototype.phoneNumber = function(params, success, fail) {
return cordova.exec(function(args) {
success(args);
}, function(args) {
fail(args);
}, 'DeviceInfo', 'phoneNumber', [params]);
};
DeviceInfo.prototype.imsi = function(success, fail) {
return cordova.exec(function(args) {
success(args);
}, function(args) {
fail(args);
}, 'DeviceInfo', 'imsi', []);
};
window.deviceInfo = new DeviceInfo();
// backwards compatibility
window.plugins = window.plugins || {};
window.plugins.deviceInfo = window.deviceInfo;
})(window.PhoneGap || window.Cordova || window.cordova);
Here is my Java plugin:
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
public class DeviceInfo extends CordovaPlugin
{
public DeviceInfo()
{
}
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException
{
PluginResult.Status status = PluginResult.Status.ERROR;
String result = "";
if (action.equals("imeiNumber"))
{
status = PluginResult.Status.OK;
result = this.DeviceImeiNumber();
}
callbackContext.sendPluginResult(new PluginResult(status, result));
return true;
}
public String DeviceImeiNumber(){
//TelephonyManager tManager = (TelephonyManager)cordova.getActivity().getSystemService(Context.TELEPHONY_SERVICE);
//return tManager.getDeviceId();
return "Success1";
}
}
and this in my html page, I use this js code to call my plugin:
function onLoad()
{
alert("I've been loaded");
document.addEventListener("deviceready", onDeviceReady, true);
}
function onDeviceReady()
{
window.plugins.deviceInfo.imeiNumber(function(imei) {
if(imei !== "")
{
alert("success, IMEI: " + imei);
}
else
{
alert("Failed :(");
}
});
Am I doing something wrong?
Many thanks before :)
@Unknown
ReplyDeleteYeah, if you are using a later version of PhoneGap you need to do a require in order to pull in the exec module. Check out:
https://git-wip-us.apache.org/repos/asf?p=cordova-plugin-camera.git;a=blob;f=www/Camera.js;h=b2da5da95bfe5755cab4ef1029745467ae9140d5;hb=HEAD
for an example. Also, don't expect cordova.exec to return you anything useful. Use the success and failure callbacks.
I might be a bit thick, but where do we create the class that extends PreferenceActivity from step #4. I'm using Icenium if that makes a difference. I though the purpose of a plugin is to save you from writing native code. Your .java file already contains the native code, so where do I extend PreferenceActivity?
ReplyDelete@David Silveria
ReplyDeleteFollow the link earlier in the blog post "go read this tutorial" to learn how to setup the Java side.
are there any plans to get this working with the cloud build system ?
ReplyDeleteI did read the article, but the part I do not get is where to place that code, it is never said in plain text in the article. I can only use native code in the plugins folder, which I thought already contains all needed code for the plugin.
ReplyDelete@Classified
ReplyDeleteI don't have time to work on it right now but I will gladly take pull request to my repo that provide that support. Someday I will have time to revisit all of my plugins.
@David Silveria
ReplyDeleteIt is up to you where you put the code. It all depends on what the package name of your app is. For instance if I create the class SimonsPrefs and it is in the package com.simonmacdonald I should put the code in src/com/simonmacdonald/SimonsPrefs.java