How to access database on Android app without root - java

I'm developing a small app with a database of 100 elements. I import the database but only in one emulator (of 3 witch I have) runs correctly. I found that it runs without problems because the "Songs.db" database exists in data/data/myapppackage/databases/ folder witch I can't have access without rooting the device.
I search through internet for different approaches and solutions to this problem but nothing is working. I am new to android programming and for this kind of problem there isn't any tutorial.
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "Songs.db";
public static final String TABLE_NAME = "songs_table";
public static final String COL_1 = "ID";
public static final String COL_2 = "TITLE";
public DatabaseHelper (Context context) {
super( context, DATABASE_NAME, null, 1 );
SQLiteDatabase db = this.getWritableDatabase();
}
public Cursor getData(int id) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery( "select TITLE from songs_table where ID="+id+"", null );
return res;
}
}
and on PlayerTurn class
myDb = new DatabaseHelper( this );
Cursor rs = db.getData( b );
rs.moveToFirst();
tit = rs.getString( rs.getColumnIndex( db.COL_2 ) );
The error message I get most of the times is android.database.sqlite.SQLiteException: no such table: songs_table (code 1):
Can anyone help me? I spend almost 15 hours about that...

You can copy the DB into SD card, From SD card you can always access the DB
Try this code:
try {
File sd = Environment.getExternalStorageDirectory();
File data = Environment.getDataDirectory();
if (sd.canWrite()) {
String currentDBPath = "data/"+sPackageName+"/databases/"+sDBName;
String backupDBPath = "/.appname-external-data-cache/"+sDBName; //"{database name}";
File dir = new File(sd,backupDBPath.replace(sDBName,""));
if(dir.mkdir()) {
}
File currentDB = new File(data, currentDBPath);
File backupDB = new File(sd, backupDBPath);
if (currentDB.exists()) {
FileChannel src = new FileInputStream(currentDB).getChannel();
FileChannel dst = new FileOutputStream(backupDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
}
}
} catch (Exception e) {
}

Related

Android Studio - Trying to Read MP3 FIles from the Music Directory on Android Device

I have a function below that I got from a post on here, where I am trying to read the music files from the device.
public List<AudioModel> getAllAudioFromDevice(final Context context) {
final List<AudioModel> tempAudioList = new ArrayList<>();
Cursor c = getAllTracks(this);
if (c != null) {
Log.d("Count :", String.valueOf(c.getCount()));
while (c.moveToNext()) {
AudioModel audioModel = new AudioModel();
String path = c.getString(0);
String name = c.getString(1);
String album = c.getString(4);
audioModel.setaAlbum(album);
audioModel.setaArtist(artist);
Log.e("Name :" + name, " Album :" + album);
Log.e("Path :" + path, " Artist :" + artist);
tempAudioList.add(audioModel);
}
c.close();
} else {
Log.d("Name :", "No Music");
}
return tempAudioList;
}
public Cursor getAllTracks(Context context) {
// gets all tracks
if (context != null) {
ContentResolver cr = context.getContentResolver();
final String[] columns = {track_id, track_no, artist, track_name,
album, duration, path, year, composer};
return cr.query(uri, columns, null, null, null);
} else {
return null;
}
}
When I run the app, it doesn't list any of the MP3 files, but it picks up oog files. The mp3 files I have uploaded to the emulator look as below:
I have tried the EXTERNAL_CONTENT_URI as well, but that doesn't display them.
This is from the "Playlist Manager" app as suggested by Theo:
Sorry, I am very new to Android Studio and am probably missing something very obvious. Can someone help please?
Your issue is
Uri uri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;
change this to
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
and also remove the .DATA bit from
Cursor c = context.getContentResolver().query(uri, projection, MediaStore.Audio.Media.DATA, null, null)
as you put criteria there. Look up the syntax for query. Set it to null and it will work
For what it's worth - I had the exact same problem. I added my audio files to the emulator using the Device File Explorer and the code didn't seem to work.
It turns out that I had to simply reboot my emulator after adding the files in order for the uploaded files to appear in the MediaStore data base.
I don't know if this is a bug or a feature in Android Studio and/or the emulator, but in my case it fixed the issue. I tested it on two different emulator sessions (one with SDK31 and the other SDK29).
This is my approach, note the syntax of
return cr.query(uri, columns, null, null, null)
whereas you have
Cursor c = context.getContentResolver().query(uri, projection, MediaStore.Audio.Media.DATA, null, null);
private final String track_id = MediaStore.Audio.Media._ID;
private final String track_no = MediaStore.Audio.Media.TRACK;
private final String track_name = MediaStore.Audio.Media.TITLE;
private final String artist = MediaStore.Audio.Media.ARTIST;
private final String artist_id = MediaStore.Audio.Media.ARTIST_ID;
private final String duration = MediaStore.Audio.Media.DURATION;
private final String album = MediaStore.Audio.Media.ALBUM;
private final String composer = MediaStore.Audio.Media.COMPOSER;
private final String year = MediaStore.Audio.Media.YEAR;
private final String path = MediaStore.Audio.Media.DATA;
private final String date_added = MediaStore.Audio.Media.DATE_ADDED;
private final Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
public Cursor getAllTracks(Context context) {
// gets all tracks
if (context != null) {
ContentResolver cr = context.getContentResolver();
final String[] columns = {track_id, track_no, artist, track_name,
album, duration, path, year, composer};
return cr.query(uri, columns, null, null, null);
} else {
return null;
}
}

SQLite SELECT query in Android external database - table error

I'm developing a data collection app using multiple relational data tables. I've created my database. And the code is working fine in case of the first table. If I try to run the same query for the second table, it shows the table doesn't exist, even though the table is in the database.
Database structure
public String getName(String Plant) {
c1 = db.rawQuery("select * from Area where PAd = '" + Plant + "'", new String[]{});
StringBuffer buffer = new StringBuffer();
while (c.moveToNext()) {
String plant = c.getString(0);
buffer.append("" + plant);
}
return buffer.toString();
}
Error Log:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.dbtest, PID: 28350
android.database.sqlite.SQLiteException: no such table: Area (code 1): , while compiling: select * from Area where PAd = 'Plant02'
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:890)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:501)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1392)
at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1331)
at com.example.dbtest.DatabaseAcess.getName(DatabaseAcess.java:46)
at com.example.dbtest.MainActivity$3.onClick(MainActivity.java:86)
at android.view.View.performClick(View.java:6305)
at android.view.View$PerformClick.run(View.java:24840)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6501)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Table structure of the second table
CREATE TABLE Area (
Name TEXT,
Address TEXT,
PAd TEXT
);
Table structure of the first table
CREATE TABLE Table1 (
Name TEXT,
Address TEXT
);
DatabaseOpenHelper code.
public class DatabaseOpenHelper extends SQLiteAssetHelper {
private static final String DATABASE_NAME = "MyExternalDatabase1.db";
public static final int DATABASE_VERSION = 1;
public DatabaseOpenHelper(Context context){
super(context,DATABASE_NAME,null,DATABASE_VERSION);
}
}
DatabaseAccess code.
public class DatabaseAcess {
private SQLiteOpenHelper openHelper;
private SQLiteDatabase db;
private static DatabaseAcess instance;
Cursor c = null;
Cursor c1 = null;
private DatabaseAcess(Context context){
this.openHelper = new DatabaseOpenHelper(context);
}
public static DatabaseAcess getInstance(Context context){
if(instance == null){
instance = new DatabaseAcess(context);
}
return instance;
}
public void open(){
this.db = openHelper.getWritableDatabase();
}
public void close(){
if(db!=null){
this.db.close();
}
}
public String getAddress(String name){
c= db.rawQuery("select Address from Table1 where Name = '" + name + "'", new String[]{});
StringBuffer buffer = new StringBuffer();
while (c.moveToNext()) {
String address = c.getString(0);
buffer.append("" + address);
}
return buffer.toString();
}
public String getName(String Plant) {
c1 = db.rawQuery("select Name from Area where PAd = '" + Plant + "'", null);
StringBuffer buffer = new StringBuffer();
while (c.moveToNext()) {
String plant = c.getString(0);
buffer.append(""+plant);
}
return buffer.toString();
}
}
Maybe this can help you
public String getName(String Plant) {
Cursor c = db.rawQuery("SELECT * FROM Area WHERE PAd='+Plant+'", null);
StringBuffer buffer = new StringBuffer();
while (c.moveToNext()) {
String plant = c.getString(0);
buffer.append(""+plant);
}
return buffer.toString();
}
I think by the external database, you meant a database which you want to be loaded from your asset directory. Here you need to copy the database in your application internal storage first to make this accessible from your code. So I would like to suggest you do the following when you run the application for the first time.
public static final String DB_PATH = "/data/data/" + "com.your.package.name" + "/databases/";
private void copyFromAssetsAndCreateDatabase() {
InputStream yourDatabaseFromAsset;
try {
yourDatabaseFromAsset = getApplicationContext().getAssets().open("MyExternalDatabase1");
File dir = new File(DataHelper.DB_PATH);
if (!dir.exists()) dir.mkdir();
File f = new File(DataHelper.DB_PATH + "MyExternalDatabase1" + ".sqlite");
if (!f.exists()) {
f.createNewFile();
}
OutputStream mOutput = new FileOutputStream(f);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = yourDatabaseFromAsset.read(mBuffer)) > 0)
mOutput.write(mBuffer, 0, mLength);
mOutput.flush();
mOutput.close();
mInputEnglish.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Now when the database is copied from your external folder to your internal storage where the databases are located usually, it should find the database without any error. I do not know about the first database though. I think it was created in your application using the CREATE TABLE statement.
Hope that helps.
One possible reason is that you created only first table at first time. After that you append code for second table. Note database is already created and will not call onCreate() again. You should upgrade database version and create second table in onUpgrade().
I made same mistakes before.

