当前位置: 首页 > 知识库问答 >
问题:

在内部存储上共享文件时,其他应用程序中的NullPointerException

南宫胡媚
2023-03-14

在我们的应用程序中,我们发现有必要通过另一个应用程序的意图从我们的内部存储中打开文档。即打开我们内部存储在用户选择的默认pdf阅读器中的pdf。

在清单中,我将应用程序设置为提供程序,在我们的Provider类中,我实现了调用的openFile(Uri uri, String模式)方法,并且不会抛出FileNotFoundException。

我已经验证了该文件是否存在于预期的位置-并且意图不为空,并且实际上看起来是正确的。

但是,当我发送新的Intent时,尝试打开文件的应用程序会因NPE而死亡。例如,这是尝试打开PDF时的堆栈跟踪:

02-26 14:53:59.047: E/AndroidRuntime(4138): FATAL EXCEPTION: main
02-26 14:53:59.047: E/AndroidRuntime(4138): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tf.thinkdroid.sg/com.tf.thinkdroid.pdf.app.RenderScreen}: java.lang.NullPointerException
02-26 14:53:59.047: E/AndroidRuntime(4138):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)
02-26 14:53:59.047: E/AndroidRuntime(4138):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
02-26 14:53:59.047: E/AndroidRuntime(4138):     at android.app.ActivityThread.access$600(ActivityThread.java:130)
02-26 14:53:59.047: E/AndroidRuntime(4138):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
02-26 14:53:59.047: E/AndroidRuntime(4138):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-26 14:53:59.047: E/AndroidRuntime(4138):     at android.os.Looper.loop(Looper.java:137)
02-26 14:53:59.047: E/AndroidRuntime(4138):     at android.app.ActivityThread.main(ActivityThread.java:4745)
02-26 14:53:59.047: E/AndroidRuntime(4138):     at java.lang.reflect.Method.invokeNative(Native Method)
02-26 14:53:59.047: E/AndroidRuntime(4138):     at java.lang.reflect.Method.invoke(Method.java:511)
02-26 14:53:59.047: E/AndroidRuntime(4138):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
02-26 14:53:59.047: E/AndroidRuntime(4138):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
02-26 14:53:59.047: E/AndroidRuntime(4138):     at dalvik.system.NativeStart.main(Native Method)
02-26 14:53:59.047: E/AndroidRuntime(4138): Caused by: java.lang.NullPointerException
02-26 14:53:59.047: E/AndroidRuntime(4138):     at com.tf.thinkdroid.pdf.app.RenderScreen.onNewIntent(Unknown Source)
02-26 14:53:59.047: E/AndroidRuntime(4138):     at com.tf.thinkdroid.pdf.app.RenderScreen.onCreate(Unknown Source)
02-26 14:53:59.047: E/AndroidRuntime(4138):     at android.app.Activity.performCreate(Activity.java:5008)
02-26 14:53:59.047: E/AndroidRuntime(4138):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
02-26 14:53:59.047: E/AndroidRuntime(4138):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
02-26 14:53:59.047: E/AndroidRuntime(4138):     ... 11 more
02-26 14:53:59.054: W/ActivityManager(251):   Force finishing activity com.tf.thinkdroid.sg/com.tf.thinkdroid.pdf.app.RenderScreen

我想不出任何方法来调试它,因为它发生在我的应用程序之外,我只是不知道为什么会发生。有没有人知道这可能是什么原因,或者我如何修复它?

谢谢

编辑:这就是我创建意图的方式。

  Intent intent = new Intent(Intent.ACTION_VIEW);
  String extension = EventUtil.getExtension(file);
  String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
  Uri uri = Uri.parse(getContext().getPackageName() + file.getPath());
  intent.setDataAndType(uri, type);

以及发射意图:

getContext().startActivity(intent);

另一次编辑!

修复损坏的url(请参见下面的注释)后,将调用my ContentProvider openFile(),并且不会引发任何异常,但接收应用程序仍会崩溃。

还有另一个编辑。。。。。

这当然是我如何处理Uri的问题-我在下面的评论中链接到的SO答案中的代码似乎给了我一些我不想要的额外路径信息(即data/data/com.xxxxx.xxxxx/files/files/subdir/filename-太多的文件目录!)但是我还没有弄清楚如何准确地获得正确创建url所需的内容!

共有1个答案

党博超
2023-03-14

所以,这完全是一个Uri问题。使用错误的方案(即文件:///)传递Uri会导致接收应用程序崩溃,因为它无法将Uri正确解析为文件-它需要是content://Uri方案。遗憾的是,如果不在我们的应用程序中添加框架,我找不到任何方法来解决这种类型的方案(Android support 4显然有一个FileProvider类可以做到这一点)因此,我必须使一个字符串保持常量以保存Uri的第一部分,然后在末尾添加正确的路径。

我看到过几个答案说您可以调用getContext(). getPackageName()file.getPath(),但正如用户njkz2指出的那样,这是不对的。如果没有正确的框架,您需要编写自己的类来处理Uri以传回正确的方案,或者您需要创建一个String常量来指向您自己的内部文件目录。

 类似资料:
  • 我想用SharingContent将声音从原始文件夹共享到另一个应用程序 我使用此代码共享文本和字符串

  • 我的目标是在内部存储上创建一个XML文件,然后通过share Intent发送它。 我能够使用以下代码创建XML文件 我一直在尝试检索输出文件的Uri以共享它。我首先尝试通过将文件转换为Uri来访问该文件 此返回file:///data/data/com.my.package/files/myfile.xml但我似乎无法将此附加到电子邮件、上载等。 如果我手动检查文件长度,它是正确的,并显示有一个

  • 我正在使用此代码在Whatsapp、Facebook和Instagram等网站上共享图像。此代码在API 25以下运行良好,但在API 25以上不起作用。

  • 我有一个音频文件的回收视图,该音频文件存储在原始文件夹中。现在,我想与其他应用程序共享我的音频文件。我正在适配器clss中尝试此代码。 但它不起作用。如何解决这个问题。 提前谢谢。

  • 我试图通过将提供程序的设置为来破坏安全性,但是会在内部检查自己是否导出,如果导出了,它会抛出一个异常。

  • 问题内容: 我想用一些登录用户创建一个Django应用程序。另一方面,由于我需要一些实时功能,因此我想使用Express.js应用程序。 现在,问题是,我不希望未经身份验证的用户访问Express.js应用程序的数据。因此,我必须在Express.js和Django应用程序之间共享会话存储。 我认为使用Redis是个好主意,因为volatile键非常适合这种情况,而且我已经在应用程序的另一部分使用