Why SQLite Database not showing in File Explorer in android studio? - java

in order to working with SQLite in android, I wrote this code:
public class TimeTrackerOpenHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "timetracker.db";
public TimeTrackerOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table timerecords " +
"(id integer primary key, time text, notes text)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
and also for instantiating of above class, I added following code to one of my activity class oncreate method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView listView = (ListView) findViewById(R.id.times_list);
adapter = new TimeTrackerAdapter();
listView.setAdapter(adapter);
TimeTrackerOpenHelper openHelper = new TimeTrackerOpenHelper(this);
Log.d("databaseCreation", openHelper.toString());
openHelper.close();
}
For monitoring the result of each query that I send to my timetracker.db, I need to access to my database file. I do the following steps:
1.Run your application.
2.Go to Tools--->Android---->Device Monitor.
3.Find your application name in left panel.
4.Then click on File Explorer tab.
5.Select data folder.
6.Select data folder again and find your app or module name.
7.Click on your database name.
8.On right-top window you have an option to pull file from device.
9.Click it and save it on your PC.
10.Use FireFox Sqlite manager to attach it to your project.
but I have to say that there is not any trace of my .db file. So how can I find that?

Your database will not be created until you call getReadableDatabase() or getWriteableDatabase() on the SQLiteOpenHelper. Simply creating the instance of the SQLiteOpenHelper will not do that.

Uninstall and Reinstall the app, it will work because you changed TimeTrackerOpenHelper class so ..

Related

Call non-static method of another class

