Ajax requests not working on particular Android SDK - android

I have a Phonegap/Jquery mobile app that i am trying to wrap for Android, but the target SDK I am using is not allowing Ajax/Cross-domain requests.
In short, the requests work fine with Android 4.0.3 (API 15), the most current, but not for Android 2.3.3 ( API 10), which is what i need to be compatible for a Galaxy Tablet.
I am having a hard time debugging this as I can't see the actual error since I am wrapped in phonegap and cant user Firebug/Chrome web tools. and I haven't had any luck over at developer.android.com.
I have tried the steps located at http://jquerymobile.com/test/docs/pages/phonegap.html, including
$.mobile.allowCrossDomainPages = true;
$.support.cors = true.
This didn't work either.
Can anyone help me out, I don't know what else to try.
Thanks!
Here is the a quick example of code. note that it returns success = true but hits the 'Response is not an XML element' error:
return $.soapRequest({
url: url,
namespace: 'testns',
returnJson: false,
shortMethod: 'methodname',
method: 'longmethodname',
params: params || {},
success: function(data) {
if (data && data.documentElement) {
// hits this on Android SDK 15
if (successFn) {
return successFn(data.documentElement);
}
}
else {
// hits this on Android SDK 10
return fail("Response is not an XML element!");
}
},
error: function(str) {
return fail(str);
}

try to write httpConnection with phonegap pluggin. it cound CrossDomain
httpPlugin.java
package com.android.test;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
import org.apache.cordova.api.PluginResult.Status;
import org.json.JSONArray;
import org.json.JSONException;
import android.util.Log;
import com.android.connection.HTTPConnect;
public class HttpPlugin extends Plugin {
public final String ACTION_SEND_MESSAGE = "SendCommand";
private HTTPConnect httpConnect;
public HttpPlugin() {
// TODO Auto-generated constructor stub
httpConnect = new HTTPConnect();
}
#Override
public PluginResult execute(String action, JSONArray arg1, String callbackId) {
PluginResult result = new PluginResult(Status.INVALID_ACTION);
if (action.equals(ACTION_SEND_MESSAGE)) {
try {
String message = arg1.getString(0);
String receiveString = httpConnect.setURL(message);
if(receiveString == null){
//show error result
result = new PluginResult(Status.ERROR,"kakaka");
}else{
Log.v("MAN", "data received");
result = new PluginResult(Status.OK);
}
result = new PluginResult(Status.OK);
} catch (JSONException ex) {
// TODO Auto-generated catch block
result = new PluginResult(Status.JSON_EXCEPTION, ex.getMessage());
}
}
return result;
}
}
plugin.xml file
Httpplugin .js
var Httpplugin = function () {};
Httpplugin.prototype.post = function (message, successCallback, failureCallback) {
// navigator.notification.alert("OMG");
return cordova.exec(successCallback, failureCallback, 'Httpplugin', 'SendCommand', [message]);
};
PhoneGap.addConstructor(function() {
PhoneGap.addPlugin("http", new Httpplugin());
});

Related

Programmatically Auto Accept Incoming Bluetooth Files

I am trying to find a way to have a tablet basically auto-accept/give permission to accept an incoming Bluetooth Share file transferred from a laptop to my Nexus Android device. Since the Android bluetooth system itself does not support this feature, I was wondering if this could be done programmatically using an Android application that listened for the notification and accepted it for me.
MUCH EASIER WAY
If you have a rooted device and use XPosed Framework, your goal can be achieved much easier.
You Need not implement your own bluetooth server nor kill the original BT service, which are very bothering!!!
xposed tutorial link.
Try this code.
import android.util.*;
import de.robv.android.xposed.*;
import de.robv.android.xposed.callbacks.XC_LoadPackage.*;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
public class Tutorial implements IXposedHookLoadPackage
{
private String TAG="TUTORIAL";
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.equals("com.android.bluetooth"))
{
Log.i(TAG,"Not: "+lpparam.packageName);
return;
}
Log.i(TAG,"Yes "+lpparam.packageName);
findAndHookMethod("com.android.bluetooth.opp.BluetoothOppManager", lpparam.classLoader, "isWhitelisted", String.class,new XC_MethodHook() {
#Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Log.v(TAG,"HOOK DONE");
param.setResult(true); /* you can compare the sender address(String) with your computer and determine if you return true or just allow the original method to be called after this returns.*/
}
});
}
}
I tested and it works fine:)
Links
Dropbox link of the auto accepting app
Dropbox link of the project files (zip)
Xposed apk site
Towelroot site to root your phone
Background(Original answer)
As I commented above, you bay be able to, and I tried and succeeded in blocking (though not receiving) with this code.
import android.util.*;
import de.robv.android.xposed.*;
import de.robv.android.xposed.callbacks.XC_LoadPackage.*;
import java.io.*;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
public class Tutorial implements IXposedHookLoadPackage
{
private String TAG="TUTORIAL";
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.equals("com.android.bluetooth"))
{
Log.i(TAG,"Not: "+lpparam.packageName);
return;
}
Log.i(TAG,"Yes "+lpparam.packageName);
findAndHookMethod("com.android.bluetooth.opp.BluetoothOppService", lpparam.classLoader, "startSocketListener", new XC_MethodHook() {
#Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Log.v(TAG,"HOOK DONE");
param.setResult(null);
}
});
}
}
The code above hooks the method startListenerSocket() of com.android.bluetooth.BluetoothOppService and prevents the original method from being called by the line param.setResult(null);
Refer to here to see the full code of com.android.bluetooth.BluetoothOppService.java and you will understand the operation.
And the code you can start from is shown below.
import android.util.*;
import de.robv.android.xposed.*;
import de.robv.android.xposed.callbacks.XC_LoadPackage.*;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
public class Tutorial implements IXposedHookLoadPackage
{
private String TAG="TUTORIAL";
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.equals("com.android.bluetooth"))
{
Log.i(TAG,"Not: "+lpparam.packageName);
return;
}
Log.i(TAG,"Yes "+lpparam.packageName);
findAndHookMethod("com.android.bluetooth.opp.BluetoothOppObexServerSession", lpparam.classLoader, "onPut", new XC_MethodHook() {
#Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Log.v(TAG,"HOOK DONE");
Class c=param.thisObject.getClass();
}
});
}
}
This code hooks the onPut method of com.android.bluetooth. BluetoothOppObexServerSession linked here. I either am newbie to xposed framework but I hope my answer helped.
I had the same issues you asked and partially solved the problem by implementing my custom OBEX server and manually / programmatically(with ps|grep and su kill pid) killing the native BluetoothOppService. But I will either try the idea of hooking and directly executing my code.
And to help you customize OBEX server session I post my implementation below.
#Override
public int onPut(Operation op)
{
if (D)
{
Log.d(TAG, "onPut " + op.toString());
}
HeaderSet request;
String name, mimeType;
Long length;
String extension=null;// type;
int obexResponse = ResponseCodes.OBEX_HTTP_OK;
String destination;
if (mTransport instanceof BluetoothObexTransport)
{
destination = ((BluetoothObexTransport) mTransport).getRemoteAddress();
}
else
{
destination = "FF:FF:FF:00:00:00";
}
boolean isWhitelisted =IsWhitelisted(destination);
try
{
boolean preReject = false;
request = op.getReceivedHeader();
if (V)
{
// Constants.logHeader(request);
}
name = (String) request.getHeader(HeaderSet.NAME);
length = (Long) request.getHeader(HeaderSet.LENGTH);
mimeType = (String) request.getHeader(HeaderSet.TYPE);
if (length == 0)
{
if (D)
{
Log.w(TAG, "length is 0, reject the transfer");
}
preReject = true;
obexResponse = ResponseCodes.OBEX_HTTP_LENGTH_REQUIRED;
}
if (name == null || name.isEmpty())
{
if (D)
{
Log.w(TAG, "name is null or empty, reject the transfer");
}
preReject = true;
obexResponse = ResponseCodes.OBEX_HTTP_BAD_REQUEST;
}
int dotIndex = name.lastIndexOf(".");
if (dotIndex > 0)
{
extension = name.substring(dotIndex + 1).toLowerCase();
}
// Reject policy: anything outside the "white list" plus unspecified
// MIME Types. Also reject everything in the "black list".
// if (!preReject && (mimeType == null || (!isWhitelisted && !Constants.mimeTypeMatches(
// mimeType, Constants.ACCEPTABLE_SHARE_INBOUND_TYPES))
// || Constants.mimeTypeMatches(mimeType,
// Constants.UNACCEPTABLE_SHARE_INBOUND_TYPES))) {
// if (D) {
// Log.w(TAG, "mimeType is null or in unacceptable list, reject the transfer");
// }
// preReject = true;
// obexResponse = ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE;
// }
if (preReject && obexResponse != ResponseCodes.OBEX_HTTP_OK)
{
// some bad implemented client won't send disconnect
return obexResponse;
}
}
catch (IOException e)
{
Log.e(TAG, "get getReceivedHeaders error " + e);
return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
}
int status = receiveFile(destination, name, extension, length, op);
/*
* TODO map status to obex response code
*/
if (status != BluetoothShare.STATUS_SUCCESS)
{
obexResponse = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
}
Log.d(TAG, "MIME TYPE)" + mimeType);
return obexResponse;
}
I just removed some rejecting codes from the original one.
Also to look at my full code please refer to my git repository.
I also thank the contributors to the android project!

