Intent extras only work on some devices - android

In my app I send some intent extras from one activity to another. But some users report back that these data are always zero - even though I can see the values are alright in the sending activity.
Here's the code of the sending activity:
Intent intent = new Intent();
intent.setClass(waypointListView.this, addWaypointActivity.class);
intent.putExtra("latitude", String.format("%9.6f", globLatitude));
intent.putExtra("longitude", String.format("%9.6f", globLongitude));
startActivityForResult(intent, ACTIVITY_ADD_WAYPOINT);
And this is how it's read in the new activity:
Intent myIntent = getIntent();
String latitudeStr = myIntent.getExtras().getString("latitude");
try{
globLatitude = Float.parseFloat(latitudeStr);
} catch(NumberFormatException nfe) {
globLatitude=0f;
}
String longitudeStr = myIntent.getExtras().getString("longitude");
try{
globLongitude = Float.parseFloat(longitudeStr);
} catch(NumberFormatException nfe) {
globLongitude=0f;
}
On both my devices it works fine, but I have 3 cases of customers complaining that it doesn't work (documented in video recordings).
Any suggestions?

I tried to change the code to use getFloatExtra() instead of getString and parse it to a float, and it solved the problem. I see this is a lot more efficient, but I still don't understand why the original solution worked on some devices but not on others.
Case closed!

Related

Android - Scandit Barcode Scanner issues with EAN-13

I implemented the scandit library in my google glass project, but if I'm scanning EAN-13 barcodes the last digit is always wrong.
For example: I'm scanning a code with the value 2220141633626 and the result is 2220141633624.
This is my code in Activity 1:
public void didScanBarcode(String content, String format) {
// send the result to another activity.
Intent resultIntent = new Intent(this, TestingActivity.class);
resultIntent.putExtra("scanContent", content);
Log.v("scanbarcode", content);
startActivity(resultIntent);
}
This is my code in Activity 2:
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.testing);
Intent resultIntent = getIntent();
String scanContent = resultIntent.getExtras().getString("scanContent");
serialNumber = Long.parseLong(scanContent);
Log.e("string ", "" + scanContent);
Log.e("long ", "" + serialNumber);
}
The content is already wrong in the didScanBarcode method of my first activity.
2220141633626 is not a valid EAN-13 code, while 2220141633624 is.
The first 12 numbers are the actual number, while the 13th is the 'check digit'. The check digit of 222014163362 is 4.
See for example http://www.morovia.com/education/utility/upc-ean.asp, enter 222014163362 in the ean-13 field and press 'calculate'

PhoneGap Barcode Scanner Issue