I have two classes pertaining to this issue: AddA and TopicSpinner.
In the AddA class, I am setting an on touch listener for a spinner. When the spinner is selected, I want to call the method loadSpinnerData() of the TopicSpinner class. So I want to call a non-static method of the TopicSpinner class in the AddA class.
I know that starting the TopicSpinner class from the AddA class works with an Intent call so the loadSpinnerData() method does work properly. I tried several approaches in the listener as you see below. However, I cannot get the method to be called without a null pointer or "non-static method cannot be referenced from static method".
Any suggestions of how to call the method loadSpinnerData() of the TopicSpinner class in the listener method of the AddA class?
Here is the current exception:
java.lang.NullPointerException
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:109)
at TopicSpinner.loadSpinnerData(TopicSpinner.java:56)
at AddA$2.onTouch(AddAlerts.java:117)
at android.view.View.dispatchTouchEvent(View.java:7241)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2168)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1903)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2174)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1917)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1953)
at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1405)
at android.app.Activity.dispatchTouchEvent(Activity.java:2410)
at android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:59)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1901)
at android.view.View.dispatchPointerEvent(View.java:7426)
at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3220)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3165)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4292)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4271)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4363)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:179)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:125)
at android.os.Looper.loop(Looper.java:124)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Instead of adding the listener in your AddA class, just add it in your TopicSpinner class. You can do it in your onCreate method. Then you can directly reference your loadSpinnerData method.
public class TopicSpinner extends AddAlerts implements OnItemSelectedListener {
// Spinner element
Spinner spinner;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_alerts);
//Spinner element
spinner = (Spinner) findViewById(R.id.spinner);
//Spinner click listener
spinner.setOnItemSelectedListener(this);
//ADD LISTENER HERE
spinner.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
loadSpinnerData();
}
return false;
}
});
//Loading spinner data from database
loadSpinnerData();
}
/**
* Function to load the spinner data from SQLite database
**/
public void loadSpinnerData() {
// database handler
DatabaseHelper db = DatabaseHelper.getInstance(getApplicationContext());
Cursor topicCursor = db.getAllTopics();
Log.v("topicCursor", topicCursor.toString());
db.close();
String str;
ArrayList<String> labels = new ArrayList<String>();
if (topicCursor.moveToFirst()) {
do {
str = topicCursor.getString(topicCursor.getColumnIndex("topic_name"));
Log.v("str", str);
labels.add(str);
Log.v("labels", labels.toString());
} while (topicCursor.moveToNext());
}
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, labels);
//Drop down layout style - list view with radio button
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Log.v("dataAdapter", dataAdapter.toString());
//Attaching data adapter to spinner
spinner.setAdapter(dataAdapter);
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// On selecting a spinner item
String label = parent.getItemAtPosition(position).toString();
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
By your question, I call tell the confusion between a "Class" and an "Object". By calling a static method, your are calling an action on no particular instance of a TopicSpinner. By calling loadSpinnerData() as it is (not static) you are saying to a precise TopicSpinner, "do the job of loadSpinnerData()". See here to learn more.
I can see in TopicSpinner that you have a field "spinner" that is onwed by "an instance" of TopicSpinner. For example, you could have 2 TopicSpinners having a different Spinner each. The method loadSpinnerData() will actually modify that Spinner. In other words, loadSpinnerData() needs to be called via an instance (object) not via a static call, because it needs to know what Spinner it's actually going to play with.
Now why do you get a Nullpointerexception if you call it correctly? If you call new TopicSpinner() manually, then it means, run the loadSpinnerData() on a new instance of the TopicSpinner that I just created. I have a feeling your topic spinner already exists. You might be able to access it by drilling down in the objects View and MotionEvent. Try to debug and look for the TopicSpinner instance. Then, you can call loadSpinnerData() on that instance.
Hope I didn't confuse you too mch, but you really need to differenciate a class and an instance of a class (object).
Your issue is that "spinner" is not set (is null) in the following line in loadSpinnerData():
spinner.setAdapter(dataAdapter);
When you launch the class with an Intent, it executes onCreate, which properly initializes the "spinner" variable. You could declare "spinner" as an instance variable in AddA, then send it as a parameter to the constructor for TopicSpinner, where you capture and save the reference. Something like this:
public AddA extends Activity {
private Spinner spinner;
private Context context;
//In onCreate or wherever
spinner = (Spinner) findViewById(R.id.spinner);
context = this;
spinner.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
TopicSpinner ts = new TopicSpinner(spinner, context);
ts.loadSpinnerData();
}
//etc
Now in TopicSpinner add a constructor:
public class TopicSpinner extends AddA implements OnItemSelectedListener {
// Spinner element
private Spinner spinner;
private Context context;
public TopicSpinner(Spinner spinner, Context context){
this.spinner = spinner;
this.context = context;
}
//etc
In your TopicSpinner class replace getContext() with context.
The rest of your code remains untouched.
You could try passing in the spinner or context in as a parameter?
So copy and paste your load spinner data and sub out with the parameterized spinner and context:
public Spinner loadSpinnerData(Context context, Spinner spinner) {
// database handler
DatabaseHelper db = DatabaseHelper.getInstance(context);
Cursor topicCursor = db.getAllTopics();
Log.v("topicCursor", topicCursor.toString());
db.close();
String str;
ArrayList<String> labels = new ArrayList<String>();
if (topicCursor.moveToFirst()) {
do {
str = topicCursor.getString(topicCursor.getColumnIndex("topic_name"));
Log.v("str", str);
labels.add(str);
Log.v("labels", labels.toString());
} while (topicCursor.moveToNext());
}
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, labels);
//Drop down layout style - list view with radio button
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Log.v("dataAdapter", dataAdapter.toString());
//Attaching data adapter to spinner
spinner.setAdapter(dataAdapter);
return spinner;
}
And then reassign the spinner you passed in to be the new one that comes out of this method. It will hold its previous references as well because we are not assigning it in this method
Old Answer, (left because this 'was' true at the time, but the above code/info has changed)
To start with your first mistake is not storing the 'new' TopicSpinner. That is why you can't call 'member methods(might be wrong name, but 'non-static' methods)' of the class.
final Spinner spinner = (Spinner) findViewById(R.id.spinner);
spinner.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
// Intent i = new Intent(AddA.this, TopicSpinner.class);
//startActivity(i);
//TopicSpinner ts = new TopicSpinner();
//ts.loadSpinnerData(); //null
// the problem is that you aren't saving the reference to the
// newly created TopicSpinner Object.
// Storing that reference here allows you to call
// non-static methods.
TopicSpinner myTopicSpinner = new TopicSpinner();
// Perhaps this can be above if it follows the builder pattern...
// but if not, then you need to separate these calls.
myTopicSpinner.loadSpinnerData(); // loadSpinnerData you have listed returns 'void' so it doesn't follow builder pattern.
// if myTopicSpinner is null here then you have bigger issues in THAT class.
// Now you can call non-static methods on the OBJECT.
// Since you 'have' an object now.
myTopicSpinner.loadSpinnerData(); //non-static method
}
return false;
}
});
Calling your Activity classes by the names of other classes is seriously confusing people.
AddA is an Activity.
TopicSpinner is also an Activity since you extends AddA.
Calling new TopicSpinner() creates an Activity object, but does not inflate it, so calling setContentView and findViewById are pointless inside of TopicSpinner. It might even return null because the view cannot be found.
As is, you have two options and both get rid of the extends AddA.
Option 1: Just load the data in AddA
Option 2: Create a separate class that loads the data that is not an Activity. You are getting all confused with onCreate and setContentView and findViewById. All you need is the Context and Spinner.
public class AddA extends Activity implements AdapterView.OnItemSelectedListener {
private Spinner spinner;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_a);
spinner = (Spinner) findViewById(R.id.spinner);
spinner.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
/** Option 1 **/
loadSpinnerData();
/** Option 2 **/
TopicLoader loader = new TopicLoader(getApplicationContext());
loader.loadSpinner(spinner);
}
return false;
}
});
}
private void loadSpinnerData() {
Context ctx = getApplicationContext();
// TODO: Implement Option 1 here
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// On selecting a spinner item
String label = parent.getItemAtPosition(position).toString();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
}
public class TopicLoader {
private Context mCtx;
public TopicLoader(Context ctx) {
this.mCtx = ctx;
}
public void loadSpinner(Spinner spinner) {
// Context ctx = this.mCtx;
// TODO: Implement Option 2 here
}
}
DatabaseHelper db =
DatabaseHelper.getInstance(getApplicationContext()); return null.
If this is the case, then your DatabaseHelper class is where your issues
actually is.
Here is a question with an (almost) complete answer that will show you what to do (you will need to impl. your own rawQuery(), that they don't do in that link)
Looking for Cause of Null Pointer Exception
There are a couple things that you can try. (Hard to tell without seeing source for DatabaseHelper)
1) DatabaseHelper db = new DatabaseHelper(getApplicationContext()); then db.open() right after it. (if you follow the pattern that I show below). Use normal constructor instead of 'getInstance()'. I haven't seen DBHelper classes being singletons or something else that would require 'getInstance()' before. A SQLite DB should be able to handle multiple-concurrent readable DB accesses EASILY (writes have timing issues, but that is 'app logic' not the SQLite DB itself).
2) Start logging within your DatabaseHelper class and see where it fails internally.
Here is (part of) a sample DBHelper class I wrote a long time ago.
You shouldn't be getting a 'null' when you try to instantiate yours. You should make sure that class is operating properly. If you don't have one you should have an internal SQLiteOpenHelper class (very helpful).
// Database open/upgrade helper
private myDbHelper dbHelper; // this is inside my DBAdapter class
// ...
/**
* constructor that accepts the context to be associated with
*
* #param _context
*/
public DataDBAdaptor(Context _context) {
Log.d(LOG_TAG, "MyDBAdapter constructor");
context = _context;
dbHelper = new myDbHelper(context, DATABASE_NAME, null,
DATABASE_VERSION);
}
/**
* open the DB, and write/read access or
* just read access if that is all that is possible.
*
* #return this DataDBAdaptor
* #throws SQLException
*/
public MoocDataDBAdaptor open() throws SQLException {
Log.d(LOG_TAG, "open()");
try {
db = dbHelper.getWritableDatabase();
} catch (SQLException ex) {
db = dbHelper.getReadableDatabase();
}
return this;
}
Here is the Helper class
/**
* DB Helper Class.
*
* #author mawalker
*
*/
private static class myDbHelper extends SQLiteOpenHelper {
public myDbHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
}
#Override
public void onCreate(SQLiteDatabase db) {
Log.d(LOG_TAG, "DATABASE_CREATE: version: " + DATABASE_VERSION);
// ST:createTable:start
db.execSQL(DATABASE_CREATE_STORY);
db.execSQL(DATABASE_CREATE_TAGS);
// ST:createTable:finish
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Log version upgrade.
Log.w(LOG_TAG + "DBHelper", "Upgrading from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data");
// **** Upgrade DB ****
// TODO: migrate data?? from old DB to new DB
// drop old DB
// ST:dropTableIfExists:start
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE_STORY);
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE_TAGS);
// ST:dropTableIfExists:finish
// Create a new one.
onCreate(db);
}
}

