DWA2112 DWA2112 - 3 months ago 20
Java Question

Update of SQLite database results in error

I am new to Android and working on an app, that should retrieve data from the camera and store it into an SQlite database. Unfortunately, the database update is not working, so any hints or comments would be appreciated.

Here is the code:

package de.die_web_agenten.www.runinstant;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ListAdapter;
import android.widget.SimpleCursorAdapter;

import de.die_web_agenten.www.runinstant.db.TaskContract;
import de.die_web_agenten.www.runinstant.db.TaskDBHelper;


public class AndroidBarcodeQrExample extends Activity {
/** Called when the activity is first created. */

static final String ACTION_SCAN = "com.google.zxing.client.android.SCAN";
private ListAdapter listAdapter;
private TaskDBHelper helper;


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_barcode);
}

public void scanBar(View v) {
try {
Intent intent = new Intent(ACTION_SCAN);
intent.putExtra("SCAN_MODE", "PRODUCT_MODE");
startActivityForResult(intent, 0);
} catch (ActivityNotFoundException anfe) {
showDialog(AndroidBarcodeQrExample.this, "No Scanner Found", "Download a scanner code activity?", "Yes", "No").show();
}
}

public void scanQR(View v) {
try {
Intent intent = new Intent(ACTION_SCAN);
intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
startActivityForResult(intent, 0);
} catch (ActivityNotFoundException anfe) {
showDialog(AndroidBarcodeQrExample.this, "No Scanner Found", "Download a scanner code activity?", "Yes", "No").show();
}
}

private static AlertDialog showDialog(final Activity act, CharSequence title, CharSequence message, CharSequence buttonYes, CharSequence buttonNo) {
AlertDialog.Builder downloadDialog = new AlertDialog.Builder(act);
downloadDialog.setTitle(title);
downloadDialog.setMessage(message);
downloadDialog.setPositiveButton(buttonYes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
Uri uri = Uri.parse("market://search?q=pname:" + "com.google.zxing.client.android");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
try {
act.startActivity(intent);
} catch (ActivityNotFoundException anfe) {

}
}
});
downloadDialog.setNegativeButton(buttonNo, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int i) {
}
});
return downloadDialog.show();
}

private void updateUI() {
helper = new TaskDBHelper(AndroidBarcodeQrExample.this);
SQLiteDatabase sqlDB = helper.getReadableDatabase();
Cursor cursor = sqlDB.query(TaskContract.TABLE,
new String[]{ TaskContract.Columns.SCAN_RESULT, TaskContract.Columns.SCAN_RESULT_FORMAT,TaskContract.Columns._id,
TaskContract.Columns.DATE},
null, null, null, null, null
);


listAdapter = new SimpleCursorAdapter(
this,
R.layout.task_view,
cursor,
new String[]{TaskContract.Columns.SCAN_RESULT_FORMAT, TaskContract.Columns.SCAN_RESULT, TaskContract.Columns._id},
new int[]{R.id.taskTextView},
0
);

this.setListAdapter(listAdapter);

}

public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == 0) {
if (resultCode == RESULT_OK) {
String contents = intent.getStringExtra("SCAN_RESULT");
String format = intent.getStringExtra("SCAN_RESULT_FORMAT");
helper = new TaskDBHelper(AndroidBarcodeQrExample.this);
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
//values.clear();
values.put(TaskContract.Columns.SCAN_RESULT, contents);
values.put(TaskContract.Columns.SCAN_RESULT_FORMAT, format);
db.insertWithOnConflict(TaskContract.TABLE, null, values, SQLiteDatabase.CONFLICT_IGNORE);
//Toast toast = Toast.makeText(this, "Content:" + contents + " Format:" + format, Toast.LENGTH_LONG);
//toast.show();
/*Intent SecondIntent = new Intent(AndroidBarcodeQrExample.this, SecondListActivity.class);
SecondIntent.putExtra("SCAN_RESULT", contents);
startActivity(SecondIntent);*/
//Intent SecondIntent = new Intent(getBaseContext(), SecondListActivity.class);
//intent.putExtra("SCAN_RESULT", contents);
//intent.putExtra("SCAN_RESULT_FORMAT", format);
//Intent i = new Intent(this, SecondListActivity.class);
//startActivityForResult(i, 1);
//startActivity(SecondIntent);
Log.d("ADebugTag", "Value: " + (contents));
Log.d("BDebugTag", "Value: " + (format));
//updateUI();

//Context context = getApplicationContext();
//CharSequence text = "Informationen erfolgreich gespeichert!";
//int duration = Toast.LENGTH_SHORT;
//Toast toast = Toast.makeText(context, text, duration);
}

}

}

