在模拟器中,db文件位于/data/data/com.example.app_name/databases/data.db中。但在实际设备中没有这样的目录。由于哪个应用程序崩溃。应用程序在模拟器中运行顺利。
在真实设备中存在android / data文件夹但它不包含我的应用程序命名文件夹。
此外,当我通过toast在设备内部通过this.getDatabasePath()显示应用程序目录时,它会显示//data/data/com.example.My_App但数据库活动启动时应用程序崩溃。并且android / data中不存在com.example.My_App文件夹。
我已经尝试在android / data中创建数据文件夹并将所有数据库文件放入其中但仍然无效。还尝试在手机内存中创建它,其中android文件夹存在但没有任何反应。 请帮帮我。 答案将不胜感激。
答案 0 :(得分:2)
克服此问题您可以在移动设备的SD卡中创建数据库。它工作顺利,也可由用户访问。如果涉及安全性,请使用res / raw文件夹,以便User不访问它。 要在SD卡上创建数据库,您可以使用以下代码(它是示例代码)...
public static void saveExpanseForm(Context con,NewExpenseForm newexpanse) throws Exception {
SQLiteDatabase sampleDB = null;
try {
File sdcard;
if (android.os.Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED)){
sdcard = new File(Environment.getExternalStorageDirectory(), "ROIApp");
sdcard.mkdirs();
} else {
/* save the folder in internal memory of phone */
sdcard = new File(Environment.getRootDirectory(),"ROIApp");
sdcard.mkdirs();
}
String dbfile = sdcard.getAbsolutePath() + File.separator+ "RoiAppDB" + File.separator + NETNOTENABLE_DB_NAME;
sampleDB = con.openOrCreateDatabase(dbfile, MODE_PRIVATE,null);
sampleDB.execSQL("CREATE TABLE IF NOT EXISTS " + Expense_TABLE_NAME +
" (id INTEGER PRIMARY KEY AUTOINCREMENT, Currentdate varchar, dateFormat varchar, Name varchar, Category varchar,"+
" Location varchar,Cost varchar,Sex INTEGER, Tags varchar, Notes varchar, In1 varchar, In2 varchar, " +
"Remindme INTEGER, ImagePath varchar);");
sampleDB.execSQL("INSERT INTO " + Expense_TABLE_NAME +
"(Currentdate, dateFormat, Name, Category, Location,Cost, Sex, Tags, Notes, In1, In2, Remindme, ImagePath ) Values ('"
+newexpanse.getDates()+"','"+newexpanse.getDateFormat()+"','"+newexpanse.getName()+"','"+
newexpanse.getCategory()+"','"+newexpanse.getLocation()+"','"+newexpanse.getCost()+"','"+newexpanse.getSex()+"','"+newexpanse.getTag()+"','"
+newexpanse.getNotes()+"','"+newexpanse.getInstr1()+"','"+newexpanse.getInstr2()+"','"
+newexpanse.getRemindme()+"','"+newexpanse.getImageName()+"');");
Log.e("ExpanseTable", " ExpanseInsert "+"INSERT INTO " + Expense_TABLE_NAME +
"(Currentdate, dateFormat, Name, Category, Location,Cost, Sex, Tags, Notes, In1, In2, Remindme,ImagePath ) Values ('"
+newexpanse.getDates()+"','"+newexpanse.getDateFormat()+"','"+newexpanse.getName()+"','"+
newexpanse.getCategory()+"','"+newexpanse.getLocation()+"','"+newexpanse.getCost()+"','"+newexpanse.getSex()+"','"+newexpanse.getTag()+"','"
+newexpanse.getNotes()+"','"+newexpanse.getInstr1()+"','"+newexpanse.getInstr2()+"','"
+newexpanse.getRemindme()+"','"+newexpanse.getImageName()+"');");
insertNewExpanseForm(sampleDB);
} catch (SQLiteException e) {
// TODO: handle exception
e.printStackTrace();
}
finally {
if (sampleDB != null)
sampleDB.close();
}
}
答案 1 :(得分:1)
尝试此示例类将数据库从资源复制到应用程序包,并将数据库从应用程序包拉到SD卡路径
DBHelper.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Environment;
import android.util.Log;
public class DBHelper extends SQLiteOpenHelper {
private static String DB_PACKAGE_PATH = "/data/data/applicationPackageName/databases/";
private static String DATABASE_NAME = "data.db";
private SQLiteDatabase db;
private final Context context;
/**
*
* @param context
*/
public DBHelper(final Context context) {
super(context, DATABASE_NAME, null, 1);
this.context = context;
DB_PACKAGE_PATH = "/data/data/" + context.getPackageName()
+ "/databases/";
}
public final void createDataBaseFromAppAssetsDir() throws IOException {
final boolean dbExist = isDBExist();
SQLiteDatabase db_Read = null;
if (!dbExist) {
// ****** required****
// as it will create empty database file.
// and assets file will be overwrite on this db file
db_Read = this.getReadableDatabase();
db_Read.close();
try {
copyDbFile();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
public void copyFromDataPackgeToSdCard() throws IOException {
try {
File sdCard = Environment.getExternalStorageDirectory();
File appDataDir = Environment.getDataDirectory();
if (sdCard.canWrite()) {
String currentDBPath = "//data//"
+ this.context.getPackageName() + "//databases//"
+ DATABASE_NAME;
String backupDBPath = DATABASE_NAME;
File currentDatabase = new File(appDataDir, currentDBPath);
File backupDatabase = new File(sdCard, backupDBPath);
if (currentDatabase.exists()) {
FileChannel src = new FileInputStream(currentDatabase)
.getChannel();
FileChannel dst = new FileOutputStream(backupDatabase)
.getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
}
}
} catch (Exception e) {
Log.e("copyFromDataPackgeToSdCard", e.getMessage());
}
}
private boolean isDBExist() {
final File dbFile = new File(DB_PACKAGE_PATH + DATABASE_NAME);
return dbFile.exists();
}
private void copyDbFile() throws IOException {
final InputStream myInput = context.getAssets().open(DATABASE_NAME);
final String outFileName = DB_PACKAGE_PATH + DATABASE_NAME;
final OutputStream myOutput = new FileOutputStream(outFileName);
final 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 final void openDataBase() throws Exception {
final String myPath = DB_PACKAGE_PATH + DATABASE_NAME;
db = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
}
@Override
public final synchronized void close() {
if (db != null)
db.close();
super.close();
}
@Override
public void onCreate(final SQLiteDatabase arg0) {
}
@Override
public void onUpgrade(final SQLiteDatabase arg0, final int arg1,
final int arg2) {
}
}
致电创建数据库&复制数据库
@Override
public void onClick(View v) {
try {
switch (v.getId()) {
case R.id.btn_create_db_from_assets:
// Create DataBase From Assets Folder to Application database
// package . u can call this on startup.Use this onStart up
clsHelper.createDataBaseFromAppAssetsDir();
break;
case R.id.btn_copy_to_sdcard:
// Copy database from applicaiton data packages to sd card. to
// avid root access and all for device
clsHelper.copyFromDataPackgeToSdCard();
break;
default:
break;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
答案 2 :(得分:0)
在真正的Android设备中,您将无法访问数据文件夹。你需要一个有根设备。
答案 3 :(得分:0)
我建议您压缩数据库文件,并将其放在应用程序的res / raw目录中。并做这样的事情;
// Call this whenever the application starts, or at another suitable place, for example in a
// Content providers create method.
public void createDataBaseIfDoesNotExist() throws IOException {
boolean dbExist = doesDatabaseExist();
if (!dbExist) {
try {
copyDataBase();
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
throw new Error("Error copying database ");
}
}
}
// Extracts the Compressed database file to the database directory of your application
private void copyDataBase() throws IOException {
InputStream myInput = myContext.getResources().openRawResource(R.raw.abbrev);
ZipInputStream zis = new ZipInputStream(myInput);
zis.getNextEntry();
File outFile = myContext.getDatabasePath(DATABASE_NAME);
OutputStream myOutput = new FileOutputStream(outFile);
byte[] buffer = new byte[1024];
int length;
while ((length = zis.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
// Checks if database exists
private boolean doesDatabaseExist() {
SQLiteDatabase checkDB = null;
try {
String myPath =myContext.getDatabasePath(DATABASE_NAME).toString();
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
答案 4 :(得分:0)
您必须拥有手机以访问应用程序数据库文件,即使这样您也必须更改数据/中文件夹的访问权限。如果要在SD卡或资产文件夹中打开并读取某些db文件,则可以在不生根的情况下执行此操作。