I am developing an application in cordova but my barcode scanner from Zxing opens and closes Automatically after scanning the product in need to add a scan/exit button and a close button the scanner shouldnt open and close automatically. I also need to check if the scanned product exist in the database (SQL SERVER) and return product infomation i have tried to google but to no avail please help.the following is my code in Eclipse. I need to know how i can modify The UI and add my own control of my ZXING barcode scanner plugin i am developing in Eclipse and have a web api service hosted in IIS which i can access on my android App.Please ASAP or show me how i can modify this barcode UI to ADD my controls.
public void scan() {
Intent intentScan = new Intent(SCAN_INTENT);
intentScan.addCategory(Intent.CATEGORY_DEFAULT);
this.cordova.startActivityForResult((CordovaPlugin) this, intentScan, REQUEST_CODE);
}
My OnStartActivity code is here is the code but it seems like it is the same as yours.
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
JSONObject obj = new JSONObject();
try {
obj.put(TEXT, intent.getStringExtra("SCAN_RESULT"));
obj.put(FORMAT, intent.getStringExtra("SCAN_RESULT_FORMAT"));
obj.put(CANCELLED, false);
} catch (JSONException e) {
Log.d(LOG_TAG, "This should never happen");
}
//this.success(new PluginResult(PluginResult.Status.OK, obj), this.callback);
this.callbackContext.success(obj);
} else if (resultCode == Activity.RESULT_CANCELED) {
JSONObject obj = new JSONObject();
try {
obj.put(TEXT, "");
obj.put(FORMAT, "");
obj.put(CANCELLED, true);
} catch (JSONException e) {
Log.d(LOG_TAG, "This should never happen");
}
//this.success(new PluginResult(PluginResult.Status.OK, obj), this.callback);
this.callbackContext.success(obj);
} else {
//this.error(new PluginResult(PluginResult.Status.ERROR), this.callback);
this.callbackContext.error("Unexpected error");
}
}
}
Good Afternoon I have an app that do what you are looking for... first of all I create an intent so i can use any QR scanner I use an external app in order to get the value of the QR code here.
public void scanNow(View view) {
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("com.google.zxing.client.android.SCAN.SCAN_MODE", "QR_CODE_MODE");
startActivityForResult(intent, 0);
}
so in my onStartActivity for result send that info to the server side and I wait for the answer...
public void onActivityResult(int requestCode, int resultCode, Intent intent){
if(requestCode == 0){
if(resultCode == RESULT_OK){
contents = intent.getStringExtra("SCAN_RESULT");// here is the content of the qr scanner
String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
String messLoc = "Visita Guardada Con Exito";
Log.i("xZing", "contents: " + contents + " format: " + format);// Handle successful scan
Toast.makeText(this, messLoc, Toast.LENGTH_LONG).show();
new Thread(new Task()).start(); // here I start the thread for the connection
return;
}
else if(resultCode == RESULT_CANCELED);{// Handle cancel
Log.i("xZing", "Cancelled");
}
}
}
Please let me know if this help you
UPDATE:
I just started using Zbar instead Zxing. It's a whole lot easier to work with. Extremely easy to embed (no 3rd party app for the scanner). It has a lot let file to load into the project. Also, it has an included example that you can pretty much copy and paste into your code. The example is perfect for what you are trying to do and would only require a few edits to gain the functions you are looking for. So try using the zbar library.
Zbar - https://github.com/dm77/ZBarScanner
A tutorial - http://community.magicsoftware.com/en/library?book=en/Magicxpa/&page=Android_Barcode_Scanning_(Using_ZBar_SDK)_Sample.htm
The tutorial isn't that good but it helps with setting it up. NOTE: the links they have don't work if you click them..you have to copy and paste the text into your browser.
The database stuff I explained below still is relevant but ignore the parts about zxing.
Best of luck to you!
Original answer
I may be able to help somewhat for you SQL issues. Do you have any database helper set up?
First off I would google around and find a simply database example to set up the database. There are a number of good ones out there that show you how to set up a database in SQLite for android. The one I used to learn some of the basics:http://hmkcode.com/android-simple-sqlite-database-tutorial/ . You can use the example of Book to create a product class with all the values for columns that match your needs. Then you simply create automatic getters and setters with eclipse click "Source -> generate getters and setters". Onces you've done that you can use the tutorial below to set up your qr scanner. As for keeping the window open, I don't think you need to do that. Just create an activity that the scanner closes into. In that acticity you can have the output and have the scan results compared to the database.
I was able to use the tutorial http://%20http://code.tutsplus.com/tutorials/android-sdk-create-a-barcode-reader--mobile-17162 to integrate zxing into my app. Once I did that
An example of parsing the data from the qr code:
First you call the scan:
public void onClick(View v){
//respond to clicks
if(v.getId()==R.id.scanQRButton){
//scan
IntentIntegrator scanIntegrator = new IntentIntegrator(this);
scanIntegrator.initiateScan();
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
startActivityForResult(intent, 0);
The scan results code then looks like this:
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
//retrieve scan result
IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
if (scanningResult != null) {
//we have a result
scanContent = scanningResult.getContents();
}
else{
Toast toast = Toast.makeText(getApplicationContext(),
"No scan data received!", Toast.LENGTH_SHORT);
toast.show();
}
}
Now the finishing method for the scan button:
public void onClick(View v){
//respond to clicks
if(v.getId()==R.id.scanQRButton){
//scan
IntentIntegrator scanIntegrator = new IntentIntegrator(this);
scanIntegrator.initiateScan();
Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
startActivityForResult(intent, 0);
formatTxt.setText( "Scan Initiated");
contentTxt.setText(" Scan Results: " + scanContent);
if(scanContent != null){
String userid,medname,tabstaken,dob;
// Here I am breaking apart the scan results and
//saving them into variables.
//Do this then call the database for your product and compare
StringTokenizer st = new StringTokenizer(scanContent, ",");
// token 0
dob = st.nextToken();
//token 1
medname = st.nextToken();
//token 2
tabstaken = st.nextToken();
//token 3
//rxnumber
// So here you setup the db so you can access it
DatabaseHandler db = new DatabaseHandler(getApplicationContext());
//This is used to call the results
HashMap<String,String> user = new HashMap<String, String>();
//Use a method such as getProductResults() for your case
user = db.getUserDetails();
enter code here
//An example of me storing the user
userid = user.get("uid");
//debug.setText("Userid: "+ userid+ " medname: " + medname + " tabs: " +tabstaken);
UserLogEntry userlog = new UserLogEntry(getApplicationContext(),userid,medname,tabstaken);
userlog.addUserLog();
}
}
}
If you need to see my database class let me know. Obviously this isn't the exact code you need, but it shows you how to use the results from the QR and call the DB results to do comparisons. Hopefully its helpful

Pass an Exception as a Parcel

I am trying to pass an exception to an activity meant to dump the relevant information to the screen.
Currently I pass it through a bundle:
try {
this.listPackageActivities();
} catch (Exception e) {
Intent intent = new Intent().setClass(this, ExceptionActivity.class).putExtra("Exception", e);
startActivity(intent);
}
But when it gets there:
if (!(this.bundle.getParcelable("Exception") != null))
throw new IndexOutOfBoundsException("Index \"Exception\" does not exist in the parcel." + "/n"
+ "Keys: " + this.bundle.keySet().toString());
This sweet exception is thrown but when I look at the keySet and the bundle details it tells me that there is one parcelable object with a key named "Exception".
I understand that this has something to do with types but I do not understand what I am doing wrong. I just want to dump information about an exception, any exception to the screen. Is there a way to do that without having to condense all the information into a string every time?
I stumbled on this question when I was searching for a method to pass exceptions from a service to an activity. However, I found a better method, you can use the putSerializable() method of the Bundle class.
To add:
Throwable exception = new RuntimeException("Exception");
Bundle extras = new Bundle();
extras.putSerializable("exception", (Serializable) exception);
Intent intent = new Intent();
intent.putExtras(extras);
To retrieve:
Bundle extras = intent.getExtras();
Throwable exception = (Throwable) extras.getSerializable("exception");
String message = exception.getMessage();
The class Exception doesn't implement the Parcelable interface. Unless android is breaking some fundamental Java constructs of which I'm unaware, this means you can't put an Exception as a Parcel into a Bundle.
If you want to "pass" the execption to a new Activity, just bundle up the aspects of it that you're going to need in your new Activity. For example, let's say you just want to pass along the exception message and the stacktrace. You'd so something like this:
Intent intent = new Intent().setClass(this,ExceptionActivity.class)
intent.putExtra("exception message", e.getMessage());
intent.putExtra("exception stacktrace", getStackTraceArray(e));
startActivity(intent);
where getStackTraceArray looks like this:
private static String[] getStackTraceArray(Exception e){
StackTraceElement[] stackTraceElements = e.getStackTrace();
String[] stackTracelines = new String[stackTraceElements.length];
int i =0;
for(StackTraceElement se : stackTraceElements){
stackTraceLines[i++] = se.toString();
}
return stackTraceLines;
}

problem in comparing two Strings in android

in my app i have two editbox in which the user types the email and password. The values are send to an URL and if the return values is success i am moving to a new activity, else if the return value is Email And Password Not Match! i want to show an alert box that emailand pwd mismatches.
For this, after getting the xml file from the network using sax parser i am doing parsing the and if the return value is "Email And Password Not Match!", i am storing this in a constant names as ERROR_VALUE.
i have already stored the value in a String constant as follows
public static String ERROR_CONST = "Email And Password Not Match!";
now i am comparing those values and showing an alert box,
if (ERROR_CONST.contentEquals(ERROR_VALUE))
{
alertbox();
}
after this i am using the else part to move to a new activity, my app gets crashed at this part only
else if(ERROR_VALUE == null)
{
Intent myIntent = new Intent(getBaseContext(), Add.class);
startActivityForResult(myIntent, 0);
finish();
}
}
how to use else condition successfully in my app, please help me friends
Well when comparing 2 strings its always a good idea to use
s1.compareToIgnoreCase(s2);
reading your post I would suggest you use enum or constants
public static final ERROR_CODE_INVALIDE_LOGGIN = 1;
to compare rather that strings.
Comparing strings is tedious (have to be careful that your comparing the characters and not references etc.). As comparing 2 int is easy and takes less time
I checked quickly in the javaDoc
contentEquals compares your String to a StringBuffer
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#contentEquals(java.lang.StringBuffer)
as
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#compareTo(java.lang.String)
Compares the actual string letters
other edit (sorry about that)
if your code is
if (ERROR_CONST.contentEquals(ERROR_VALUE))
{
alertbox();
}
else if(ERROR_VALUE == null)
{
Intent myIntent = new Intent(getBaseContext(), Add.class);
startActivityForResult(myIntent, 0);
finish();
}
then you have a problem when ERROR_VALUE is == null.
you pass null in contentequals and I'm guessing Java tries to convert null to StringBuffer and crashes.
what you want to do it
if(ERROR_VALUE == null)
{
Intent myIntent = new Intent(getBaseContext(), Add.class);
startActivityForResult(myIntent, 0);
finish();
}else if (ERROR_CONST. equalsIgnoreCase(ERROR_VALUE))
{
alertbox();
}
this way you avoid any null pointer exceptions and your compare will work just fine

