Android - 在外部应用程序中打开pdf

2023-12-14

我的应用程序资产目录中有一个 pdf 文件,我想使用外部应用程序打开该文件,因此编写了我的内容提供程序,我正在尝试使其工作,但没有任何结果...

这是代码:

内容提供商:

package package.name;

import java.io.File;
import java.io.FileNotFoundException;
import java.net.URI;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;

public class FileContentProvider extends ContentProvider {
       private static final String URI_PREFIX = "content://package.name.filecontentprovider";

       public static String constructUri(String url) {
           Uri uri = Uri.parse(url);
           return uri.isAbsolute() ? url : URI_PREFIX + url;
       }

       @Override
       public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
           URI uri1 = URI.create("file:///data/data/package.name/"+uri.getPath()); 
           File file = new File(uri1.getPath());
           ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
           return parcel;
       }

       @Override
       public boolean onCreate() {
           return true;
       }

       @Override
       public int delete(Uri uri, String s, String[] as) {
           throw new UnsupportedOperationException("Not supported by this provider");
       }

       @Override
       public String getType(Uri uri) {
           throw new UnsupportedOperationException("Not supported by this provider");
       }

       @Override
       public Uri insert(Uri uri, ContentValues contentvalues) {
           throw new UnsupportedOperationException("Not supported by this provider");
       }

       @Override
       public Cursor query(Uri uri, String[] as, String s, String[] as1, String s1) {
           throw new UnsupportedOperationException("Not supported by this provider");
       }

       @Override
       public int update(Uri uri, ContentValues contentvalues, String s, String[] as) {
           throw new UnsupportedOperationException("Not supported by this provider");
       }

    }

这里我如何调用文件的打开:

    File pdf = new File("assets/prova.pdf");
    Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("content://package.name/" + pdf));
    i.setType("application/pdf");
    startActivity(i);

我在 android 清单中的标签内添加了以下行:

    <provider android:name=".FileContentProvider" android:authorities="package.name" />

这是 logcat 输出:

02-26 19:47:44.938: ERROR/AndroidRuntime(6494): Uncaught handler: thread main exiting due to uncaught exception
02-26 19:47:44.953: ERROR/AndroidRuntime(6494): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tf.thinkdroid.samsung/com.tf.thinkdroid.pdf.app.PdfRenderScreen}: java.lang.NullPointerException
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at android.app.ActivityThread.access$2200(ActivityThread.java:119)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at android.os.Looper.loop(Looper.java:123)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at android.app.ActivityThread.main(ActivityThread.java:4363)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at java.lang.reflect.Method.invokeNative(Native Method)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at java.lang.reflect.Method.invoke(Method.java:521)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:862)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at dalvik.system.NativeStart.main(Native Method)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494): Caused by: java.lang.NullPointerException
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at com.tf.thinkdroid.pdf.app.RenderScreen.onNewIntent(Unknown Source)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at com.tf.thinkdroid.pdf.app.RenderScreen.onCreate(Unknown Source)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at com.tf.thinkdroid.pdf.app.PdfRenderScreen.onCreate(Unknown Source)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
02-26 19:47:44.953: ERROR/AndroidRuntime(6494):     ... 11 more

不明白问题出在哪里,似乎外部应用程序无法获取该文件。

谢谢你的帮助!


我的实现如下。请注意,如果您的文件名是 MyPdf.pdf,则该文件应为 asset/public_pdfs/MyPdf.pdf.mp3。路径public_pdfs是为了只导出你真正想要导出的pdf,.mp3扩展名是为了防止压缩。

AndroidManifest.xml

<provider android:authorities="my.app.PdfContentProvider" android:enabled="true" android:exported="true" android:name="my.app.PdfContentProvider">
</provider>

打开 PDF

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);

Uri uri = Uri.parse("content://my.app.PdfContentProvider/" + filename);
intent.setDataAndType(uri, "application/pdf");

startActivity(intent);

PdfContentProvider.java

public class PdfContentProvider extends ContentProvider
{
  private static final String PDFPATH = "public_pdfs/";

  @Override
  public String getType(Uri uri)
  {
    return "application/pdf";
  }

