0

I have issues in copying database file from /assets to /data/data folder in file explorer. I have searched this website, found many answers, but could not find the appropriate answer that suits my context. I have created the database externally with SQLite Manager and imported it into assets folder. Now, when I run my application, I am getting NullPointerException in the emulator. I found that the package has not created in /data/data folder at all. But the application is launching in the emulator. The debugger also did not show any errors.

I have tried the following solutions -

Restarted eclipse and emulator, deleted and recreated existing emulator, finally restarted laptop

None of the solutions solved my problem. Can any one please tell me, whats my mistake?

Here is my MainActivity.java :-

public class MainActivity extends Activity implements OnClickListener
{
Dialog d;
private photoDbAdapters mDbAdapter;
public int currentimageindex=0;
 String[] sp;   

int p=1;

 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        images();
 }
 public void images()
 {
        try{
            String rt=mDbAdapter.fetchsingles(); //the application 
                                           is getting crashed in this part

        int id = getResources().getIdentifier(rt, null, null);
        ImageView iv = (ImageView) findViewById(R.id.ImageView3_Left);
        iv.setImageResource(id);
    }catch(NullPointerException er)
{
        String ht=er.toString();
        Toast.makeText(getApplicationContext(), ht, Toast.LENGTH_LONG).show    ();
    }}


@Override
public void onClick(View v)
{
    finish();
    android.os.Process.killProcess(android.os.Process.myPid());
    // TODO Auto-generated method stub
}

fetchsingles method :- (this method will retreive image file name from database)

public String fetchsingles()
{

    try{

img = mDbHelper.getData();


    }catch(Exception e)
    {
        String error= e.toString();
        Dialog d = new Dialog(null);
        d.setTitle("image cannot be fetched");
        int err=Integer.parseInt(error);
        d.setContentView(err);
        d.show();
    }
    return img;


}

getdata method:-

public String getData() 
{
    // TODO Auto-generated method stub

    String dry="SELECT "+COL_DATA+" FROM Photos WHERE "+COL_ID+"=2;";

        Cursor c = myDataBase.rawQuery(dry,null);

        String result = "";
        int img = c.getColumnIndex(COL_DATA);


            result = c.getString(img);





    return dry;

The code might look lengthy, don't mind anything and please help me in solving this problem.

Thanks in advance.

nki
  • 192
  • 2
  • 17
  • possible duplicate of [problem in copying data from assets to application](http://stackoverflow.com/questions/6609186/problem-in-copying-data-from-assets-to-application) – LOG_TAG Aug 29 '13 at 08:55
  • Only put the code as mentioned it the question "copying database file from /assets to /data/data folder" remove unwanted codes and make it simple, also search in stackoverflow for answers before asking the question ! – LOG_TAG Aug 29 '13 at 08:58
  • actually, I have searched many questions, tried all those solutions. But, every time the application crashes unexpectedly. – nki Aug 29 '13 at 09:20
  • I have already tried the solution in the link you have sent to me. But, any how, thanks for replying with a solution. – nki Aug 29 '13 at 09:23
  • only put the code which is you tried remove unwanted codes.. first step is to push the db file to internal storage DB path, make sure you have put the right String DB_PATH DB_NAME correctly also same file, file format in assets ! before trying to run the code next time please uninstall or remove the DB file from DB path at the DDMS – LOG_TAG Aug 29 '13 at 09:36
  • what do you mean by internal storage? is it, "\data\data\com.example.activityscsaver\databases" ? – nki Aug 29 '13 at 10:06

1 Answers1

1

Try using below code to copy database from assets to data/data/package directory

package com.example.myapp;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

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

      public class DataBaseHelper1 extends SQLiteOpenHelper{
      private static String DB_PATH = "/data/data/com.example.myapp/databases/";

      private static String DB_NAME = "myDB.sqlite";

      private SQLiteDatabase myDataBase;

      private final Context myContext;

      public DataBaseHelper1(Context context) 
      {
          super(context, DB_NAME, null, 1);
          this.myContext = context;
      }

      public void createDataBase() throws IOException{


    boolean dbExist = checkDataBase();

      if(dbExist)
      {
          Log.i("DB....", "database available....");
      }
      else
      {
          this.getWritableDatabase();

          try {

          copyDataBase();

          } catch (IOException e) {

          throw new Error("Error copying database");

          }

         Log.i("DB..", "database created.....");
       }   

      }


      public boolean checkDataBase(){

      SQLiteDatabase checkDB = null;

      try{

      String myPath = DB_PATH + DB_NAME;

      checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);

      }catch(SQLiteException e){

          Log.e("CheckDb","DB not found");
      //database does't exist yet.

      if(checkDB != null){

      checkDB.close();

      }
      }
      finally
      {
          if(checkDB != null){

              checkDB.close();

              } 
          this.close();
      }
      return checkDB != null ? true : false;

      }




      private void copyDataBase() throws IOException{

      InputStream myInput = myContext.getAssets().open(DB_NAME);

      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 SQLiteDatabase openDataBase() throws SQLException{

      String myPath = DB_PATH + DB_NAME;

      return myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);

      }


      @Override

      public synchronized void close() {

      if(myDataBase != null)

      myDataBase.close();

      super.close();

      }

      @Override

      public void onCreate(SQLiteDatabase db) {

      }

      @Override

      public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {


      }  


      public void getData()
      {
          SQLiteDatabase myDB ;
          Cursor cursor ;
           try {

                myDB=this.openDataBase();                   

                    cursor=myDB.rawQuery("SELECT * FROM Country_Master",null);


                    if (cursor != null ) {
                       if  (cursor.moveToFirst()) {
                       do {

                           // put your code to get data from cursor                      

                       }while (cursor.moveToNext());
                       }

                    }



                   if(cursor != null)
                    {
                        myDB.close();
                       cursor.close();
                    }                      
                    }catch(SQLException sqle){

                    throw sqle;

                    }


        }
}

Also put this code under onCreate method in your activity where you want to copy database..

 DataBaseHelper1 myDbHelper = new DataBaseHelper1(MyActivity.this); 
     try 
     {
         myDbHelper.createDataBase();
     }catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            }

     finally
     {
         myDbHelper.close();
     }
