2016-07-05 1 views
2

내가 뭘하려고 오전 내 애플 리케이션에서 만든 DB를 가지고있다. 나는 내 전화에서 동일한 DB를 복사하고있다. (내 전화기는 뿌리 째 나와 복사하여 내 Mac에 붙여 넣기가 쉽다.) 내 Mac에서 SQLite 관리자를 통해 데이터를 삽입하는 중이 야 (왜냐하면 내가 db로 csv 파일을 가져올 필요가 있기 때문에이 작업을 수행함) 나중에 동일한 데이터베이스 파일을 내 응용 프로그램 데이터베이스 폴더로 복사하고 있습니다.어떻게 내 PC에서 수정하고 내 애플 리케이션의 db 폴더에 복사 한 내 안드로이드 애플 리케이션의 db를 읽을 수

문제는 db 파일을 삽입하거나 읽으려고 할 때마다 응용 프로그램이 충돌하고 있다는 것입니다.

<?xml version="1.0" encoding="utf-8"?> 

    <manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.uttara.dbpull"> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
    <application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 
    <activity android:name=".MainActivity"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 

가 여기 내 DBhelper 클래스의 :

여기 내 매니페스트 파일입니다.

public class DHelper extends SQLiteOpenHelper { 
    private static final String DATABASE_NAME = "sampledata1"; 
    private static final String TABLE_NAME="sampledata1"; 
    private static final int DATABASE_VERSION = 1; 
    private static final String NUMBER="NUMBER"; 
    private static final String NAME = "NAME"; 
    private static final String SURNAME = "SURNAME"; 
    private static final String MARKS = "MARKS"; 
    private static final String SQL_CREATE_TABLE_SAMPLE = "CREATE TABLE  sampledata1 (NUMBER INTEGER PRIMARY KEY, NAME TEXT, SURNAME TEXT, MARKS INTEGER)"; 

    public DHelper(Context applicationcontext) { 
    super(applicationcontext, DATABASE_NAME, null, DATABASE_VERSION); 
} 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
    db.execSQL(SQL_CREATE_TABLE_SAMPLE); 

} 

@Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
    db.execSQL("DROP TABLE IF EXISTS sampledata1"); 
    onCreate(db); 

} 
    public boolean insertData(String name,String surname,String marks){ 
    SQLiteDatabase db=this.getWritableDatabase(); 
    ContentValues contentValues=new ContentValues(); 
    contentValues.put(NAME,name); 
    contentValues.put(SURNAME,surname); 
    contentValues.put(MARKS,marks); 
    long result = db.insert(TABLE_NAME,null,contentValues); 
    if (result == -1) 
     return false; 
    else 
     return true; 

} 
    public Cursor getAllData(){ 
    SQLiteDatabase db=this.getWritableDatabase(); 
    Cursor res=db.rawQuery("SELECT * FROM " +TABLE_NAME,null); 
    return res; 
} 
} 

내 MainActivity.class

public class MainActivity extends AppCompatActivity { 
DHelper myDb; 
EditText editname,editsurname,editmarks; 
Button btnadd,btnview; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    myDb=new DHelper(this); 
    editname= (EditText) findViewById(R.id.editText_name); 
    editsurname= (EditText) findViewById(R.id.editText_surname); 
    editmarks= (EditText) findViewById(R.id.editText_marks); 
    btnadd= (Button) findViewById(R.id.button_add); 
    btnview= (Button) findViewById(R.id.button_view); 
    viewAll(); 
    addData(); 

} 
public void addData(){ 
    btnadd.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      boolean isInserted= myDb.insertData(editname.getText().toString(),editsurname.getText().toString(),editmarks.getText().toString()); 
      if (isInserted==true) 
       Toast.makeText(MainActivity.this,"Data inserted",Toast.LENGTH_SHORT).show(); 

      else 
       Toast.makeText(MainActivity.this,"Data not inserted",Toast.LENGTH_SHORT).show(); 

     } 
    }); 

} 
public void viewAll(){ 
    btnview.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Cursor res= myDb.getAllData(); 
      if (res.getCount()==0){ 
       showMessage("Error","NO DATA FOUND"); 
       return; 

      } 

      StringBuffer buffer=new StringBuffer(); 
      while (res.moveToNext()){ 
       buffer.append("NUMBER :"+ res.getString(0)+"\n"); 
       buffer.append("NAME :"+ res.getString(1)+"\n"); 
       buffer.append("SURNAME :"+ res.getString(2)+"\n"); 
       buffer.append("MARKS :"+ res.getString(3)+"\n\n"); 

      } 
      showMessage("Alert",buffer.toString()); 
     } 
    }); 
} 
public void showMessage(String title,String Message){ 
    AlertDialog.Builder builder=new AlertDialog.Builder(this); 
    builder.setCancelable(true); 
    builder.setTitle(title); 
    builder.setMessage(Message); 
    builder.show(); 
    } 
} 