  @Override
  public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException
  {
    AssetManager am = getContext().getAssets();
    String file_name = uri.getLastPathSegment();

    if (file_name == null) throw new FileNotFoundException();
    AssetFileDescriptor afd = null;
    try
    {
      afd = am.openFd(PDFPATH + file_name + ".mp3");
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
    return afd;
  }

  private final static String[] COLUMNS = {OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE};

  @Override
  /**
   * This function is required for it to work on the Quickoffice at Android 4.4 (KitKat)
   */
  public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
  {
    if (projection == null)
    {
      projection = COLUMNS;
    }

    String[] cols = new String[projection.length];
    Object[] values = new Object[projection.length];
    int i = 0;
    for (String col : projection)
    {
      if (OpenableColumns.DISPLAY_NAME.equals(col))
      {
        cols[i] = OpenableColumns.DISPLAY_NAME;
        values[i++] = uri.getLastPathSegment();
      }
      else if (OpenableColumns.SIZE.equals(col))
      {
        cols[i] = OpenableColumns.SIZE;
        values[i++] = AssetFileDescriptor.UNKNOWN_LENGTH;
      }
    }

    cols = copyOf(cols, i);
    values = copyOf(values, i);

    final MatrixCursor cursor = new MatrixCursor(cols, 1);
    cursor.addRow(values);
    return cursor;
  }

  private static String[] copyOf(String[] original, int newLength)
  {
    final String[] result = new String[newLength];
    System.arraycopy(original, 0, result, 0, newLength);
    return result;
  }

  private static Object[] copyOf(Object[] original, int newLength)
  {
    final Object[] result = new Object[newLength];
    System.arraycopy(original, 0, result, 0, newLength);
    return result;
  }

  @Override
  public boolean onCreate()
  {
    return true;
  }

  @Override
  public Uri insert(Uri uri, ContentValues values)
  {
    return null;
  }

  @Override
  public int delete(Uri uri, String selection, String[] selectionArgs)
  {
    return 0;
  }

  @Override
  public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
  {
    return 0;
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android - 在外部应用程序中打开pdf 的相关文章

随机推荐

  • 在二进制文件中搜索字符串的代码

    前几天我问过这个问题 如何在二进制文件中查找 ANSI 字符串 我得到了一个非常好的answer 后来变成了一个更难的问题 输入迭代器可以用在需要前向迭代器的地方吗 现在确实不是我能理解的水平 我仍在学习 C 并且正在寻找一种在二进制文件中
  • socket.io 硬编码与动态连接 url

    为什么这里的大多数教程 示例和问题都使用本地 IP 或localhost 或任何其他硬编码路径 如下所示 var socket io connect http 127 0 0 1 3700 而不是简单地 var socket io conn
  • 在 WPF 应用程序中加密凭据

    在 WPF 应用程序中 我想提供典型的 记住我 选项来记住凭据并在下次启动应用程序时自动使用它们 使用单向哈希显然不是一个选择 虽然我可以存储凭据隔离存储 or 在注册表中 加密凭证时需要处理一个问题 如果我使用对称密钥加密算法 我需要将密
  • 检测 ThreadPool WorkItem 已完成/等待完成

    无论出于何种原因 ThreadPool s QueueWorkItem不返回IAsyncResult或工作项的其他一些句柄 这将允许等待它完成 有RegisterWait 方法 但你必须通过WaitHandle并且创建它们是昂贵的 参见IA
  • 检测 QlistWidget 中某行是否单击了某个项目

    我被赋予了这个简单的任务 我有这个列表 每当单击 ok 时我都会插入项目 void Form ok 处理该事件应该将新的列表项添加到列表中 现在我无法做的是检测是否在某行单击了某个项目 然后根据该操作执行某些操作 这是我的代码 includ
  • Angular Material2 单击时更改按钮颜色

    我想在单击按钮时更改材质 mat mini fab 按钮的颜色 我的尝试如下 但不起作用
  • html select(下拉)控制asp.net中的选定索引更改事件

    当值更改时 我试图将后端代码放入我的 html 选择控件 下拉列表 中 以触发后端方法 但我找不到该事件 我尝试了这样的方法
  • 从在 gitlab CI 中不起作用的资源读取文件

    我在使用以下命令在 gitlab CI 上运行测试时遇到错误 gradlew clean test 我正在使用测试容器来运行我的测试 https www testcontainers org modules docker compose 这
  • 在Java中将PDF转换为Word [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 Java 可以将 PDF 转换为 Word 吗 我不是在谈论解析 PDF 文档 然后将其再次自定义渲染到 Word 我想要一个可以直接转换它的Jav
  • 在 Visual Studio 设计器中找不到自定义字体的 C# 文件

    我对 C 比较陌生 所以我的 WinForms 项目中几乎有一个包含自定义字体的文件夹 该字体在启动应用程序时工作得非常好 但在 Visual Studio 本身的实际设计器中 无法加载自定义控件 因为我在设计器中使用的路径不同 这是我用来
  • 如何从 png 图像的一行获取 x y 坐标并在闪亮的应用程序中使用它

    这是对此的后续问题在闪亮的应用程序中使用 sliderInput 为区域着色 假设我有这个图像 我如何将 ismirsehregal 的解决方案应用于这张图片 我想我必须把食道的x和y放到代码中 但我不知道如何获取食道的x和y 图中绿色 代
  • 需要一个 API 来检测 iPhone 何时插入

    我正在为 Mac 制作一个应用程序 我需要一个 API 来检测 iPhone 何时插入 谢谢 编辑 具体来说 我需要一个 API 来检测 iPhone 何时插入 Mac 上的 USB 端口 我没有完整的答案 但实现您想要的功能的程序是 US
  • C++:switch 语句在右大括号之前缺少分号

    为了未来读者的利益和我自己的理智 我想绝对清楚地表明 switch没有a的语句default案例 由于涵盖了所有案例 或顺序if elseif else最后的 else 不应执行任何操作 不得省略 并包含对此效果的注释 请参见示例 然而 每
  • 在 Oracle SQL 中处理日期

    我在使用 SQL 方面非常陌生 我尝试做的是仅使用月份和年份选择 waterUsage 和 electrcityUsage 并选择上一年的 waterUsage 和 electrcityUsage 然而 我似乎无法找出使用日期来完成这项工作
  • Swift:iOS 12.2 应用程序启动时崩溃

    更新 Xcode 和 swift 5 后 在 iOS 12 2 上启动模拟器后 我的应用程序在启动时崩溃 但在早期版本的 ios 如 12 0 中 应用程序可以正常工作 我在真实设备 ios 12 0 1 上启动应用程序并且应用程序正常工作
  • UITextView 应该检测链接,但否则应该将触摸传播到下面的视图

    我有一个文本视图 我想在其中检测链接 但是当触摸点处没有链接时 它应该将触摸传播到下面的视图 目前没有 它将包含在表格视图单元格中 如果用户点击链接 它应该进行交互 它可以工作 但是当点击另一个点时 它应该选择表格视图单元格 我需要文本不可
  • 如何使用win32com从word文档中按颜色获取文本?

    我有一个包含几个表格的word文档 每张桌子有两种颜色 黑色和红色 我想按颜色从 Word 文档表中的单元格中获取文本 我找到了一个方法 但我认为效率很低 以下代码从单词表单元格中获取文本 并用它的颜色打印每个单词 import os sy
  • 由于 .NET 运行时中的内部错误,该进程被终止

    我正在使用 WPF 不知何故今天我得到了这个新的崩溃信息 Description The process was terminated due to an internal error in the NET Runtime at IP 6A
  • 阻止 AlertDialog 在单击肯定按钮时关闭

    我正在尝试设置一个自定义 AlertDialog 它有 2 个按钮 取消按钮和肯定按钮 我需要做到这一点 以便单击肯定按钮后 我可以更改文本 而不关闭对话框 大致流程是肯定按钮会显示 发送 单击后它将更改为 发送 然后代码将向我们的服务器发
  • Android - 在外部应用程序中打开pdf

    我的应用程序资产目录中有一个 pdf 文件 我想使用外部应用程序打开该文件 因此编写了我的内容提供程序 我正在尝试使其工作 但没有任何结果 这是代码 内容提供商 package package name import java io Fil