Failed to open Database Android Java SQLite

Here is my code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SQLiteDatabase.openOrCreateDatabase("/gregpeck.db", null);
}
Obviously this is inside my Main Activity.
I have also added the permission to my Main Activity:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ie.callanan.dennis.testhw" >
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
The error message I receive is:
Failed to open database 'gregpeck.db'.
android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
I would recommend to use a SQLiteOpenHelper, if you need a private database for your application:
public class MyDatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "DatabaseName";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_CREATE = "CREATE TABLE ....";
public MyDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase database) {
database.execSQL(TABLE_CREATE);
}
#Override
public void onUpgrade(SQLiteDatabase database,int oldVersion,int newVersion){
// do whatever is required for the upgrade
}
}
Here you find a full example. If you want to open a database from SD card, use:
File file = new File("/sdcard/db.sqlite" );
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(file, null);
Log.d("MyApp", "Successfully opened: " + db.isOpen());
For the first case you don't need any particular permissions. For the second one you do. Note: Android 4.3 and 4.4 do restrict the access on the SD card. So it might be that you cannot access the database file at all (see for instance this article).

Android Custom Array Adapter to read CSV files

I am a newbie to android application development. I am currently working on a project which deals with the import of csv files which consists of only one column and many rows , onto my android project. I am able to read those csv files onto my project using csv adapters and array adapters and I didn't use any string arrays. Only used csvadapter and array adapters. Now in the list view where all the csv datas are presented, I am having a concern where when clicked on an item in the list I wanted to toast the item name. I tried out all possible combinations but it displays me only a toast saying string#somerandomvalue. Request someone to help me on this. Thanks in advance.
The following is my csvadapter class. The .csv files are in placed in assets folder..
public class CSVAdapter extends ArrayAdapter<clock>{
Context ctx;
public CSVAdapter(Context context,int textViewResourceId)
{
super (context,textViewResourceId);
this.ctx = context;
loadArrayFromFile();
}
#Override
public View getView(final int pos,View convertView,final ViewGroup parent){
TextView mView=(TextView)convertView;
if(null == mView){
mView = new TextView(parent.getContext());
mView.setTextSize(28);
}
mView.setText(getItem(pos).getTime());
return mView;
}
And this is my class to read that .csv array into GUI
public class mrvtoparanur extends Activity {
CSVAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mrvtoparanur);
final ListView mList = (ListView)findViewById(R.id.mrvtoparanurlist);
mAdapter=new CSVAdapter(this,-1);
mList.setAdapter(mAdapter);
mList.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Toast.makeText(getApplicationContext(), "you selected item number"+arg2, Toast.LENGTH_SHORT).show();
}});
}
Request someone to help on the Toast in the second class java file. In the msg "YOU SELECTED ITEM NUMBER" the arg2 gives the item id.. In a similar way i want to display or toast the item name instead of item ID. Pls help me someone
This is clock.java file... Please refer below.
public class clock {
private String t;
public String getTime() {
return t;
}
public void setTime(String t) {
this.t = t;
}
}
Use the data from the adapter:
clock clicked = mAdapter.getItem(arg2);
(Then I don't know the structure of the clock object)

Eclipse inserting data into SQLite Database, no such table

I'm trying to insert data into the database but it tells me there's no such table. I also have another sqlite database inside the application, i'm not sure if that affects this one, but I don't think so. It uses the same database name, but a different table name. If you think it does affect it, tell me and I'll post up the code for that too.
The logcat gives me these messages:
(1) no such table: notes
Error inserting title=Bleh desc=bleh
android.database.sqlite.SQLiteException: no such table: notes (code 1): , while compiling: INSERT INTO notes(title,desc) VALUES (?,?)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1467)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1339)
at com.example.stepsaway.NoteActivity.addEntry(NoteActivity.java:102)
at com.example.stepsaway.NoteActivity.onClick(NoteActivity.java:75)
at android.view.View.performClick(View.java:4240)
at android.view.View$PerformClick.run(View.java:17721)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
The Activity java is:
public class NoteActivity extends Activity implements OnClickListener {
Button buttonLeaveNote;
private EditText mTitle;
private EditText mDesc;
protected NoteDBHelper noteDB = new NoteDBHelper(NoteActivity.this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_note);
buttonLeaveNote = (Button) findViewById(R.id.buttonLeaveNote);
buttonLeaveNote.setOnClickListener(this);
mTitle = (EditText)findViewById(R.id.etitle);
mDesc = (EditText)findViewById(R.id.edesc);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.note, menu);
return true;
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.buttonLeaveNote:
String title = mTitle.getText().toString();
String desc = mDesc.getText().toString();
boolean invalid = false;
if(title.equals(""))
{
invalid = true;
Toast.makeText(getApplicationContext(), "Please enter a title", Toast.LENGTH_SHORT).show();
}
else
if(desc.equals(""))
{
invalid = true;
Toast.makeText(getApplicationContext(), "Please enter description", Toast.LENGTH_SHORT).show();
}
else
if(invalid == false)
{
addEntry(title, desc);
Intent i_note = new Intent(NoteActivity.this, JustWanderingActivity.class);
startActivity(i_note);
//finish();
}
break;
}
}
public void onDestroy()
{
super.onDestroy();
noteDB.close();
}
private void addEntry(String title, String desc)
{
SQLiteDatabase notedb = noteDB.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("title", title);
values.put("desc", desc);
//values.put("lati", lati);
//values.put("lng", lng);
try
{
long newRowId;
newRowId = notedb.insert(NoteDBHelper.DATABASE_TABLE_NAME, null, values);
Toast.makeText(getApplicationContext(), "Note successfully added", Toast.LENGTH_SHORT).show();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
And the Database java is:
public class NoteDBHelper extends SQLiteOpenHelper
{
private SQLiteDatabase notedb;
public static final String NOTE_ID = "_nid";
public static final String NOTE_TITLE = "title";
public static final String NOTE_DESC = "desc";
public static final String NOTE_LAT = "lati";
public static final String NOTE_LONG = "lng";
NoteDBHelper noteDB = null;
private static final String DATABASE_NAME = "stepsaway.db";
private static final int DATABASE_VERSION = 2;
public static final String DATABASE_TABLE_NAME = "notes";
private static final String DATABASE_TABLE_CREATE =
"CREATE TABLE " + DATABASE_TABLE_NAME + "(" +
"_nid INTEGER PRIMARY KEY AUTOINCREMENT," +
"title TEXT NOT NULL, desc LONGTEXT NOT NULL);";
public NoteDBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
System.out.println("In constructor");
}
#Override
public void onCreate(SQLiteDatabase notedb) {
try{
notedb.execSQL(DATABASE_TABLE_CREATE);
}catch(Exception e){
e.printStackTrace();
}
}
#Override
public void onUpgrade(SQLiteDatabase notedb, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
public Cursor rawQuery(String string, String[] strings) {
// TODO Auto-generated method stub
return null;
}
public void open() {
getWritableDatabase();
}
public Cursor getDetails(String text) throws SQLException
{
Cursor mCursor =
notedb.query(true, DATABASE_TABLE_NAME,
new String[]{NOTE_ID, NOTE_TITLE, NOTE_DESC},
NOTE_TITLE + "=" + text,
null, null, null, null, null);
if (mCursor != null)
{
mCursor.moveToFirst();
}
return mCursor;
}
}
Any help would be appreciated, thank you.
Edit: Looks like the problem is creating a second table within the same database name. It won't let me create a second one. The first time creating the DB works fine, but it gives the SQLite Exception with no such table when trying to create another table. Is there some code I need to alter or add to create a second table? Because all i did was create another sqlite database java with the same DATABASE_NAME, but a different DATABASE_TABLE_NAME.
My best guess is when you create nodeDB object, the activity is still not available. Therefore you will failed creating the table.
You can try moving how you initialise the noteDB into inside onCreate():
protected NoteDBHelper noteDB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_note);
noteDB = new NoteDBHelper(NoteActivity.this);
buttonLeaveNote = (Button) findViewById(R.id.buttonLeaveNote);
buttonLeaveNote.setOnClickListener(this);
mTitle = (EditText)findViewById(R.id.etitle);
mDesc = (EditText)findViewById(R.id.edesc);
}
Your onUpgrade() is empty and database schema version is 2. My guess is that your initial version of the database didn't have the notes table and when it was later added, the empty upgrade code couldn't add it. But SQLiteOpenHelper is satisfied as it is now running version 2 of the database.
To fix it once, clean your app data. E.g. in settings app, go to manage apps -> downloaded -> select your app and click on the "Clear application data" button. Or just uninstall and reinstall the app. This approach is good enough during development.
To fix it for released versions, implement onUpgrade() so that is updates the database schema and does any necessary data migration. If you're not concerned about data loss, you can just call DROP TABLE on the old tables and then call onCreate() to recreate the tables.
To your follow-up question regarding multiple tables: Just use the same helper class to manage the database. One helper per database file. Create all tables in onCreate() and do any required migrations in onUpgrade().
Regarding to First issue : as I explained in my comment >
If you have created the DB before and adding a table afterwards this can cause the problem. Tables are created for the first time DB created. So uninstall or clean the data in the app from device and run it again.
For the Second Issue :
If you want to Create a table, do the same that you are already doing for the table you have.
#Override
public void onCreate(SQLiteDatabase notedb) {
try{
notedb.execSQL(DATABASE_TABLE_CREATE);
notedb.execSQL(DATABASE_TABLE_CREATE_STRING_2);
}catch(Exception e){
e.printStackTrace();
}
}