Securing Spring RESTful webservice APIs from unautherized access?

I have successfully created a Spring RESTful webservice with different APIs. Now I should protect them from unauthorized access. I followed http://www.beingjavaguys.com/2014/10/spring-security-oauth2-integration.html and the login logic is entirely different from mine. Can someone help me to move on?
Fetch user login request
#RequestMapping(value = "/login", method = RequestMethod.POST)
#ResponseBody
#ResponseStatus(HttpStatus.OK)
public UserResponse login(#RequestBody final UserLoginRequest userRequest) throws ServletException, IOException {
UserResponse userResponse = new UserResponse();
try {
userResponse = accessService.login(userRequest);
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return userResponse;
}
Process user login request
#Transactional
public UserResponse login(UserLoginRequest userRequest) throws SQLException,
ClassNotFoundException, IOException {
UserResponse userResponse = new UserResponse();
int status = 0;
//boolean isExist = loginDao.isUserExist(userRequest.getUsername(), userRequest.getPassword());
User user = loginDao.getUser(userRequest.getEmailID());
if (user != null) {
if (userRequest.getPassword().equals(user.getPassword())) {//Case sensitive password and added to check status
//User exist
if (user.getStatus().equals("1")) {
//Device token check
loginDao.isDeviceTokenExists(userRequest, user.getProfileId());
status = 2;
} else {
status = 3;
}
} else {
status = 4;
}
} else {
status = 1;
}
if (status == 1) {
userResponse.setCode(WeekenterConstants.USER_EMAIL_EXIST_CODE);
userResponse.setMessage("User does not exists.Please Register.");
} else if (status == 2) {
userResponse.setCode(WeekenterConstants.SUCCESS_CODE);
userResponse.setMessage("User login success");
userResponse.setId(user.getProfileId());
} else if (status == 3) {
userResponse.setCode(WeekenterConstants.FAILURE_CODE);
userResponse.setMessage("Your Account is blocked. Please contact Weekenter administrator.");
userResponse.setId(user.getProfileId());
} else if (status == 4) {
userResponse.setCode(WeekenterConstants.FAILURE_CODE);
userResponse.setMessage("Password is wrong.");
userResponse.setId(user.getProfileId());
}
return userResponse;
}
I have API's for fetch countries, userlist etc. Those services should only give data to the Android client once the user is valid. I know the authentication will be processed by using access token. How could I do it in a standard way?
I think you need to have a separate process that will authorize a device for use in your application.
I have worked on an application in which tablets are registered for using an app. The tablet ID is saved in a simple text file that is accessible to the Apache server. Then all REST requests have a special header X_DEVICEID which contains the device ID, and a PHP script used by Apache checks for this ID in the file, and will only give a response if the ID is for a registered device.
The file of allowed device IDs acts as a sort of firewall to block unregistered devices.
You can follow the mentioned tutorial itself by changing the login
logic in your service.define a custom authentication service in your
spring-security.xml.
Typically, a simple Spring Security enabled application would use a
simple user service as the authentication source:
<!--Custom User details service which is provide the user data-->
<bean id="customUserDetailsService"
class="com.yourpackage.CustomUserDetailsService" />
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="customUserDetailsService" />
</authentication-manager>
Your customUserDetailsService should implement UserDetailsService
available in
org.springframework.security.core.userdetails.UserDetailsService
import com.weekenter.www.dao.LoginDao;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
#Service
#Transactional(readOnly = true)
public class CustomUserDetailsService implements UserDetailsService {
#Autowired
private LoginDao loginDao;
public UserDetails loadUserByUsername(String login)
throws UsernameNotFoundException {
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
com.weekenter.www.entity.User user = null;
try {
user = loginDao.getUser(login);//login variable contain your requested username
if (user != null) {
if (user.getStatus().equals("1")) {
enabled = false;
}
} else {
throw new UsernameNotFoundException(login + " Not found !");
}
} catch (Exception ex) {
try {
throw new Exception(ex.getMessage());
} catch (Exception ex1) {
}
}
<!-- Password comparison will happen here -->
return new User(
user.getEmail(),
user.getPassword(),
enabled,
accountNonExpired,
credentialsNonExpired,
accountNonLocked,
getAuthorities()
);
}
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> authList = getGrantedAuthorities(getRoles());
return authList;
}
public List<String> getRoles() {
List<String> roles = new ArrayList<String>();
roles.add("ROLE_APP");
return roles;
}
public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (String role : roles) {
authorities.add(new SimpleGrantedAuthority(role));
}
return authorities;
}
}
And finally in spring-security.xml you can filter protected URL's
like below
<!-- This is where we tells spring security what URL should be protected
and what roles have access to them -->
<http pattern="/api/**" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/api/**" access="ROLE_APP" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>

errors with adding cordova sms plugin in worklight 6.0

Nothing happening on clicking SEND button. Smsplugin.js disappears on building the app from assets/WWW in android environment. I have tried most ways around internet but nothing working.
SmsPlugin.js
var SmsPlugin = function () {};
SmsPlugin.prototype.SendSMS = function (successCallback,failureCallbackphone, phone,message, method) {
return cordova.exec(successCallback, failureCallback, 'SmsPlugin', "SendSMS", [phone, message,method]);
};
cordova.addConstructor(function() {
cordova.addPlugin("SmsPlugin", new SmsPlugin());
});
Main javascript file
function send(){
var myElement = document.getElementById('btnDefaultSMS');
myElement.onclick = function() {
var number = $("#numberTxt").val();
var message = $("#messageTxt").val();
window.SmsPlugin.SendSMS(number , message,
function () {
alert('Message successfully sent to' + contactNumber);
},
function (event) {
alert('Message failed due to:' + event);
}
,"INTENT");
};
}
document.addEventListener("deviceready", send , false);
SmsPlugin.java
package org.apache.cordova.plugin;
import org.json.JSONArray;
import org.json.JSONException;
import android.app.PendingIntent;
import android.content.Intent;
import android.telephony.SmsManager;
import org.apache.cordova.api.CallbackContext;
import org.apache.cordova.api.CordovaPlugin;
import org.apache.cordova.api.PluginResult;
public class SmsPlugin extends CordovaPlugin {
public final String ACTION_SEND_SMS = "SendSMS";
#Override
public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
if (action.equals(ACTION_SEND_SMS)) {
try {
String phoneNumber = args.getString(0);
String message = args.getString(1);
String method = args.getString(2);
if(method.equalsIgnoreCase("INTENT")){
invokeSMSIntent(phoneNumber, message);
callbackContext.sendPluginResult(new PluginResult( PluginResult.Status.NO_RESULT));
} else{
sendSMS(phoneNumber, message);
}
callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK));
return true;
}
catch (JSONException ex) {
callbackContext.sendPluginResult(new PluginResult( PluginResult.Status.JSON_EXCEPTION));
}
}
return false;
}
private void invokeSMSIntent(String phoneNumber, String message) {
Intent sendIntent = new Intent(Intent.ACTION_VIEW);
sendIntent.putExtra("sms_body", message);
sendIntent.setType("vnd.android-dir/mms-sms");
this.cordova.getActivity().startActivity(sendIntent);
}
private void sendSMS(String phoneNumber, String message) {
SmsManager manager = SmsManager.getDefault();
PendingIntent sentIntent = PendingIntent.getActivity(this.cordova.getActivity(), 0, new Intent(), 0);
manager.sendTextMessage(phoneNumber, null, message, sentIntent, null);
}
}
It looks like you are trying to add a plug-in to a pure Cordova application, rather than a Worklight app... Have you read the training materials for using Cordova plug-ins in Worklight?
See my answer to the following question, which details the HowTo. It also fits for "importing" existing plug-ins. The procedure is mostly the same*: IBM Worklight 6.1 - Cordova plug-in not getting executed
*You mention Worklight 6.0 rather than 6.1, so the difference would be in the structure of declaring a plug-in in config.xml; just follow suite like the rest of the plug-in declarations in the file...

How can I detect the Android runtime (Dalvik or ART)?

Google added a new ART runtime with Android 4.4. How can I determine whether ART or Dalvik is the current runtime?
Update
At least, as early as June 2014 Google has released an official documentation on how to correctly verify the current runtime in use:
You can verify which runtime is in use by calling System.getProperty("java.vm.version"). If ART is in use, the property's value is "2.0.0" or higher.
With that, now there is no need to go through reflection and simply check the corresponding system property:
private boolean getIsArtInUse() {
final String vmVersion = System.getProperty("java.vm.version");
return vmVersion != null && vmVersion.startsWith("2");
}
One possible way is to read the respective SystemProperty through reflection.
Sample:
package com.example.getcurrentruntimevalue;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MainActivity extends Activity {
private static final String SELECT_RUNTIME_PROPERTY = "persist.sys.dalvik.vm.lib";
private static final String LIB_DALVIK = "libdvm.so";
private static final String LIB_ART = "libart.so";
private static final String LIB_ART_D = "libartd.so";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView)findViewById(R.id.current_runtime_value);
tv.setText(getCurrentRuntimeValue());
}
private CharSequence getCurrentRuntimeValue() {
try {
Class<?> systemProperties = Class.forName("android.os.SystemProperties");
try {
Method get = systemProperties.getMethod("get",
String.class, String.class);
if (get == null) {
return "WTF?!";
}
try {
final String value = (String)get.invoke(
systemProperties, SELECT_RUNTIME_PROPERTY,
/* Assuming default is */"Dalvik");
if (LIB_DALVIK.equals(value)) {
return "Dalvik";
} else if (LIB_ART.equals(value)) {
return "ART";
} else if (LIB_ART_D.equals(value)) {
return "ART debug build";
}
return value;
} catch (IllegalAccessException e) {
return "IllegalAccessException";
} catch (IllegalArgumentException e) {
return "IllegalArgumentException";
} catch (InvocationTargetException e) {
return "InvocationTargetException";
}
} catch (NoSuchMethodException e) {
return "SystemProperties.get(String key, String def) method is not found";
}
} catch (ClassNotFoundException e) {
return "SystemProperties class is not found";
}
}
}
Hope this helps.
For anyone needing a JNI version:
#include <sys/system_properties.h>
static bool isArtEnabled() {
char buf[PROP_VALUE_MAX] = {};
__system_property_get("persist.sys.dalvik.vm.lib.2", buf);
// This allows libartd.so to be detected as well.
return strncmp("libart", buf, 6) == 0;
}
Or if you want to follow a code path closer to what shoe rat posted,
static bool isArtEnabled(JNIEnv *env)
{
// Per https://developer.android.com/guide/practices/verifying-apps-art.html
// if the result of System.getProperty("java.vm.version") starts with 2,
// ART is enabled.
jclass systemClass = env->FindClass("java/lang/System");
if (systemClass == NULL) {
LOGD("Could not find java.lang.System.");
return false;
}
jmethodID getProperty = env->GetStaticMethodID(systemClass,
"getProperty", "(Ljava/lang/String;)Ljava/lang/String;");
if (getProperty == NULL) {
LOGD("Could not find java.lang.System.getProperty(String).");
return false;
}
jstring propertyName = env->NewStringUTF("java.vm.version");
jstring jversion = (jstring)env->CallStaticObjectMethod(
systemClass, getProperty, propertyName);
if (jversion == NULL) {
LOGD("java.lang.System.getProperty('java.vm.version') did not return a value.");
return false;
}
const char *version = env->GetStringUTFChars(jversion, JNI_FALSE);
// Lets flip that check around to better bullet proof us.
// Consider any version which starts with "1." to be Dalvik,
// and all others to be ART.
bool isArtEnabled = !(strlen(version) < 2 ||
strncmp("1.", version, 2) == 0);
LOGD("Is ART enabled? %d (%s)", isArtEnabled, version);
env->ReleaseStringUTFChars(jversion, version);
return isArtEnabled;
}
The Android docs actually give the following suggestion:
You can verify which runtime is in use by calling System.getProperty("java.vm.version"). If ART is in use, the property's value is "2.0.0" or higher.
This seems accurate on my Nexus 4 w/ ART enabled (running Android 4.4.4). Nexus 5 on Dalvik returned 1.6.0.
A simple solution :
String vm = System.getProperty("java.vm.name") + " " + System.getProperty("java.vm.version");
On my Android 8.0 (API 26) phone, it returns Dalvik 2.1.0 .
I think you should be able to use System.getProperty with java.vm.name as the key.
In the JavaDoc its value is Dalvik, which let's hope it is Art or ART when using that runtime. It's worth a try...
final String vm = VMRuntime.getRuntime().vmLibrary();
and then compare vm with "libdvm.so" or "libart.so" to check if it is Dalvik or ART.
Reference: https://gitorious.org/cyandreamproject/android_frameworks_base/commit/4c3f1e9e30948113b47068152027676172743eb1

