如何使用原生 android file-open-dialog?
How to use native android file-open-dialog?
我在某些应用程序中看到 pick/open 一个文件 android 的对话框,在我看来它是本机的。但是我找不到在我自己的应用程序中使用它的方法。所附屏幕截图的语言是德语,但我相信有人会认出它。
Screenshot of the file-dialog
这似乎是 the Storage Access Framework 的系统 UI。您可以使用 ACTION_OPEN_DOCUMENT
允许用户打开现有文档,或使用 ACTION_CREATE_DOCUMENT
允许用户创建新文档。
但是,这不是 文件 UI。这是一个内容UI。用户可以浏览非本地存储的内容——在屏幕截图中,用户可以浏览他们的 Google Drive 和 One Drive 区域。而且,你得到的是 a Uri
pointing to content, not a file path.
您可以使用具有 MIME 类型 */*
的意图 ACTION_GET_CONTENT。
它将return onActivityResult()
中的URI
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent()
.setType("*/*")
.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select a file"), 123);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 123 && resultCode == RESULT_OK) {
Uri selectedfile = data.getData(); //The uri with the location of the file
}
}
参见Android developer documents and files documentations。
在 Kotlin 中你可以 launch file open dialog like that:
/**
* Starts bookmarks import workflow by showing file selection dialog.
*/
private fun showImportBookmarksDialog() {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "*/*" // That's needed for some reason, crashes otherwise
putExtra(
// List all file types you want the user to be able to select
Intent.EXTRA_MIME_TYPES, arrayOf(
"text/html", // .html
"text/plain" // .txt
)
)
}
bookmarkImportFilePicker.launch(intent)
// See bookmarkImportFilePicker declaration below for result handler
}
// Assuming you have context access as a fragment or an activity
val bookmarkImportFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
// Using content resolver to get an input stream from selected URI
// See: https://commonsware.com/blog/2016/03/15/how-consume-content-uri.html
result.data?.data?.let{ uri ->
context?.contentResolver?.openInputStream(uri).let { inputStream ->
val mimeType = context?.contentResolver?.getType(uri)
// TODO: do your stuff like check the MIME type and read from that input stream
}
}
}
我在某些应用程序中看到 pick/open 一个文件 android 的对话框,在我看来它是本机的。但是我找不到在我自己的应用程序中使用它的方法。所附屏幕截图的语言是德语,但我相信有人会认出它。 Screenshot of the file-dialog
这似乎是 the Storage Access Framework 的系统 UI。您可以使用 ACTION_OPEN_DOCUMENT
允许用户打开现有文档,或使用 ACTION_CREATE_DOCUMENT
允许用户创建新文档。
但是,这不是 文件 UI。这是一个内容UI。用户可以浏览非本地存储的内容——在屏幕截图中,用户可以浏览他们的 Google Drive 和 One Drive 区域。而且,你得到的是 a Uri
pointing to content, not a file path.
您可以使用具有 MIME 类型 */*
的意图 ACTION_GET_CONTENT。
它将return onActivityResult()
中的URI@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent()
.setType("*/*")
.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select a file"), 123);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 123 && resultCode == RESULT_OK) {
Uri selectedfile = data.getData(); //The uri with the location of the file
}
}
参见Android developer documents and files documentations。 在 Kotlin 中你可以 launch file open dialog like that:
/**
* Starts bookmarks import workflow by showing file selection dialog.
*/
private fun showImportBookmarksDialog() {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "*/*" // That's needed for some reason, crashes otherwise
putExtra(
// List all file types you want the user to be able to select
Intent.EXTRA_MIME_TYPES, arrayOf(
"text/html", // .html
"text/plain" // .txt
)
)
}
bookmarkImportFilePicker.launch(intent)
// See bookmarkImportFilePicker declaration below for result handler
}
// Assuming you have context access as a fragment or an activity
val bookmarkImportFilePicker = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
// Using content resolver to get an input stream from selected URI
// See: https://commonsware.com/blog/2016/03/15/how-consume-content-uri.html
result.data?.data?.let{ uri ->
context?.contentResolver?.openInputStream(uri).let { inputStream ->
val mimeType = context?.contentResolver?.getType(uri)
// TODO: do your stuff like check the MIME type and read from that input stream
}
}
}