Adding Information in SQLite

I am having trouble with my Android App when adding information into SQLite. I am relatively new to Java/SQLite and though I have followed a lot of tutorials on SQLite and have been able to get the example code to run I am unable to get tables to be created and data to import when running my own app. I have included my code in two Java files Questions (Main Program) and QuestionData (helper class represents the database).
Questions.java:
public class Questions extends Activity {
private QuestionData questions;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.quiztest);
questions = new QuestionData(this);
try {
Cursor cursor = getQuestions();
showQuestions(cursor);
} finally {
questions.close();
}
}
private Cursor getQuestions() {
//Select Query
String loadQuestions = "SELECT * FROM questionlist";
SQLiteDatabase db = questions.getReadableDatabase();
Cursor cursor = db.rawQuery(loadQuestions, null);
startManagingCursor(cursor);
return cursor;
}
private void showQuestions(Cursor cursor) {
// Collect String Values from Query and Display them this part of the code is wokring fine when there is data present.
QuestionData.java
public class QuestionData extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "TriviaQuiz.db" ;
private static final int DATABASE_VERSION = 2;
public QuestionData(Context ctx) {
super(ctx, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE questionlist (_id INTEGER PRIMARY KEY AUTOINCREMENT, QID TEXT, QQuestion TEXT, QAnswer TEXT, QOption1 TEXT, QOption2 TEXT, QOption3 TEXT, QCategoryTagLvl1 TEXT, QCategoryTagLvl2 TEXT, QOptionalTag1 TEXT, QOptionalTag2 TEXT, QOptionalTag3 TEXT, QOptionalTag4 TEXT, QOptionalTag5 TEXT, QTimePeriod TEXT, QDifficultyRating TEXT, QGenderBias TEXT, QAgeBias TEXT, QRegion TEXT, QWikiLink TEXT, QValidationLink1 TEXT, QValidationLink2 TEXT, QHint TEXT, QLastValidation TEXT, QNotes TEXT, QMultimediaType TEXT, QMultimediaLink TEXT, QLastAsked TEXT);");
db.execSQL("INSERT INTO questionlist (_id, QID, QQuestion, QAnswer, QOption1, QOption2, QOption3, QCategoryTagLvl1, QCategoryTagLvl2, QOptionalTag1, QOptionalTag2, QOptionalTag3, QOptionalTag4, QOptionalTag5, QTimePeriod, QDifficultyRating, QGenderBias, QAgeBias, QRegion, QWikiLink, QValidationLink1, QValidationLink2, QHint, QLastValidation, QNotes, QMultimediaType, QMultimediaLink, QLastAsked)"+
"VALUES (null,'Q00001','Example','Ans1','Q1','Q2','Q3','Q4','','','','','','','','','','','','','','','','','','','','')");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
Any suggestions at all would be great. I have tried debugging which suggests that the database does not exist. Thanks in advance for your assistance.
I removed the constants setup which had a capitalisation in it which was not referenced elsewhere. I knew it was going to be something simple but I could not locate the issue. Thanks again!

Categories

Resources