Intent for app details page

My app relies heavily on a database for data and sometimes the database won't copy correctly, gets corrupted, or just throws a generic strop. Clearing the app data and then reopening the app seems to work well, but it's quite a chore to ask my users to dig through the settings pages, and I'm looking for a way to quickly get to the app details page (which shows the uninstall, move to SD, clear data etc.)
I've found the Settings.ACTION_APPLICATION_DETAILS_SETTINGS Intent action but get an ActivityNotFoundException when I try to launch it as described on my Desire Z. Can anyone help me out how to properly sort this?
Thanks
EDIT: As noted in the answers, this is only API9 and above, the code I now use if anyone wants it is below. Believe it works on API3 and above.
try {
Intent i = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("package:com.espian.formulae"));
startActivity(i);
} catch (ActivityNotFoundException ex) {
Intent i = new Intent(android.provider.Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(i);
}
I know that this is way too late answer but it may help someone. Based on the platform (froyo) source I make one function that opens a specific package's settings page. It works in the emulator but I never tried on a real device. I don't know if it works on API < 8 either.
Here it is:
public boolean startFroyoInstalledAppDetailsActivity(String packagename) {
boolean result = false;
Intent i = new Intent();
i.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails");
i.setAction(Intent.ACTION_VIEW);
i.putExtra("pkg", packagename);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
cx.startActivity(i);
result = true;
} catch (Exception ex) {
result = false;
}
return result;
}
Based on your code I also make a Gingerbread version which works on real devices with API levels 9, 10, 11, 12, 13, 14 and 15 but it can be called safely from API 8 however in this case it will return false.
Here it is:
public boolean startGingerbreadInstalledAppDetailsActivity(String packagename) {
boolean result = false;
Intent i = new Intent();
i.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("package:" + packagename));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
cx.startActivity(i);
result = true;
} catch (Exception ex) {
result = false;
}
return result;
}
I'll post it as answer here in addition to my comment. That intent is only available as of API Level 9 (2.3). The Desire Z doesn't have 2.3... yet. ;)

Categories

Resources