使用 ACTION_OPEN_DOCUMENT_TREE 选择文件夹时打开 sqlite 数据库
open a sqlite database when choosing folder with ACTION_OPEN_DOCUMENT_TREE
我在文件夹 /sdcard/myfolder/db/mydb.db
中已有一个 sqlite 数据库。
我的应用程序显示了一个对话框来选择一个文件夹:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, 42);
弹出对话框,我可以选择文件夹:
我选择文件夹 /sdcard/myfolder/db/ 并按 choose/ok。
我的 onActivityResult 被调用。我遍历所有文件,如果文件是我的 "mydb.db" 然后我尝试用 SQLiteDatabase.openDatabase(); 打开 sqlite 数据库;我得到一个错误(见下文)
我对问题的猜测:
这将不起作用,因为 openDatabase 需要数据库的完整路径,如 /sdcard/myfolder/db/mydb.db
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// if (requestCode == REQUEST_QUICKLIST) {
if (resultCode == Activity.RESULT_OK) {
if(requestCode==42){
// TreeDialog for choosing the Installdirectory
Uri treeUri = data.getData();
DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);
for (DocumentFile file : pickedDir.listFiles()) {
if(file.getName().equals("mydb.db")){
SQLiteDatabase sqliteTest= SQLiteDatabase.openDatabase(file.getUri().getPath(), null, SQLiteDatabase.OPEN_READONLY);
}
Log.d("DEBUG FILE", "Found file " + file.getName() + " with size " + file.length() + " " + file.getParentFile().getName());
}
file.getUri().getPath()
的值为:/tree/primary:myfolder/db/document/primary:myfolder/db/mydb.db
如何打开sqlite数据库?
堆栈跟踪:
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=42, result=-1, data=Intent { dat=content://com.android.externalstorage.documents/tree/primary:myfolder/db flg=0xc3 }} to activity {mycompany.browser/mycompany.browser.browser}: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
at android.app.ActivityThread.deliverResults(ActivityThread.java:3976)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4019)
at android.app.ActivityThread.access00(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1471)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5834)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
Caused by: 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:318)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:228)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:512)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:206)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:178)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:891)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:861)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:696)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:671)
at mycompany.browser.browser.onActivityResult(browser.java:1533)
at android.app.Activity.dispatchActivityResult(Activity.java:6475)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3972)
由于 Lollipop 设备目前不可用,我还没有测试过,但这应该可以,如果有任何问题,请告诉我!
if(file.getName().equals("mydb.db")){
Uri uri = file.getUri();
Uri docUri = DocumentsContract.buildDocumentUriUsingTree(uri,
DocumentsContract.getTreeDocumentId(uri));
String path = ASFUriHelper.getPath(this, docUri);
SQLiteDatabase sqliteTest= SQLiteDatabase.openDatabase(path, null,
SQLiteDatabase.OPEN_READONLY);
}
ASFUriHelper.getPath() 方法和中间方法的要点可以在这里找到:ASFUriHelper.getPath()
感谢您的回答。我的问题是,当我在 SD 卡上选择一个目录时,我的 HTC M8 with SD 卡上的 getPath returns NULL。
那是因为在getpath的代码中uri没有包含"primary"作为espectect :
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
对我来说,类型包含“1AF0-170C”,完整的 uri 是:
/tree/1AF0-170C:SmartDiveBook/document/1AF0-170C:SmartDiveBook/SmartDiveBook.db
我在文件夹 /sdcard/myfolder/db/mydb.db
中已有一个 sqlite 数据库。
我的应用程序显示了一个对话框来选择一个文件夹:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, 42);
弹出对话框,我可以选择文件夹:
我选择文件夹 /sdcard/myfolder/db/ 并按 choose/ok。
我的 onActivityResult 被调用。我遍历所有文件,如果文件是我的 "mydb.db" 然后我尝试用 SQLiteDatabase.openDatabase(); 打开 sqlite 数据库;我得到一个错误(见下文)
我对问题的猜测: 这将不起作用,因为 openDatabase 需要数据库的完整路径,如 /sdcard/myfolder/db/mydb.db
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// if (requestCode == REQUEST_QUICKLIST) {
if (resultCode == Activity.RESULT_OK) {
if(requestCode==42){
// TreeDialog for choosing the Installdirectory
Uri treeUri = data.getData();
DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);
for (DocumentFile file : pickedDir.listFiles()) {
if(file.getName().equals("mydb.db")){
SQLiteDatabase sqliteTest= SQLiteDatabase.openDatabase(file.getUri().getPath(), null, SQLiteDatabase.OPEN_READONLY);
}
Log.d("DEBUG FILE", "Found file " + file.getName() + " with size " + file.length() + " " + file.getParentFile().getName());
}
file.getUri().getPath()
的值为:/tree/primary:myfolder/db/document/primary:myfolder/db/mydb.db
如何打开sqlite数据库?
堆栈跟踪:
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=42, result=-1, data=Intent { dat=content://com.android.externalstorage.documents/tree/primary:myfolder/db flg=0xc3 }} to activity {mycompany.browser/mycompany.browser.browser}: android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
at android.app.ActivityThread.deliverResults(ActivityThread.java:3976)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4019)
at android.app.ActivityThread.access00(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1471)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5834)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
Caused by: 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:318)
at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:228)
at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:512)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:206)
at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:178)
at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:891)
at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:861)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:696)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:671)
at mycompany.browser.browser.onActivityResult(browser.java:1533)
at android.app.Activity.dispatchActivityResult(Activity.java:6475)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3972)
由于 Lollipop 设备目前不可用,我还没有测试过,但这应该可以,如果有任何问题,请告诉我!
if(file.getName().equals("mydb.db")){
Uri uri = file.getUri();
Uri docUri = DocumentsContract.buildDocumentUriUsingTree(uri,
DocumentsContract.getTreeDocumentId(uri));
String path = ASFUriHelper.getPath(this, docUri);
SQLiteDatabase sqliteTest= SQLiteDatabase.openDatabase(path, null,
SQLiteDatabase.OPEN_READONLY);
}
ASFUriHelper.getPath() 方法和中间方法的要点可以在这里找到:ASFUriHelper.getPath()
感谢您的回答。我的问题是,当我在 SD 卡上选择一个目录时,我的 HTC M8 with SD 卡上的 getPath returns NULL。
那是因为在getpath的代码中uri没有包含"primary"作为espectect :
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
对我来说,类型包含“1AF0-170C”,完整的 uri 是:
/tree/1AF0-170C:SmartDiveBook/document/1AF0-170C:SmartDiveBook/SmartDiveBook.db