Android – 选择并查看任何类型的文件
我想让用户能够在手机中选择任何文件类型,然后再用意图查看。
选择文件项目我写这个(我正在使用Kotlin,Java中的相同问题):
fun goToDocumentPicker() { val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) intent.addCategory(Intent.CATEGORY_OPENABLE) intent.type = "*/*" if (intent.resolveActivity(mContext.packageManager) != null) mContext.startActivityForResult(intent, REQUEST_DOCUMENT) }
并显示选择的项目:
fun showDocumentPreviewer(uri: Uri) { val i = Intent(Intent.ACTION_VIEW) i.data = uri mContext.startActivity(i) }
文档选取器工作正常,在onActivityResult
我可以接收所选文档的Uri对象,但文档预览器无法打开对象。 已经尝试将mime-type设置为预览者的意图,但不成功。 我使用不正确的方式在Android中打开文件? 任何通用的方式来显示Android中的任何文件类型? (因为我想支持多种文件类型)
采摘Uri: content://com.android.providers.media.documents/document/image:80
更新:基于@ CommonsWare的评论,我编辑了如下的预览功能:
fun showAttachmentPreviewer(uri: Uri, mimeType: String?) { Log.d("TEST", "Preview " + uri.toString()) val intent = Intent(Intent.ACTION_VIEW, uri) intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) val chooser = Intent.createChooser(intent, "Open with") if (intent.resolveActivity(mContext.packageManager) != null) mContext.startActivity(chooser) else mContext.showSnackBar("No suitable application to open file") }
现在应用程序总是与下面的崩溃日志崩溃:
java.lang.SecurityException:UID 10202没有权限0 u @ content://com.android.providers.media.documents/document/audio:17915
更新2:我的应用程序崩溃在行mContext.startActivity(chooser)
。 这里是完整的崩溃日志:
致命例外:主进程:com.makeit.lite,PID:12851 java.lang.SecurityException:Uid 10477没有权限0 u @ content://com.android.providers.media.documents/document/image:24776在android.app.Android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2514)android.os.Parcel.readException(Parcel.java:1493)android.os.Parcel.readException(Parcel.java:1540)。 Instrumentation.execStartActivity(Instrumentation.java:1494)at android.app.Activity.startActivityForResult(Activity.java:3913)at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:50)at android.support.v4 .app.FragmentActivity.startActivityForResult(FragmentActivity.java:79)在android.app.Activity.startActivityForResult(Activity.java:3860)在android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:859)在android。 app.Activity.startActivity(Activity.java:4184)at android.app.Activity.startActivity(Activity.java :4152)at com.makeit.lite.attachment.AttachmentNavigator.showAttachmentPreviewer(AttachmentNavigator.kt:92)at com.makeit.lite.attachment.list.AttachmentListPresenter.onAttachmentClicked(AttachmentListPresenter.kt:37)at com.makeit.lite。 attachment.list.AttachmentListFragment $ onViewCreated $ 1.onItemClick(AttachmentListFragment.kt:39)at eu.davidea.viewholders.FlexibleViewHolder.onClick(FlexibleViewHolder.java:121)at android.view.View.performClick(View.java:5156)at android.view.View $ PerformClick.run(View.java:20755)at android.os.Handler.handleCallback(Handler.java:739)at android.os.Handler.dispatchMessage(Handler.java:95)at android.os .Looper.loop(Looper.java:145)at android.app.ActivityThread.main(ActivityThread.java:5835)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:1399)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
更新3:如果我将mimeType设置为intent: intent.type = mimeType
,应用程序不会再崩溃。 mimeType
是我从picker intent(在content:
uri旁边)得到的字符串。 mimeType值可以是image/jpeg
或任何基于选定文件类型的东西。 虽然它不会崩溃,但在给定的URI里的文件也不会显示。 如果我从Intent-Chooser中选择Gallery
,图库将打开并显示所有图像。 我想第三个应用程序不知道如何确定在给定的uri文件。
这里是我的功能的最新来源:
fun showAttachmentPreviewer(uri: Uri, mimeType: String?) { Log.d("TEST", "Preview " + uri.toString() + " For type" + mimeType) val intent = Intent(Intent.ACTION_VIEW, uri) intent.type = mimeType //Can be "image/jpeg" or sth corresponding to the filetype. intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) val chooser = Intent.createChooser(intent, "Open with") if (intent.resolveActivity(mContext.packageManager) != null) mContext.startActivity(chooser) else mContext.showSnackBar("No suitable application to open file") }
我使用不正确的方式在Android中打开文件?
首先,可能没有能够查看文件类型的应用程序。
其次,您尚未授予应用程序查看内容的权限。 在ACTION_VIEW
Intent
上使用addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
。
如果您想要使用该文件执行完美的功能,则应该使用任何第三方库来实现此功能。
你应该检查下面的链接文件采摘最常见的库: –
val intent = Intent(Intent.ACTION_VIEW, uri) intent.type = mimeType
改成
val intent = Intent(Intent.ACTION_VIEW); intent.setDataAndType (uri, mimeType );
你应该设置一个语句的URI和MIME类型。 否则,接收的应用程序将收到null为uri。 大多数应用程序不会告诉你,他们没有收到一个URI。 图库应用程序实例不。
我不知道Kotlin的确切函数名称。
首先,我要对@GreenApps,@Ankit和@CommonsWare表示感谢。 谁花时间调查我的问题。
我终于找到将源提取到分离的简单项目的根本原因。 这是因为我这样解析uri-string到uri-instance(根本原因的代码没有包括在我的问题中,我的道歉):
val uri = Uri.parse(URLDecoder.decode(uriString, "UTF-8")) as Uri
当我改为val uri = Uri.parse(uriString)
他们的问题就解决了。
顺便说一句,我想分享我的Github中的选择器和预览器的示例代码,有人可能需要看看。 java源代码位于master
分支上,Kotlin源代码位于kotlin-version
分支上。 使用这个简单的代码,现在我可以选择任何文件类型(图像,音频,视频,PDF,XLSX,…),然后通过Intent.ACTION_VIEW打开它。
这里是:
- 无法让dokka在gradle / android项目上生成kotlin文档
- Gradle无法在Windows上读取正确的本地Maven存储库
- notifyDataChanged()无法更新可扩展列表视图数据
- 如何为Kotlin和Gradle设置“sourceCompatibility”?
- 显示DialogFragment抛出“无法执行此操作后onSaveInstanceState”错误
- Kotlin协同程序:测试Android Presenter时切换上下文
- Android:等待多个任务完成
- 无法使用Kotlin Android扩展调用getMapAsync函数
- 在Kotlin(Android)中以字符串形式读取文本资产(来自assets文件夹的文本文件)