Java 使用Environment.getExternalStorageDirectory().getAbsolutePath()设置路径
我想将数据库与apk文件一起存储,但当我试图硬编码路径时,应用程序似乎找不到数据库 我用它来硬编码路径,但不起作用Java 使用Environment.getExternalStorageDirectory().getAbsolutePath()设置路径,java,android,eclipse,Java,Android,Eclipse,我想将数据库与apk文件一起存储,但当我试图硬编码路径时,应用程序似乎找不到数据库 我用它来硬编码路径,但不起作用 private final String DB_PATH="/data/data/com.example.shopkart/databases/"; private final String Db_NAME = "dbshopkart.db"; 如何使用Environment.getExternalStorageDirectory().getAbsolute
private final String DB_PATH="/data/data/com.example.shopkart/databases/";
private final String Db_NAME = "dbshopkart.db";
如何使用Environment.getExternalStorageDirectory().getAbsolutePath()
请帮忙
编辑:我的datamanager类
public class openingclass extends SQLiteOpenHelper {
public openingclass(Context c) {
super(c, Db_NAME, null, DB_VERSION);
createDataBase();
}
public void createDataBase() {
boolean dbExist;
try {
dbExist = checkDataBase();
} catch (SQLiteException e) {
e.printStackTrace();
throw new Error("database dose not exist");
}
if (dbExist) {
//do nothing - database already exist
} else {
try {
copyDataBase();
} catch (IOException e) {
e.printStackTrace();
throw new Error("Error copying database");
}
//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();
}
}
/**
* 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;
try {
String myPath = DB_PATH + "/" + Db_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
//database does't exist yet.
throw new Error("database does't exist yet.");
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* 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 {
//copyDataBase();
//Open your local db as the input stream
InputStream myInput = c1.getAssets().open(Db_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + "/" + Db_NAME;
File databaseFile = new File(DB_PATH);
// check if databases folder exists, if not create one and its subfolders
if (!databaseFile.exists()) {
databaseFile.mkdir();
}
//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();
}
@Override
public synchronized void close() {
if (myDataBase != null)
myDataBase.close();
super.close();
}
日志:
05-03 11:26:21.713: E/Database(4612): sqlite3_open_v2("/data/data/com.example.shopkart/databases/dbshopkart.db", &handle, 1, NULL) failed
05-03 11:26:21.713: W/dalvikvm(4612): threadid=1: thread exiting with uncaught exception (group=0x40015578)
05-03 11:26:21.721: E/AndroidRuntime(4612): FATAL EXCEPTION: main
05-03 11:26:21.721: E/AndroidRuntime(4612): java.lang.Error: database does't exist yet.
05-03 11:26:21.721: E/AndroidRuntime(4612): at com.example.shopkart.datamanager$openingclass.checkDataBase(datamanager.java:114)
05-03 11:26:21.721: E/AndroidRuntime(4612): at com.example.shopkart.datamanager$openingclass.createDataBase(datamanager.java:65)
05-03 11:26:21.721: E/AndroidRuntime(4612): at com.example.shopkart.datamanager$openingclass.<init>(datamanager.java:57)
05-03 11:26:21.721: E/AndroidRuntime(4612): at com.example.shopkart.datamanager.<init>(datamanager.java:48)
05-03 11:26:21.721: E/AndroidRuntime(4612): at com.example.shopkart.MainActivity.onCreate(MainActivity.java:50)
05-03 11:26:21.721: E/AndroidRuntime(4612): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-03 11:26:21.721: E/AndroidRuntime(4612): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
05-03 11:26:21.721: E/AndroidRuntime(4612): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
05-03 11:26:21.721: E/AndroidRuntime(4612): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
05-03 11:26:21.721: E/AndroidRuntime(4612): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
05-03 11:26:21.721: E/AndroidRuntime(4612): at android.os.Handler.dispatchMessage(Handler.java:99)
05-03 11:26:21.721: E/AndroidRuntime(4612): at android.os.Looper.loop(Looper.java:130)
05-03 11:26:21.721: E/AndroidRuntime(4612): at android.app.ActivityThread.main(ActivityThread.java:3689)
05-03 11:26:21.721: E/AndroidRuntime(4612): at java.lang.reflect.Method.invokeNative(Native Method)
05-03 11:26:21.721: E/AndroidRuntime(4612): at java.lang.reflect.Method.invoke(Method.java:507)
05-03 11:26:21.721: E/AndroidRuntime(4612): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
05-03 11:26:21.721: E/AndroidRuntime(4612): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
05-03 11:26:21.721: E/AndroidRuntime(4612): at dalvik.system.NativeStart.main(Native Method)
05-03 11:26:21.713:E/Database(4612):sqlite3\u open\u v2(“/data/data/com.example.shopkart/databases/dbshopkart.db”,&handle,1,NULL)失败
05-03 11:26:21.713:W/dalvikvm(4612):threadid=1:线程以未捕获异常退出(组=0x40015578)
05-03 11:26:21.721:E/AndroidRuntime(4612):致命异常:主
05-03 11:26:21.721:E/AndroidRuntime(4612):java.lang.Error:数据库尚不存在。
05-03 11:26:21.721:E/AndroidRuntime(4612):位于com.example.shopkart.datamanager$openingclass.checkDataBase(datamanager.java:114)
05-03 11:26:21.721:E/AndroidRuntime(4612):在com.example.shopkart.datamanager$openingclass.createDataBase(datamanager.java:65)
05-03 11:26:21.721:E/AndroidRuntime(4612):在com.example.shopkart.datamanager$openingclass.(datamanager.java:57)
05-03 11:26:21.721:E/AndroidRuntime(4612):位于com.example.shopkart.datamanager.(datamanager.java:48)
05-03 11:26:21.721:E/AndroidRuntime(4612):在com.example.shopkart.MainActivity.onCreate(MainActivity.java:50)
05-03 11:26:21.721:E/AndroidRuntime(4612):在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-03 11:26:21.721:E/AndroidRuntime(4612):在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
05-03 11:26:21.721:E/AndroidRuntime(4612):在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
05-03 11:26:21.721:E/AndroidRuntime(4612):在android.app.ActivityThread.access$1500(ActivityThread.java:117)
05-03 11:26:21.721:E/AndroidRuntime(4612):在android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
05-03 11:26:21.721:E/AndroidRuntime(4612):在android.os.Handler.dispatchMessage(Handler.java:99)上
05-03 11:26:21.721:E/AndroidRuntime(4612):在android.os.Looper.loop(Looper.java:130)上
05-03 11:26:21.721:E/AndroidRuntime(4612):位于android.app.ActivityThread.main(ActivityThread.java:3689)
05-03 11:26:21.721:E/AndroidRuntime(4612):位于java.lang.reflect.Method.Invokenactive(本机方法)
05-03 11:26:21.721:E/AndroidRuntime(4612):在java.lang.reflect.Method.invoke(Method.java:507)
05-03 11:26:21.721:E/AndroidRuntime(4612):在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
05-03 11:26:21.721:E/AndroidRuntime(4612):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
5-03 11:26:21.721:E/AndroidRuntime(4612):在dalvik.system.NativeStart.main(本机方法)
您应该使用方法getDatabasePath()
由于您在上下文中作为构造函数中的参数c
发送,因此可以使用c.getDatabasePath()获取路径。如果您在其他地方需要它,只需将其另存为类成员即可。或者,您可以将您的上下文另存为成员,并在以后的通话中使用该成员。所有应用(根或非根)都有一个默认数据目录,即/data/data/
。默认情况下,应用程序数据库、设置和所有其他数据都位于此处
默认情况下,数据库将仅存储在data/data/com.example.shopkart/databases/
目录中。您可以使用文件资源管理器查看它。不需要指定显式路径
所以您不需要指定路径“/data/data/com.example.shopkart/databases/”代码>。还有关于Environment.getExternalStorageDirectory().getAbsolutePath()
的问题,因此它用于指定外部存储路径
如果您希望将数据库存储在SD卡中,则只有您可以选择环境.getExternalStorageDirectory().getAbsolutePath()
,否则默认情况下,您的数据库将存储在/data/data/com.example.shopkart/databases/“
中,尽管您没有指定
看看这个网站,你会知道的
编辑:
请为您的数据库助手类尝试以下代码
public class DataBaseHelper extends SQLiteOpenHelper{
private Context mycontext;
private static String DB_NAME ="dbshopkart.db"; //the extension may be .sqlite or .db
public SQLiteDatabase myDataBase;
public DataBaseHelper(Context context) throws IOException {
super(context,DB_NAME,null,1);
this.mycontext=context;
ContextWrapper cw =new ContextWrapper(getApplicationContext());
private static String DB_PATH =cw.getFilesDir().getAbsolutePath() + "/Database/";
boolean dbexist = checkdatabase();
if(dbexist)
{
//System.out.println("Database exists");
opendatabase();
}
else
{
System.out.println("Database doesn't exist");
createdatabase();
}
}
public void createdatabase() throws IOException{
boolean dbexist = checkdatabase();
if(dbexist)
{
//System.out.println(" Database exists.");
}
else{
this.getReadableDatabase();
try{
copydatabase();
}
catch(IOException e){
throw new Error("Error copying database");
}
}
}
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;
}
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 byte to inputfile to 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 + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(mypath, null, SQLiteDatabase.OPEN_READWRITE);
}
public synchronized void close(){
if(myDataBase != null){
myDataBase.close();
}
super.close();
}
getDatabasePath方法因我的类错误而未定义!!有什么问题吗?请至少提一提。我在应用程序中用于所有数据库操作的datamanager类是一个普通java类,它不扩展活动。因此,如何在那里使用有效的上下文?不应假定数据库路径是实现类罚款,除非您有一个依赖于根黑客的文件资源管理器,或者正在查看文件资源管理器应用程序的数据库路径而不是应用程序的数据库路径,否则您无法使用文件资源管理器查看该文件。@AchuthanM如果文件资源管理器崩溃,请发布您的logcat错误。是的,但这只能在从上下文继承的类中使用,可能只有在完全启动后才能使用。否既然你已经为你的类添加了代码,我已经相应地修改了我的答案。因为你的数据库在内部存储上,所以外部存储发现方法不适用。Scott的答案中给出的内部存储发现方法可以工作,但你必须在有效的上下文中使用它。如果你在没有在扩展上下文时,您可能需要传入应用程序或活动类的上下文,或者只需在其中获取路径并传入。将数据库从资产复制到需要为设备上的android安装查找正确数据库路径的文件,实际上是您的方法,所以您可能需要这样做将需要向传递有效的上下文。而您的崩溃似乎是因为您试图在创建数据库之前通过从资源中复制它来检查数据库(或者将它复制到wr)