android onUpgrade moving some records from old db to new db

What I'm trying to achieve is that my application will ship with an existing sqlite database exported from my web panel with some records(news, products, categories etc.) and later on it will insert some records of its own into it(lets say it'll insert notifications it receives) and it will be copied to the databases folder, up to here there is no problem but my concern is when a user upgrades their application through market I want to replace the new database with the old one but keep those application generated records(notifications it has received) and insert them into the new one. Here's my code so far: (please enhance if necessary)
public class Helper_Db extends SQLiteOpenHelper{
public static final String DB_NAME = "Test.sqlite";
public static final int DB_VERSION = 3;
private static String DB_PATH = "";
private SQLiteDatabase _db;
private final Context _ctx;
public Helper_Db(Context context) {
super(context, null, null, 1);
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
_ctx = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
try
{
copyDatabase();
Log.e("DATABASE", "Database created");
}
catch(IOException io)
{
Log.e("DATABASE", io.toString());
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//take out the notifications from old db
//insert them into the new db
//delete the old db
//copy the new db
}
private void copyDatabase() throws IOException
{
InputStream input = _ctx.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream output = new FileOutputStream(outFileName);
byte [] buffer = new byte [1024];
int length;
while((length = input.read(buffer)) > 0)
{
output.write(buffer, 0, length);
}
output.flush();
output.close();
input.close();
}
public boolean openDatabase() throws SQLException
{
String path = DB_PATH + DB_NAME;
_db = SQLiteDatabase.openDatabase(path, null,
SQLiteDatabase.CREATE_IF_NECESSARY);
return _db != null;
}
#Override
public void close()
{
if(_db != null)
{
_db.close();
}
super.close();
}
}
Thanks in advance.
I do something similar. I have default content in a database that I ship with the app that changes sometimes. However, I have a routine for synchronizing databases for syncing between users and with backups, and each time I upgrade the DB, I just take the included DB and sync it with the existing user's DB.
That may be too much for your needs, but this brings me to how I know whether data is user data or not which seems like is the real problem here. You need to determine what data is user data. Then all you need to do is copy that data.
So, my recommendation is to create an integer column in each database table called something like "IncludedContent" and set that to 1 on all data that you include in your shipped database and set the default value to 0 which is what all user content will have. Then all you have to so is attach the databases using the Attach command something like this:
db.execSQL("ATTACH DATABASE ? AS Old_DB", new String[]{fullPathToOldDB});
and then do an insert like this to copy only user content:
db.execSQL("INSERT INTO New_DB.TABLE SELECT * FROM Old_DB.TABLE WHERE IncludedContent = 0");

Android application force closing on device

On the Emulator the app runs fine. On the device the moment im trying to copy my database over the application's database and execute a query the app force closes. Any idea why this could be happening? Do i have to request any kind of permissions or something in manifest for it to run?
Database.Java
public class Database extends SQLiteOpenHelper{
//The Android's default system path of your application database.
private static String DB_PATH = "/data/data/gr.BHC.www/databases/";
//Name of the Database to be created.
private static String DB_NAME = "BHCLibrary3.sqlite";
private SQLiteDatabase myDataBase;
private final Context myContext;
* Constructor
* Takes and keeps a reference of the passed context in order to access to the application assets and resources.
* #param context
*/
public Database(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
/**
* Creates a empty database on the system and rewrites it with your own database.
* */
public void createDataBase() throws IOException{
//First we check if the database already exists, Method declared later
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exists
}else{
//By calling this method an empty database will be created into the default system path
//of your application so we are going to be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase(); //Method declared later
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
/**
* Check if the database already exist to avoid re-copying the file each time you open the application.
* #return true if it exists, false if it doesn't
*/
private boolean checkDataBase() {
//SQLiteDatabase checkdb = null;
boolean checkdb = false;
try{
String myPath = DB_PATH + DB_NAME;
File dbfile = new File(myPath);
//checkdb = SQLiteDatabase.openDatabase(myPath,null,SQLiteDatabase.OPEN_READWRITE);
checkdb = dbfile.exists();
}
catch(SQLiteException e){
System.out.println("Database doesn't exist");
}
return checkdb;
}
/**
* Copies your database from your local assets-folder to the just created empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transferring byte stream.
* */
private void copyDataBase() throws IOException{
//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
//Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}
//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
//Opening the Database
public void openDataBase() throws SQLException{
//Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}
//Finally overriding a few methods as required
#Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
//First we check if the database already exists, Method declared later
boolean dbExist = checkDataBase();
if(dbExist){
//do nothing - database already exists
}else{
//By calling this method an empty database will be created into the default system path
//of your application so we are going to be able to overwrite that database with our database.
this.getReadableDatabase();
try {
copyDataBase(); //Method declared later
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
And Results.java (The activity i run my query)
public class SearchResults extends ListActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.searchresults);
Database myDbHelper = new Database(null);
myDbHelper = new Database(this);
}
// Get the intent, verify the action and get the query
Intent intent = getIntent();
String query = intent.getStringExtra(SearchManager.QUERY);
SQLiteDatabase myDb = myDbHelper.getReadableDatabase();
//Executing our query against the server using rawQuery and getting the cursor
String select="SELECT DISTINCT b._ISBN as _id, b.BookTitle, b.Edition, b.Year, b.Pages, b.Rating, c.Category, p.Publisher, w.LastName" +
" FROM" +
" Books b" +
" JOIN Categories_Books cb ON cb._Books_ISBN = _id" +
" JOIN Categories c ON c._CategoryID = cb._Categories_CategoryID" +
" JOIN Publishers p ON p._PublisherID = b.PublisherID" +
" JOIN Writers_Books wb ON wb._Books_ISBN = _id" +
" JOIN Writers w ON w._WriterID = wb._Writers_WriterID" +
" WHERE b.BookTitle LIKE '%" + query +"%'" +
" OR c.Category LIKE '%" + query +"%'" +
" OR p.Publisher LIKE '%" + query +"%'" +
" OR w.LastName LIKE '%" + query +"%'" +
" OR _id LIKE '%" + query +"%'" +
" GROUP BY b.BookTitle";
Cursor c = myDb.rawQuery(select, null);
startManagingCursor(c);
// the desired columns to be bound
String[] columns = new String[] { "Books.BookTitle", "Publishers.Publisher" };
// the XML defined views which the data will be bound to
int[] to = new int[] { R.id.ISBN_entry, R.id.Title_entry };
//Getting results into our listview
try
{
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this, R.layout.listlayout, c, columns, to);
this.setListAdapter(mAdapter);
}
catch( Exception e)
{
}
}
}
Help would be appreciated.
EDIT: The error im getting is : java.lang.runtimeexception: Unable to start activity Componentinfo(gr.BHC.www/gr.BHC.www.SearchResults} and then various exceptions saying table books etc dont exist.
EDIT2: I saw the exception im getting usually related with content providers but i still cant figure out why i'd get that.
I think I solved the problem. I made some changes on your codes and now it is working. Here are the codes:
SearchResults.java
public class SearchResults extends ListActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.searchresults);
DbManager myDbHelper = new DbManager(null);
myDbHelper = new DbManager(this);
// Get the intent, verify the action and get the query
myDbHelper.createNewDatabase();
try {
myDbHelper.open();
Log.d("Search Results", "database opened");
} catch (SQLException sqle) {
throw sqle;
}
Intent intent = getIntent();
String query = intent.getStringExtra(SearchManager.QUERY);
// Executing our query against the server using rawQuery and getting the
// cursor
String select = "SELECT DISTINCT b._ISBN as _id, b.BookTitle, b.Edition, b.Year, b.Pages, b.Rating, c.Category, p.Publisher, w.LastName"
+ " FROM"
+ " Books b"
+ " JOIN Categories_Books cb ON cb._Books_ISBN = _id"
+ " JOIN Categories c ON c._CategoryID = cb._Categories_CategoryID"
+ " JOIN Publishers p ON p._PublisherID = b.PublisherID"
+ " JOIN Writers_Books wb ON wb._Books_ISBN = _id"
+ " JOIN Writers w ON w._WriterID = wb._Writers_WriterID"
+ " WHERE b.BookTitle LIKE '%"
+ query
+ "%'"
+ " OR c.Category LIKE '%"
+ query
+ "%'"
+ " OR p.Publisher LIKE '%"
+ query
+ "%'"
+ " OR w.LastName LIKE '%"
+ query
+ "%'"
+ " OR _id LIKE '%"
+ query
+ "%'"
+ " GROUP BY b.BookTitle";
Cursor c = myDbHelper.rawQ(select);
startManagingCursor(c);
// the desired columns to be bound
String[] columns = new String[] { "Books.BookTitle",
"Publishers.Publisher" };
// the XML defined views which the data will be bound to
int[] to = new int[] { R.id.ISBN_entry, R.id.Title_entry };
// Getting results into our listview
try {
SimpleCursorAdapter mAdapter = new SimpleCursorAdapter(this,
R.layout.listlayout, c, columns, to);
this.setListAdapter(mAdapter);
} catch (Exception e) {
}
}
}
And your new database helper, DbManager:
DbManager.java
public class DbManager extends SQLiteOpenHelper {
private static final String DB_NAME = "BHCLibrary3.sqlite";
private static final String DB_PATH = "/data/data/gr.BHC.www/databases/";
private static final Integer DB_VERSION = 1;
private static final String TAG = "DbManager";
private final Context context;
private SQLiteDatabase db;
private DbManager dbManager;
public DbManager(Context context) {
super(context, DB_NAME, null, DB_VERSION);
this.context = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE 'notes' (_id integer primary key autoincrement, title text not null);");
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
public DbManager open() {
dbManager = new DbManager(context);
db = dbManager.getWritableDatabase();
return this;
}
public void createNewDatabase() {
InputStream assetsDB = null;
try {
assetsDB = context.getAssets().open(DB_NAME);
OutputStream dbOut = new FileOutputStream(DB_PATH + DB_NAME);
byte[] buffer = new byte[1024];
int length;
while ((length = assetsDB.read(buffer)) > 0) {
dbOut.write(buffer, 0, length);
}
dbOut.flush();
dbOut.close();
assetsDB.close();
Log.i(TAG, "New database created...");
} catch (IOException e) {
Log.e(TAG, "Could not create new database...");
e.printStackTrace();
}
}
public Cursor rawQ(String select) {
return db.rawQuery(select, null);
}
}
Looks like the size of your database exceeds one MB. In that case you need to store it in the assets folder as .jpg and then copy it over. This is because Android places a restriction on the size of the text assets.

Android sqlite creating database error

i am newbie with android sqlite database. now i just try to create my custom database manager and i got the error at oncreate() function. I already spent 3 days to figure it out but unfortunately i am still stuck in it. Any brilliant idea would be appreciate.
public class DBManager extends SQLiteOpenHelper {
private SQLiteDatabase db;
private static Context myContext;
public static final String DB_NAME = "goldenland.db";
public static final String TB_CAT = "tbl_categories";
public static final String TB_ARTICLE = "tbl_articles";
public static final String TB_SUBCAT = "tbl_subcategories";
public static final String TB_SCHEDULE = "tbl_schedule";
public static final String TB_CONTENT = "tbl_contents";
public static final String TB_CITY = "tbl_cities";
public static final String name = "name";
public static String DB_PATH = "/data/data/com.gokiri.goldenland/databases/";
public DBManager(Context context) {
super(context, DB_NAME, null, 1);
DBManager.myContext = context;
}
public void createDataBase() throws IOException {
boolean dbExit = checkDataBase();
if (dbExit) {
System.out.println("Testing");
} else {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
}
}
private boolean checkDataBase() {
SQLiteDatabase checkDb = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDb = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
} catch (SQLException e) {
}
if (checkDb != null) {
checkDb.close();
}
return checkDb != null ? true : false;
}
public void copyDataBase() throws IOException {
InputStream myInput = myContext.getAssets().open("goldenland_2.sqlite");
String outFileName = DB_PATH + DB_NAME;
OutputStream myOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDatabase() throws SQLiteException {
String myPath = DB_PATH + DB_NAME;
db = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
}
A few things might be wrong. Does your database really exist in res/assets? Are you writing to the correct directory? Stepping through with the debugger would go a long way toward diagnosing the problem.
You might get a sanity check by having copyDatabase take a String argument, which would be this.getReadableDatabase().getPath(). You might even try writing that out to the log to see if you're writing to the correct database directory.
Few things to check.
1. in method checkDataBase open the database in OPEN_READONLY mode.
2. this is very important check that the size of the database is less than 1 mb. Android version previous to 3.0 don't allow file copy of more than 1 mb.
Update:
You will need to split the database file into parts of 1Mb each, copy all parts one by one and join them together again. refer to following link
unless you didnt put up all your code, it seems to me that you are missing somethings. I used this tutorial and had no problems
http://www.devx.com/wireless/Article/40842/1954
hope that helps

Categories