2013-07-26 20 views
7

Ostatnio buduję aplikację dla Androida. Używam phonegapa, aby zrobić to samo. Wszystko działa dobrze, z wyjątkiem jednego problemu, tj. Nie mogę otworzyć pliku pdf za pomocą jquery w Androidzie. Wiele próbowałem zrobić, ale nie jestem w stanie tego zrobić.Jak otworzyć plik pdf za pomocą jquery i phonegap w systemie Android?

To, co chcę, to to, że po kliknięciu obrazu otworzy się plik pdf z adresu URL.

Zmieniano:

Próbowałem to:

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

funkcja openPdf jest tak:

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

I fileOpener Wtyczka jest tak:

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"); 
} 

muszę dodawać wtyczki jak w stronie config.xml tak:

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

I dodałem FileOpener.java w pakiecie com.phonegap.plugins.file tak:

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; 
     } 
    } 
    } 

Mam również uprawnienia do pliku manifestu.

teraz za pomocą mojej wtyczki fileopener wszystko otwiera się idealnie po zmianie strony file.java. (Możesz zobaczyć w edytowanej sekcji). wideo, mp3, img otwiera się idealnie, jeśli jest przechowywane lokalnie lub globalnie. Jeśli plik pdf jest przechowywany w folderze android/asset, to pokazuje mi, ale jeśli pochodzi ze strony internetowej, to pokazuje mi błąd.

Logcat mówi mi:

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 

Więc może ktoś mi pomóc, co robię źle? Z góry dziękuję.

+0

Mam nadzieję, że przecinek w window.plugins.fileOpener, open (pdfUrl); to tylko literówka? Czy masz również czytnik Adobe Reader w swoim urządzeniu? Czy próbowałeś otworzyć normalny plik pdf w urządzeniu? – SHANK

+0

@SHANK Yap, mam czytnik abod w moim urządzeniu i widzę normalny plik pdf w urządzeniu. I kiedy używam window.plugins.fileOpener.open (pdfUrl); Logcat mówi: 07-26 11: 03: 44.516: E/Web Console (2525): Uncaught TypeError: Nie można wywołać metody 'open' z undefined w pliku: ///android_asset/www/index.html: 60 – Avijit

+0

Również w twoim kodzie fileOpener istnieje ten problem z przecinkiem FileOpener.prototype, open = function (url) {... Widzę problem z kopią, użyłeś fileOpener, FileOpener, fileopener. Możliwe, że ta niedopasowanie również – SHANK

Odpowiedz

0

Odmienny takt, jeśli są chętni, aby umożliwić urządzenie do obsługi przeglądania pliku: Użyj wtyczki InAppBrowser (zwany teraz cordova-plugin-inappbrowser), a następnie użyć window.open(pdfUrl, '_system');

1

Disclaimer: Jestem programistą w zespole

PSPDFKit można spojrzeć na https://github.com/PSPDFKit/Cordova-Android i https://github.com/PSPDFKit/Cordova-iOS.Obie wtyczki są owijania PSPDFKit i umożliwiają przeglądanie dokumentów PDF tak proste jak

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

pobieranie pliku może być albo wykonywane przez wtyczkę downloader Cordova (jak wspomniano przez Joram Teusink) lub po prostu rozszerzenie PSPDFKit wtyczki siebie. Witamy każdy wkład w projekt!

Powiązane problemy