【问题标题】:How to open a pdf file using jquery and phonegap in android?如何在android中使用jquery和phonegap打开pdf文件?
【发布时间】:2013-07-26 06:10:13
【问题描述】:

最近我正在为 android 构建一个应用程序。我正在使用phonegap来做同样的事情。一切运行良好,除了一个问题,即我无法在 android 中使用 jquery 打开 pdf 文件。我已经尝试了很多做同样的事情,但我做不到。

我想要的是,点击图片后,它会从一个 url 打开一个 pdf。

已编辑:

我试过这个:

<img src="img/b_img1.png" onclick="openPdf('http://www.w3.org/2011/web-apps-ws/papers/Nitobi.pdf')"/>

openPdf 函数是这样的:

 function openFile(pdfUrl) {
     window.plugins.fileOpener.open(pdfUrl);
 }

而fileOpener插件就是这样的:

cordova.define("cordova/plugin/fileopener",
    function(require, exports, module) {
        var exec = require("cordova/exec");
        var FileOpener = function() {};

        FileOpener.prototype.open = function(url) {
            exec(null, null, "FileOpener", "openFile", [url]);
        };

        var fileOpener = new FileOpener();
        module.exports = fileOpener;

    });
/**
 * Load Plugin
 */
if (!window.plugins) {
    window.plugins = {};
}
if (!window.plugins.fileOpener) {
    window.plugins.fileOpener = cordova.require("cordova/plugin/fileopener");
}

我已经像这样在 config.xml 页面中添加了插件:

 <plugin name="FileOpener" value="com.phonegap.plugins.file.FileOpener"/>

我在 com.phonegap.plugins.file 包中添加了 FileOpener.java,如下所示:

    package com.phonegap.plugins.file;

     import java.io.File;
     import java.io.FileOutputStream;
     import java.io.IOException;
     import java.io.InputStream;
     import java.net.URL;
     import java.net.URLConnection;

     import org.json.JSONArray;
     import org.json.JSONException;

     import android.content.Context;
     import android.content.Intent;
     import android.content.pm.PackageManager;
     import android.net.Uri;

     import org.apache.cordova.api.CallbackContext;
     import org.apache.cordova.api.CordovaPlugin;
     import org.apache.cordova.api.PluginResult;

     public class FileOpener extends CordovaPlugin {
      private static final String YOU_TUBE = "youtube.com";
        private static final String ASSETS = "file:///android_asset/";

    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) 
               {
        PluginResult.Status status = PluginResult.Status.OK;
        String result = "";

        try {
            if (action.equals("openFile")) {
                openFile(args.getString(0));
            }
            else {
                status = PluginResult.Status.INVALID_ACTION;
            }
            callbackContext.sendPluginResult(new PluginResult(status, result));
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }

    private void openFile(String url) throws IOException {

        if (url.contains("bit.ly/") || url.contains("goo.gl/") || url.contains("tinyurl.com/") || url.contains("youtu.be/")) {
            //support for google / bitly / tinyurl / youtube shortens
            URLConnection con = new URL(url).openConnection();
            con.connect();
            InputStream is = con.getInputStream();
            //new redirected url
            url = con.getURL().toString();
            is.close();
        }
        // Create URI
        Uri uri = Uri.parse(url);

        Intent intent = null;
        // Check what kind of file you are trying to open, by comparing the url with extensions.
        // When the if condition is matched, plugin sets the correct intent (mime) type, 
        // so Android knew what application to use to open the file
        if (url.contains(YOU_TUBE)) {
            // If we don't do it this way you don't have the option for youtube
            uri = Uri.parse("vnd.youtube:" + uri.getQueryParameter("v"));
            if (isYouTubeInstalled()) {
                intent = new Intent(Intent.ACTION_VIEW, uri);
            } else {
                intent = new Intent(Intent.ACTION_VIEW);
                intent.setData(Uri.parse("market://details?id=com.google.android.youtube"));
            }
        } else if(url.contains(ASSETS)) {
             // get file path in assets folder
            String filepath = url.replace(ASSETS, "");
            // get actual filename from path as command to write to internal storage doesn't like folders
            String filename = filepath.substring(filepath.lastIndexOf("/")+1, filepath.length());

            // Don't copy the file if it already exists
            File fp = new File(this.cordova.getActivity().getFilesDir() + "/" + filename);
            if (!fp.exists()) {
                this.copy(filepath, filename);
            }
            // change uri to be to the new file in internal storage
            uri = Uri.parse("file://" + this.cordova.getActivity().getFilesDir() + "/" + filename);

            if (url.contains(".doc") || url.contains(".docx")) {
                // Word document
                intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(uri, "application/msword");
            } else if(url.contains(".pdf")) {
                // PDF file
                intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(uri, "application/pdf");
            } else if(url.contains(".ppt") || url.contains(".pptx")) {
                // Powerpoint file
                intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(uri, "application/vnd.ms-powerpoint");
            } else if(url.contains(".xls") || url.contains(".xlsx")) {
                // Excel file
                intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(uri, "application/vnd.ms-excel");
            } else if(url.contains(".rtf")) {
                // RTF file
                intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(uri, "application/rtf");
            } else if(url.contains(".wav")) {
                // WAV audio file
                intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(uri, "audio/x-wav");
            } else if(url.contains(".gif")) {
                // GIF file
                intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(uri, "image/gif");
            } else if(url.contains(".jpg") || url.contains(".jpeg")) {
                // JPG file
                intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(uri, "image/jpeg");
            } else if(url.contains(".txt")) {
                // Text file
                intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(uri, "text/plain");
            } else if(url.contains(".mpg") || url.contains(".mpeg") || url.contains(".mpe") || url.contains(".mp4") || url.contains(".avi")) {
                // Video files
                intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(uri, "video/*");
            }         

            //if you want you can also define the intent type for any other file

            //additionally use else clause below, to manage other unknown extensions
            //in this case, Android will show all applications installed on the device
            //so you can choose which application to use

            else {
                intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(uri, "*/*");
            }

        }else {           
        if (url.contains(".doc") || url.contains(".docx")) {
            // Word document
            intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uri, "application/msword");
        } else if(url.contains(".pdf")) {
            // PDF file
            intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uri, "application/pdf");
        } else if(url.contains(".ppt") || url.contains(".pptx")) {
            // Powerpoint file
            intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uri, "application/vnd.ms-powerpoint");
        } else if(url.contains(".xls") || url.contains(".xlsx")) {
            // Excel file
            intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uri, "application/vnd.ms-excel");
        } else if(url.contains(".rtf")) {
            // RTF file
            intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uri, "application/rtf");
        } else if(url.contains(".wav")) {
            // WAV audio file
            intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uri, "audio/x-wav");
        } else if(url.contains(".gif")) {
            // GIF file
            intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uri, "image/gif");
        } else if(url.contains(".jpg") || url.contains(".jpeg")) {
            // JPG file
            intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uri, "image/jpeg");
        } else if(url.contains(".txt")) {
            // Text file
            intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uri, "text/plain");
        } else if(url.contains(".mpg") || url.contains(".mpeg") || url.contains(".mpe") || url.contains(".mp4") || url.contains(".avi")) {
            // Video files
            intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uri, "video/*");
        }         

        //if you want you can also define the intent type for any other file

        //additionally use else clause below, to manage other unknown extensions
        //in this case, Android will show all applications installed on the device
        //so you can choose which application to use

        else {
            intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(uri, "*/*");
        }
        }

        this.cordova.getActivity().startActivity(intent);
    }


    private void copy(String fileFrom, String fileTo) throws IOException {
        // get file to be copied from assets
        InputStream in = this.cordova.getActivity().getAssets().open(fileFrom);
        // get file where copied too, in internal storage.
        // must be MODE_WORLD_READABLE or Android can't play it
        FileOutputStream out = this.cordova.getActivity().openFileOutput(fileTo, Context.MODE_WORLD_READABLE);

        // Transfer bytes from in to out
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0)
            out.write(buf, 0, len);
        in.close();
        out.close();
    }

    private boolean isYouTubeInstalled() {
        PackageManager pm = this.cordova.getActivity().getPackageManager();
        try {
            pm.getPackageInfo("com.google.android.youtube", PackageManager.GET_ACTIVITIES);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }
   }