How to access database using phone gap

I am new to android phonegap. i am storing and retrieving data using native application. i dont know how to display the retrieved data from native to phonegap(HTML)page.
can anyone pls guide me how to access sqlite with phonegap.?
Thanks in advance.
You need to first create a Android plugin for Phonegap through which you will be able to access the native code and hence the native DB like this
public class SqlitePlugin extends Plugin {
private static final String TAG = "SqlitePlugin";
private static final String CREATE_DB_ACTION = "createDatabase";
private static final String SHOW_DB_VALUES_ACTION = "showValues";
#Override
public PluginResult execute(String action, JSONArray data, String callbackId) {
Log.i(TAG, "Plugin Called");
PluginResult result = null;
if (CREATE_DB_ACTION.equals(action)) {
Log.d(TAG, "CREATE_DB_ACTION");
DB _db = new DB(ctx);
_db.insertValues();
}
else if (SHOW_DB_VALUES_ACTION.equals(action)) {
Log.d(TAG, "SHOW_DB_VALUES_ACTION");
JSONObject DBInfo = null;
try {
DBInfo = getDBValuesListing();
} catch (JSONException e) {
e.printStackTrace();
}
result = new PluginResult(Status.OK, DBInfo);
}
else {
result = new PluginResult(Status.INVALID_ACTION);
Log.d(TAG, "Invalid action : " + action + " passed");
}
return result;
}
}
After that Create a sqlite.js file like this
function SqlitePlugin() {
};
SqlitePlugin.prototype.createDatabase = function(successCallback, failCallback) {
return PhoneGap.exec(successCallback, failCallback, "SqlitePlugin",
"createDatabase", [ null ]);
};
SqlitePlugin.prototype.showValues = function(params, successCallback, failCallback) {
return PhoneGap.exec(successCallback, failCallback, 'SqlitePlugin', 'showValues',
[ params ]);
};
PhoneGap.addConstructor(function() {
PhoneGap.addPlugin("SqlitePlugin", new SqlitePlugin());
});
Import this sqlite.js in your page(index.html) and then finally use the plugin like this
function showValues() {
window.plugins.SqlitePlugin.showValues('showValues',
showValuesSuccessCallBack, showValuesFailCallBack);
}
function showValuesSuccessCallBack(e) {
if (e.Rows.length > 0) {
alert("Success");
for (i = 0; i < e.Rows.length; i++) {
alert("Id = " + e.Rows[i].id);
alert("Number = " + e.Rows[i].number);
}
} else {
alert("No values in Database");
}
}
function showValuesFailCallBack(f) {
alert("Failure");
}
Let me know if this worked out for you
Write an phonegap plugin to pass the data from native side to html (js)
http://wiki.phonegap.com/w/page/36753494/How%20to%20Create%20a%20PhoneGap%20Plugin%20for%20Android
Well, you probably should use the HTML5 functions to store and retrieve data from a sqlite DB. However, if you are set on doing it with native code you should look at our implementation which was used for older Android devices that don't support sqlite.
https://github.com/cordova/cordova-android/blob/master/framework/assets/js/storage.js
https://github.com/cordova/cordova-android/blob/master/framework/src/com/phonegap/Storage.java

Categories

Resources