Chirag Ghori
  • 4,075
  • 2
  • 16
  • 34
  • Thank you @Chirag Ghori, I have tried the same code previously, but my app did not run properly. – nki Aug 29 '13 at 09:21
  • if you don't mind anything, I'll tell one thing. If your answer solved my problem, I'll defenetly accept your answer. – nki Aug 29 '13 at 09:29
  • 1
    @nki make sure you have put the right String DB_PATH DB_NAME correctly also same file, file format in assets ! bfore trying next time please uninstall or remove the DB file from DB path at the DDMS – LOG_TAG Aug 29 '13 at 09:30
  • @ChiragGhori update the code How to use it in activity it is helpful to the nki – LOG_TAG Aug 29 '13 at 09:37
  • Thank you @LOG_TAG, I have checked the DB_PATH, "/data/data/com.example.activityscsaver/databases/", but I suspect that, this works only when the databases folder is created in that path. It means that, this works only when the package is created in the file explorer. Right? But, in my app, the package itself not created in the file explorer, then what should I do with this path?? – nki Aug 29 '13 at 09:50
  • When you run your application its create automatically also see my edited code to copy database from activity...i hope it will done for you... – Chirag Ghori Aug 29 '13 at 09:52
  • I have run the application, I have put the error prone code in try block and so I can see the exception in a toast message. The apk also loaded on to emulator, then why it is not showing me the package in the file explorer? any idea about that? Sorry @Chirag Ghori, I have tried your code, but facing the same problem. I think if the package is created in the file explorer, the problem might get solved. isn't it? – nki Aug 29 '13 at 09:57
  • yes you are right so just try again after clean your project and if possible create new emulator...it might helps you.. – Chirag Ghori Aug 29 '13 at 10:04
  • I have cleaned the project, created new emulator. But now also the package has not created. – nki Aug 29 '13 at 10:12
  • Is there any option to create package manually? any idea about that? – nki Aug 29 '13 at 10:13
  • this may help you to create database folder under your package folder.. [http://stackoverflow.com/questions/4867379/android-eclipse-ddms-cant-access-data-data-on-phone-to-pull-files] – Chirag Ghori Aug 29 '13 at 10:32
  • I have tried this already in the morning, sorry @Chirag Ghori, no change at all. – nki Aug 29 '13 at 10:41
  • Mean while I got doubt on DB_PATH, whether it is correct, or not. I tried to pass that string DB_PATH to a function in MainActivity.java, which takes that string and sets it in a textview, as well as toast message. I put this function call in try catch block. As expected, this returned me null pointer exception means, the problem lies in DB_PATH. But my DB_PATH = "/data/data/com.example.fromstart/databases" as usual. What might be wrong with this? – nki Aug 29 '13 at 14:28
  • @nki Your DB_PATH must contain your application package name so make sure with that DB_PATH = "/data/data/your_package_name/databases" – Chirag Ghori Aug 30 '13 at 04:13
  • After some changes in the code, I found out that, there is no problem with DB_PATH. But, that value in DB_PATH is not getting passed into the MainActivity. – nki Aug 30 '13 at 05:48
  • why you need to pass it in MainActivity you just put code for createdatabase in your MainActivity see updated answer where you found code for MainActivity. – Chirag Ghori Aug 30 '13 at 05:53
  • createdatabase code in MainActivity? Actually, wanted to check whether the DB_PATH is correct or not, thats why I have tried to display that path as a hardcoded string on a textview of mainactivity. If this works, in the same method, i can make my code return the value from DB and display it in mainactivity. Is there any thing needed additionally, to pass values from one class to another?? – nki Aug 30 '13 at 05:58
  • Use declaration static String DB_PATH instead of private static String DB_PATH. means you must remove private from String declaration. – Chirag Ghori Aug 30 '13 at 06:10
  • This also did not work for me. Can you please give me sample code, where a function returns some string value in class1.java and in class2.java, a variable stores that value returned by the function in class1.java – nki Aug 30 '13 at 06:17
  • see this link ...http://stackoverflow.com/questions/11830589/passing-a-method-from-another-class – Chirag Ghori Aug 30 '13 at 06:29
  • Thank you @Chirag Ghori, for sending the link, but I am sorry that this one also did not work for me. – nki Aug 30 '13 at 06:43