로그 캣 :

E/SQLiteDatabase: Failed to open database '/data/user/0/com.uttara.dbpull/databases/sampledata1'. 
android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database 
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method) 
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:237) 
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:221) 
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:468) 
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:190) 
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:182) 
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:876) 
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:856) 
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:754) 
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:579) 
at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:269) 
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223) 
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163) 
at com.uttara.dbpull.DHelper.getAllData(DHelper.java:55) 
at com.uttara.dbpull.MainActivity$2.onClick(MainActivity.java:50) 
at android.view.View.performClick(View.java:5226) 
at android.view.View$PerformClick.run(View.java:21266) 
at android.os.Handler.handleCallback(Handler.java:739) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:168) 
at android.app.ActivityThread.main(ActivityThread.java:5845) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687) 

    --------- beginning of crash 
    07-05 11:29:06.732 16734-16734/com.uttara.dbpull E/AndroidRuntime:   FATAL EXCEPTION: main Process: com.uttara.dbpull, PID: 16734 
android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database 
at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method) 
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:237) 
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:221) 
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:468) 
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:190) 
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:182) 
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:856) 
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:754) 
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:579) 
at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:269) 
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:223) 
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163) 
at com.uttara.dbpull.DHelper.getAllData(DHelper.java:55) 
at com.uttara.dbpull.MainActivity$2.onClick(MainActivity.java:50) 
at android.view.View.performClick(View.java:5226) 
at android.view.View$PerformClick.run(View.java:21266) 
at android.os.Handler.handleCallback(Handler.java:739) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:168) 
at android.app.ActivityThread.main(ActivityThread.java:5845) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687) 

답변

0

우선 안드로이드 응용 프로그램 및 모범 사례에 기존 데이터베이스 스키마를 복사하는 것은되도록 SQLite DB 처리하는 방법을 설명합니다 다른 사람들에게도 도움이 될 것입니다. 이 방법은 정적 데이터베이스 스키마가있을 때 유용합니다.

안드로이드 응용 프로그램에서 데이터베이스 개체를 사용하는 것이 좋습니다 응용 프로그램 수준에서 만들고 응용 프로그램을 통해 그것을 사용하십시오.

- :

