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
Related
I'm trying to pick pictures files and copy them to app local folder, and save path as string in database to display images, the code works fine on UWP but does not on Android (I'm using Uno Platform):
string SImag = string.Empty;
private async Task<string> MediaxPicAsync()
{
Windows.Storage.Pickers.FileOpenPicker openPicker = new Windows.Storage.Pickers.FileOpenPicker();
openPicker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
openPicker.FileTypeFilter.Add(".bmp");
openPicker.FileTypeFilter.Add(".gif");
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".jpeg");
openPicker.FileTypeFilter.Add(".png");
Windows.Storage.StorageFile file = await openPicker.PickSingleFileAsync();
if (file != null)
{
try
{
Windows.Storage.StorageFile temp = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync("TempFile." + file.FileType);
await file.CopyAndReplaceAsync(temp);
return temp.Path;
}
catch (Exception ex)
{
await new Windows.UI.Popups.MessageDialog("Could not open image!", "Error image loading").ShowAsync();;
}
}
return string.Empty;
}
Xaml Code:
<Image>
<Image.Source>
<BitmapImage UriSource="{x:Bind SImag, Mode=OneWay,Converter={StaticResource appClsConvStr2Imag}}" />
</Image.Source>
</Image>
Converter:
public class ClsConvStr2Imag : Windows.UI.Xaml.Data.IValueConverter
{
object Windows.UI.Xaml.Data.IValueConverter.Convert(object value, Type targetType, object parameter, string language)
{
if (string.IsNullOrEmpty(value as string))
{
return null;
}
else
{
string sPath = (string)value;
if (sPath.Contains("/") | sPath.Contains("\\"))
{
}
else
{
if (parameter == null)
{
sPath = Windows.Storage.ApplicationData.Current.LocalFolder.Path + "\\" + sPath;
}
else
{
sPath = Windows.Storage.ApplicationData.Current.LocalFolder.Path + "\\" + parameter + "\\" + sPath;
}
}
return new Uri(sPath);
}
}
object Windows.UI.Xaml.Data.IValueConverter.ConvertBack(object value, Type targetType, object parameter, string language)
{
return value;
}
}
On Visual studio output during Android debug it shows error as:
[BitmapFactory] Unable to decode stream: java.io.FileNotFoundException: /data/user/0/Sale.Sale/files/TempFile.png (No such file or directory)
Any help to overcome this issue is most welcome, I did research for 3 days and could not find clean solution for this issue. Many thanks in advance for time and expertise.
I was able to pass a string (a sentence) to Google's NLP API (configured in a separate class called NLPService.java) from my Main Activity Class, but I want to be able to return the result (a certain entity string) from the NLPService Class back to my Main Activity for further processing. Is it possible for me to pass the entities string back to my Main Activity? In Android Studio, I have created a NLPService.java with the following code:
//New NLP Model
public void analyzeText(String textToAnalyze) {
Document doc = new Document();
doc.setContent(textToAnalyze)
.setType("PLAIN_TEXT");
final String[] result = new String[1];
if (textToAnalyze != null && !doc.isEmpty()) {
doc.setContent(textToAnalyze);
//Config request to be sent to Google NLP
Features features = new Features();
features.setExtractEntities(true);
final AnnotateTextRequest request = new AnnotateTextRequest();
request.setDocument(doc);
request.setFeatures(features);
AsyncTask.execute(new Runnable() {
public void run() {
try {
returnResponse(NLPService.documents().annotateText(request).execute());
result[0] = returnResponse(NLPService.documents().annotateText(request).execute());
Log.i("getAsyncResponse", "RESULT: " + result[0]);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
public String returnResponse(AnnotateTextResponse response) {
final List<Entity> entityList = response.getEntities();
String entities = "";
for (Entity entity : entityList) {
entities += "\n" + entity.getName().toUpperCase() + " " + entity.getType();
}
return entities;
}
`
The common approach will be using Broadcast (LocalBroadcastManager) to pass the data you intended to send from service to any activity.
Example of Previous post
Or you can use SharedPreferences which is unlikely.
I have looked many source and question but I am still not clear to how this code of sending email through unity is not working in android build. It works fine in windows build but doesn't work in android. Can someone help me. Here is the code -
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using UnityEngine;
public class EmailUnity
{
public static string SenderEmail;
public static string SenderPassword;
public static string SmtpClient;
public static int SmtpPort;
public static void SendEmail(string to, string subject, string body, bool isHtml, string[] attachmentPaths,
Action<object, AsyncCompletedEventArgs> callback = null)
{
try
{
SmtpClient emailServer = new SmtpClient(SmtpClient, SmtpPort);
emailServer.EnableSsl = true;
emailServer.Credentials = (ICredentialsByHost) new NetworkCredential(SenderEmail, SenderPassword);
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
MailMessage message = new MailMessage(SenderEmail, to);
message.Subject = subject;
message.Body = body;
message.IsBodyHtml = isHtml;
foreach (string path in attachmentPaths)
{
if (!string.IsNullOrEmpty(path) && File.Exists(path))
{
message.Attachments.Add(new Attachment(path));
}
}
if (callback == null)
{
callback = SampleCallback;
}
emailServer.SendCompleted += new SendCompletedEventHandler(callback);
emailServer.SendAsync(message, "");
Debug.Log("Email sending");
}
catch (Exception ex)
{
Debug.Log("Error: " + ex.Message);
callback("", new AsyncCompletedEventArgs(ex, true, "Exception occured"));
}
}
private static void SampleCallback(object sender, AsyncCompletedEventArgs e)
{
if (e.Cancelled || e.Error != null)
{
Debug.Log("Error: " + e.Error.Message);
}
else
{
Debug.Log("Email sent");
}
}
}
These are the things to try if SmtpClient is not working on Android.
Go to File --> Build Settings... --> Select Android. Now, click on Player Settings.
1.On the Internet Access, change it from Auto to Require.
2.Make sure that API Compatible Level is set to .NET 2.0 not .NET 2.0 Subset.
3.Make sure that Stripping Level is set to Disabled.
4.Go to Player settings --> Android and change Internet Access from Auto to Require
I'm using ZXing in an Android app being developed in Xamarin to scan a QR code and start playing the corresponding audio file automatically.
My problem is that when I get a result from scanning, it takes some time for the audio player activity to load so it gets called twice or more due to subsequent successful scannings.
Is there a way to stop continuous scanning as soon as I get a correct result?
Here's the code:
//Start scanning
scanner.ScanContinuously(opt, HandleScanResult);
}
private void HandleScanResult(ZXing.Result result)
{
string msg = "";
if (result != null && !string.IsNullOrEmpty(result.Text))
{
msg = result.Text;
var playerActivity = new Intent(myContext, typeof(AudioActivity));
//-------------------------------------------------------------
// Prerequisite: load all tracks onto "Assets/tracks" folder
// You can put here qr code - track assignments here below
// msg: decoded qr code
// playerActivity.Putextra second parameter is a relative path
// under "Assets" directory
//--------------------------------------------------------------
//Iterate through tracks stored in assets and load their titles into an array
System.String[] trackArray = Application.Context.Assets.List("tracks");
bool trackFound = false;
foreach (string track in trackArray)
{
if (track.Equals(msg + ".mp3"))
{
playerActivity.PutExtra("Track", "tracks/" + msg + ".mp3");
for (int i = 0; i < PostList.postList.Count; i++)
{
if (PostList.postList.ElementAt(i).code.Equals(msg))
playerActivity.PutExtra("TrackTitle", PostList.postList.ElementAt(i).title);
}
myContext.StartActivity(playerActivity);
trackFound = true;
}
}
Thank you!
Old question but i'll post it anyway for anyone still looking for this information.
You need your scanner to be a class variable. This is my code:
public MobileBarcodeScanner scanner = new MobileBarcodeScanner();
private void ArrivalsClick(object sender, EventArgs e)
{
try
{
if (Arrivals.IsEnabled)
{
MobileBarcodeScanningOptions optionsCustom = new MobileBarcodeScanningOptions();
scanner.TopText = "Scan Barcode";
optionsCustom.DelayBetweenContinuousScans = 3000;
scanner.ScanContinuously(optionsCustom, ArrivalResult);
}
}
catch (Exception)
{
throw;
}
}
private async void ArrivalResult(ZXing.Result result)
{
if (result != null && result.Text != "")
{
// Making a call to a REST API
if (resp.StatusCode == System.Net.HttpStatusCode.OK)
{
int? res = JsonConvert.DeserializeObject<int>(resp.Content);
if (res == 0)
{
scanner.Cancel(); // <----- Stops scanner (Something went wrong)
Device.BeginInvokeOnMainThread(async () =>
{
await DisplayAlert("..", "..", "ΟΚ");
});
}
else
{
Plugin.SimpleAudioPlayer.ISimpleAudioPlayer player = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current;
player.Load("beep.wav");
player.Play(); // Scan successful
}
}
else
{
scanner.Cancel();
Device.BeginInvokeOnMainThread(async () =>
{
await DisplayAlert("..", "..", "ΟΚ");
});
}
}
}
I developed an Android PhoneGap Plugin. The plugin is successfully getting called, but the callback is not getting invoked. I have no idea where I have missed anything.
Does anybody have any idea as to what could be wrong when the callback are not getting invoked?
Following is my code:
JS File Contents:
var SharedPreferencePlugin = function() {};
SharedPreferencePlugin.prototype.getvalues = function(content, success, fail) {
return PhoneGap.exec(
function(args) {
console.log("success called from plugin's js file");
},
function(args) {
console.log("failure called from plugin's js file");
},
'SharedPreferencePlugin',
'getvalues',
[content]
);
};
SharedPreferencePlugin.prototype.update = function(itemName, success, fail) {
return PhoneGap.exec(
function(args) {
console.log("success called from plugin's js file");
},
function(args) {
console.log("failure called from plugin's js file");
},
'SharedPreferencePlugin',
'update',
[itemName]
);
};
PhoneGap.addConstructor(function() {
PhoneGap.addPlugin('SharedPreferencePlugin', new SharedPreferencePlugin());
});
Java file:
public class SharedPreferencePlugin extends Plugin{
public static final String GET_ACTION = "getvalues";
public static final String UPDATE_ACTION = "update";
static Context staticContext = MainActivity.staticContext;
SharedPreferences dataStorage = staticContext.getSharedPreferences(MainActivity.PREFS_NAME, 0);
public PluginResult execute(String action, JSONArray data, String callbackId)
{
Log.d("SharedPreferencePlugin", "Plugin Called with action: " + action);
PluginResult result = null;
if(action.equals(GET_ACTION))
{
Log.d("SharedPrferencePlugin", "inside if for 'getvalues'");
JSONArray savedData = getPreferences();
Log.d("SharedPreferencePlugin", "Data: " + savedData);
result = new PluginResult(Status.OK, savedData);
}
else if(action.equals(UPDATE_ACTION))
{
try
{
updateSharedPreferences(data.getJSONObject(0).getString("itemName"));
JSONObject jsonObject = new JSONObject();
jsonObject.put("status", "success");
result = new PluginResult(PluginResult.Status.OK, jsonObject);
}
catch(JSONException ex)
{
Log.d("SharedPreferencePlugin", "Got JSONException: " + ex.getMessage());
result = new PluginResult(PluginResult.Status.JSON_EXCEPTION);
}
}
else
{
result = new PluginResult(PluginResult.Status.JSON_EXCEPTION);
Log.d("SharedPreferencePlugin", "Invalid action: " + action + " obtained.");
}
return result;
}
public void updateSharedPreferences(String itemName)
{
Log.d("SharedPreferencePlugin", "Inside updateSharedPreferences, value passed: " + itemName);
SharedPreferences tmpPreferenceReference = staticContext.getSharedPreferences(MainActivity.PREFS_NAME, 0);
SharedPreferences.Editor editor = tmpPreferenceReference.edit();
if(itemName.equals(tmpPreferenceReference.getString(MainActivity.NAME_ITEM1, "")))
{
Integer tmpInt = Integer.parseInt(tmpPreferenceReference.getString(MainActivity.QUANTITY_ITEM1, "0")) - 1;
editor.putString(MainActivity.QUANTITY_ITEM1, tmpInt.toString());
}
editor.commit();
}
protected JSONArray getPreferences()
{
ArrayList<String> arrItemNames = new ArrayList<String>();
ArrayList<String> arrItemQuantities = new ArrayList<String>();
arrItemNames.add(0, dataStorage.getString(MainActivity.NAME_ITEM1, ""));
arrItemNames.add(1, dataStorage.getString(MainActivity.NAME_ITEM2, ""));
arrItemQuantities.add(0, dataStorage.getString(MainActivity.QUANTITY_ITEM1, ""));
arrItemQuantities.add(0, dataStorage.getString(MainActivity.QUANTITY_ITEM2, ""));
//-------------------------------------------------------------------
ArrayList<ArrayList> tempArrayList = new ArrayList<ArrayList>();
tempArrayList.add(arrItemNames);
tempArrayList.add(arrItemQuantities);
JSONArray jsonData = new JSONArray(tempArrayList);
//-------------------------------------------------------------------
return jsonData;
}
}
HTML CODE TO CALL THE PLUGIN:
function test()
{
console.log("Test called");
window.plugins.SharedPreferencePlugin.getvalues({},
function() { // Success function
console.log("success called");
},
function() { // Failure function
console.log('Share failed');
}
);
}
Any help is highly appreciated.
Thanks.
When you say it is definitely running the native code, how do you know this? Are you seeing the Log.d's or are you actually putting a break point in and stepping through and seeing if the return result; line is being executed?
Also, which version of phonegap are you using?
If you are using PhoneGap 1.2 you should remove the line:
PluginManager.addService("SharedPreferencePlugin","com.devapps.mmvspinningwheel.SharedPreferencePlugin");
as it is not required. Also, you should probably move PhoneGap.addConstructor() to the bottom of your .js file.
Dean is not wrong as there are some devices like the HTC that console.log does not work properly on, as well what version of Android are you testing with?
Thank you guys for your answers.
Since the problem was not getting solved, I recreated a new Test project and went step by step to ensure that each little piece of code works properly and slowly moved to the desired goal for the plugin.
I finally got it working with the new project I created and writing the Plugin again from scratch.
Thanks.