public void setListAdapter(ListAdapter listAdapter) {
this.listAdapter = listAdapter;
}

}


Here´s the TaskDBHelper class:

package de.die_web_agenten.www.runinstant.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;


public class TaskDBHelper extends SQLiteOpenHelper {

public TaskDBHelper(Context context) {
super(context, TaskContract.DB_NAME, null, TaskContract.DB_VERSION);
}

@Override
public void onCreate(SQLiteDatabase sqlDB) {
String sqlQuery =
String.format("CREATE TABLE %s (" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"%s TEXT, %s TEXT, %s TEXT, %s TEXT, %s TEXT)",
TaskContract.TABLE,
TaskContract.Columns.SCAN_RESULT,
TaskContract.Columns.SCAN_RESULT_FORMAT

);
Log.d("TaskDBHelper", "Query to form table: " + sqlQuery);
sqlDB.execSQL(sqlQuery);
}

@Override
public void onUpgrade(SQLiteDatabase sqlDB, int i, int i2) {
sqlDB.execSQL("DROP TABLE IF EXISTS "+TaskContract.TABLE);
onCreate(sqlDB);
}
}


Here´s the logcat:

08-15 14:07:23.451 1363-1363/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: de.die_web_agenten.www.runinstant, PID: 1363
java.lang.RuntimeException: Unable to resume activity {de.die_web_agenten.www.runinstant/de.die_web_agenten.www.runinstant.AndroidBarcodeQrExample}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { act=com.google.zxing.client.android.SCAN flg=0x80000 (has extras) }} to activity {de.die_web_agenten.www.runinstant/de.die_web_agenten.www.runinstant.AndroidBarcodeQrExample}: java.util.MissingFormatArgumentException: Format specifier: s
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3409)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3440)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2774)
at android.app.ActivityThread.access$900(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1430)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5910)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { act=com.google.zxing.client.android.SCAN flg=0x80000 (has extras) }} to activity {de.die_web_agenten.www.runinstant/de.die_web_agenten.www.runinstant.AndroidBarcodeQrExample}: java.util.MissingFormatArgumentException: Format specifier: s
at android.app.ActivityThread.deliverResults(ActivityThread.java:4005)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3395)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3440) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2774) 
at android.app.ActivityThread.access$900(ActivityThread.java:177) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1430) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:135) 
at android.app.ActivityThread.main(ActivityThread.java:5910) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200) 
Caused by: java.util.MissingFormatArgumentException: Format specifier: s
at java.util.Formatter.getArgument(Formatter.java:1111)
at java.util.Formatter.doFormat(Formatter.java:1076)
at java.util.Formatter.format(Formatter.java:1042)
at java.util.Formatter.format(Formatter.java:1011)
at java.lang.String.format(String.java:1803)
at java.lang.String.format(String.java:1777)
at de.die_web_agenten.www.runinstant.db.TaskDBHelper.onCreate(TaskDBHelper.java:17)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:251)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at de.die_web_agenten.www.runinstant.AndroidBarcodeQrExample.onActivityResult(AndroidBarcodeQrExample.java:107)
at android.app.Activity.dispatchActivityResult(Activity.java:6441)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4001)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3395) 
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3440) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2774) 
at android.app.ActivityThread.access$900(ActivityThread.java:177) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1430) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:135) 
at android.app.ActivityThread.main(ActivityThread.java:5910) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200) 


Any help would be appreciated, thanks

Answer

This is the problematic part: 2 more parameters needed. You have 5 placeholders and 3 of them filled...

   String sqlQuery =
            String.format("CREATE TABLE %s (" +
              "_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
              "%s TEXT, %s TEXT, %s TEXT, %s TEXT, %s TEXT)",
              TaskContract.TABLE,
              TaskContract.Columns.SCAN_RESULT,
              TaskContract.Columns.SCAN_RESULT_FORMAT
                // 2 more to go!!
              );

Also take note: using String manipulation is generally not the recommended way to create SQL queries, even though in this code, all input seems to come from inside the application.