public class MyApplication extends Application{ 
    public DBHelper dbHelper; 
    @Override 
    public void onCreate() { 
     super.onCreate(); 
     dbHelper = new DBHelper(getApplicationContext()); 
      try { 
       dbHelper.createDataBase(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
    } 
} 

application에 AndroidManifest를 파일에서 응용 프로그램의 이름을 언급하는 것을 잊었다하지 마십시오 응용 프로그램의 클래스 이름하여 MyApplication이고 그 다음이되어야한다 com.app 패키지에있는 tag.Suppose android : name = "com.app.MyApplication"

다음은 응용 프로그램과 로컬 데이터베이스 사이의 다리 역할을하는 DBHelper 클래스입니다.

public class DBHelper extends SQLiteOpenHelper{ 
    public static final String DATABASE_NAME = "Your database name"; 
    public static final int DATABASE_VERSION = 1; 
    private static String DB_PATH = ""; 
    private SQLiteDatabase mDataBase; 
    private final Context mContext; 

/** 
    * Called when the database is created for the first time. This is where the 
    * creation of tables and the initial population of the tables should happen. 
    * 
    * @param db The database. 
    */ 
    @Override 
    public void onCreate(SQLiteDatabase db) { 

} 

/** 
* Called when the database needs to be upgraded. The implementation 
* should use this method to drop tables, add tables, or do anything else it 
* needs to upgrade to the new schema version. 
* <p/> 
* <p> 
* The SQLite ALTER TABLE documentation can be found 
* <a href="http://sqlite.org/lang_altertable.html">here</a>. If you add new columns 
* you can use ALTER TABLE to insert them into a live table. If you rename or remove columns 
* you can use ALTER TABLE to rename the old table, then create the new table and then 
* populate the new table with the contents of the old table. 
* </p><p> 
* This method executes within a transaction. If an exception is thrown, all changes 
* will automatically be rolled back. 
* </p> 
* 
* @param db   The database. 
* @param oldVersion The old database version. 
* @param newVersion The new database version. 
*/ 
@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 

} 

/** 
    * Create a helper object to create, open, and/or manage a database. 
    * This method always returns very quickly. The database is not actually 
    * created or opened until one of {@link #getWritableDatabase} or 
    * {@link #getReadableDatabase} is called. 
    * 
    * @param context to use to open or create the database 
    */ 
    public DBHelper(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
     if(android.os.Build.VERSION.SDK_INT >= 17){ 
      DB_PATH = context.getApplicationInfo().dataDir + "/databases/"; 
     } 
     else 
     { 
      DB_PATH = "/data/data/" + context.getPackageName() + "/databases/"; 
     } 
     this.mContext = context; 
    } 

/** 
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 
    */ 
    public boolean checkDataBase(){ 

    SQLiteDatabase checkDB = null; 

    try{ 
     String myPath = DB_PATH + DATABASE_NAME; 
     checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 

    }catch(SQLiteException e){ 

     //database does't exist yet. 

    } 

    if(checkDB != null){ 

     checkDB.close(); 

    } 

    return checkDB != null ? true : false; 
} 
/** 
* Creates a empty database on the system and rewrites it with your own database. 
* */ 
public void createDataBase() throws IOException { 

    boolean dbExist = checkDataBase(); 

    if(dbExist){ 
     //do nothing - database already exist 
    }else{ 
     //By calling this method and empty database will be created into the default system path 
     //of your application so we are gonna be able to overwrite that database with our database. 
     this.getReadableDatabase(); 

     try { 

      copyDataBase(); 

     } catch (IOException e) { 

      throw new Error("Error copying database"); 

     } 
    } 

} 
/** 
* 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 transfering bytestream. 
* */ 
private void copyDataBase() throws IOException{ 

    //Open your local db as the input stream 
    InputStream myInput = mContext.getAssets().open(DATABASE_NAME+".sqlite"); 

    // Path to the just created empty db 
    String outFileName = DB_PATH + DATABASE_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(); 

} 

public void openDataBase() throws SQLException { 
    //Open the database 
    String myPath = DB_PATH + DATABASE_NAME; 
    mDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 

} 

@Override 
public synchronized void close() { 

    if(mDataBase != null) 
     mDataBase.close(); 

    super.close(); 
} 
} 

이제 문제를 해결할 수 있습니다. 당신은 당신의 활동에서 데이터베이스를 열고, 데이터베이스 작업을하고, 작업을 마친 후에 그것을 닫아야합니다. 다음은 코드 스 니펫입니다. -

MyApplication application = (MyApplication) getApplicationContext(); 
application.dbHelper.openDataBase(); 
boolean isInserted=application.dbHelper.insertData(editname.getText().toString(),editsurname.getText().toString(),editmarks.getText().toString()); 
application.dbHelper.close(); 

이 정보가 도움이되기를 바랍니다.

+0

commnets에서 downvote의 이유를 자세히 설명합니다. 내 대답을 업데이트하는 것이 도움이 될 것입니다. –

관련 문제