我也添加了清单文件的权限。

现在使用我的 fileopener 插件,在更改 file.java 页面后,一切都可以完美打开。(您可以在编辑的部分中看到)。 video, mp3, img 如果存储在本地或全局上,则可以完美打开。如果 pdf 文件存储在 android/asset 文件夹中,那么它会显示给我,但如果它来自网站,那么它会显示错误。

Logcat 在说我:

  07-26 15:11:38.105: E/Web Console(21696): Uncaught Error: Error calling method on NPObject. at file:///android_asset/www/js/cordova-2.7.0.js:857

那么任何人都可以帮助我做错了什么吗?提前致谢。

【问题讨论】:

  • 希望window.plugins.fileOpener中的逗号,open(pdfUrl);只是一个错字??另外,您的设备中有 adobe reader 吗?您是否尝试过在设备中打开普通的 pdf 文件?
  • @SHANK 是的,我的设备上有居住阅读器,我可以在设备中看到普通的 pdf。当我使用 window.plugins.fileOpener.open(pdfUrl); Logcat 说:07-26 11:03:44.516: E/Web Console(2525): Uncaught TypeError: Cannot call method 'open' of undefined at file:///android_asset/www/index.html:60
  • 另外,在您的 fileOpener 插件代码中,有这个逗号问题 FileOpener.prototype,open = function(url) {... 我可以看到案例问题,您使用了 fileOpener , FileOpener,文件打开器。也可能是这种不匹配
  • @SHANK:我已经编辑了“。”和案件问题,但现在也没有到来。现在在我的浏览器中,我可以看到它正在调用该函数。在 android 设备中,它既没有打开任何图像、视频、pdf 文件,也没有显示任何错误。
  • 我没有直接的答案,但尝试调试并发布执行停止的行。

标签: android jquery pdf cordova


【解决方案1】:

免责声明:我是PSPDFKit 团队的开发人员

您可以查看https://github.com/PSPDFKit/Cordova-Androidhttps://github.com/PSPDFKit/Cordova-iOS。这两个插件都封装了 PSPDFKit 并允许查看 PDF 文档就像

function showMyDocument() {
    PSPDFKit.showDocument('file://.../document.pdf');
}

文件下载可以通过 Cordova 下载器插件(如 Joram Teusink 所述)或简单地扩展 PSPDFKit 插件本身来完成。我们欢迎对项目的每一份贡献!

【讨论】:

    【解决方案2】:

    如果您愿意允许设备处理文件的查看,则另一种方法:使用 InAppBrowser 插件(现在称为cordova-plugin-inappbrowser),然后使用window.open(pdfUrl, '_system');

    【讨论】:

      【解决方案3】:

      使用这个下载器插件:http://teusink.blogspot.nl/2013/04/phonegap-android-downloader-plugin.html

      创建一个向 Android 发送 PDF 意图的额外函数(方法)。 How to render PDF in Android

      Uri path = Uri.fromFile(file); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(path, "application/pdf"); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-03
        • 1970-01-01
        • 2015-10-08
        • 1970-01-01
        • 2015-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多