web-dev-qa-db-ja.com

Android PDFブラウザとWebViewでロードされていません

PDFファイルをAndroid Webviewでロードしようとしています。Googleで検索したとき。最良の答えは、Googleドキュメントを使用することです。このURLの最後にPDFファイルURLを追加します https://docs.google.com/gview?embedded=true&url=

そして、この完全なURLをAndroid WebViewにロードします。PDFが正常にロードされます。ただし、1つのPDFファイルがあります。 WebViewおよびChromeブラウザ(私のシステム上)にロードされていない次のURLにあります。PDF URLは

http://www.expertagent.co.uk/asp/in4glestates/ {16D968D6-198E-4E33-88F4-8A85731CE605}/{05c36123-4df0-4d7d-811c-8b6686fdd526} /external.pdf

およびPDF as https://docs.google.com/gview?embedded=true&url=www.expertagent.co.uk/asp/in4glestates/ {16D968D6-198E-4E33-88F4-8A85731CE605}/{05c36123-4df0-4d7d-811c-8b6686fdd526} /external.pdf

その後、プレビュー不可と表示されます。誰でもここで間違ったことを教えてください。

26
Abdul Mohsin

これは完全な答えではありません。いくつかの可能性を調査しましたが、まだこの動作について説得力のある説明がありません。

理論A:URLエンコード... no

私の最初の考えは@ gn1と同じでした-中括弧が必要です RL encoding 。残念ながら、urlパラメーターをエンコードしても結果は変わりません。

理論B:悪いPDF file ... no

次に、おそらくGoogle Docsはこの特定のPDFファイル-サポートされていないバージョンであるか、オプション機能を使用しているか、他の視聴者が許容するエラーさえある。別のサイト。GoogleDocsに新しい場所を指定すると、問題なくプレビューできました。

理論C:非協​​力的なサイト...いいえ

次に、このサイトは何らかの理由でGoogleドキュメントと連携していないのではないかと考えました。Googleによるインデックス登録がブロックされている可能性があります。同じサイトで同じスキームの別のPDFリンク:

http://www.expertagent.co.uk/asp/in4glestates/%7B6dad6f28-a59d-4b54-b277-52f077f4927f%7D/%7Be3a6d17c-d6a8-4e92-8f52-09c6721515fc%7D/External.pdf

Google Docsにこのリンクをポイントすると、うまくプレビューできました。

理論D:異なるメタデータ...いいえ

今、私は1つのリンクが機能し、もう1つは機能しませんでした。メタデータが異なっていたかもしれません-例えばおそらく動作したのはapplication/pdfのタグが付けられていて、もう1つはタグが付けられていなかったのでしょう。そこで、HTTPヘッダーを調べました。

作業URL:

HTTP/1.1 200 OK
Cache-Control: max-age=3600
Content-Length: 1767120
Content-Type: application/pdf
Last-Modified: Fri, 02 Nov 2007 12:45:00 GMT
Accept-Ranges: bytes
ETag: "46b1592e4e1dc81:13e6"
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Date: Wed, 03 Jun 2015 23:25:23 GMT

動作しないURL:

HTTP/1.1 200 OK
Cache-Control: max-age=3600
Content-Length: 4623702
Content-Type: application/pdf
Last-Modified: Mon, 11 May 2015 15:53:16 GMT
Accept-Ranges: bytes
ETag: "acac5d9828cd01:13e6"
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Date: Wed, 03 Jun 2015 23:25:42 GMT

メタデータに明らかな大きな違いは見られません。

理論E:Googleからの奇妙な要求...いいえ

私はこの時点で明らかにストローを把握しています。 Googleからのリクエストはどういうわけか異なるのだろうか-バイト範囲やあいまいな圧縮などを要求し、ターゲットサーバーが一貫して適切に処理しなかったのかもしれません。そこで、HTTPリクエストがどのように見えるかを確認するために、自分が管理するサイトにGoogleドキュメントを向けました。

GET /asp/in4glestates/%7B16D968D6-198E-4E33-88F4-8A85731CE605%7D/%7B05c36123-4df0-4d7d-811c-8b6686fdd526%7D/External.pdf HTTP/1.1
Host: www.example.com:55555
Connection: Keep-alive
Accept-Encoding: gzip,deflate
User-Agent: Mozilla/5.0 (compatible; Google AppsViewer; http://drive.google.com)

それはまったく奇妙ではありません。ターゲットサイトが圧縮要求を無視することを確認したので、バグのある圧縮のケースではありません。また、そのUser-Agentヘッダーを使用してターゲットサイトにアクセスしようとしましたが、問題ではないようです。


だから私は問題ではないものを教えてくれる手がかりを見つけましたが、何が問題なのかをまだ説明していません。これらの否定的な結果がまだ誰かに役立つことを期待して投稿しています。

9
rhashimoto

私はこれを使用しており、私のために働いています: http://weimenglee.blogspot.com/2013/05/Android-tip-displaying-pdf-document.html

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    WebView webView=new WebView(MainActivity.this);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setPluginState(WebSettings.PluginState.ON);
    //---you need this to prevent the webview from
    // launching another browser when a url
    // redirection occurs---
    webView.setWebViewClient(new Callback());

    String pdfURL = "http://www.expertagent.co.uk/asp/in4glestates/{16D968D6-198E-4E33-88F4-8A85731CE605}/{05c36123-4df0-4d7d-811c-8b6686fdd526}/external.pdf";
    webView.loadUrl(
            "http://docs.google.com/gview?embedded=true&url=" + pdfURL);

    setContentView(webView);
}

private class Callback extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(
            WebView view, String url) {
        return(false);
    }
}
8
isma3l

open PDFダウンロードせずに、webviewで のサンプルコードをチェックアウトします。

private void init()
{
    WebView webview = (WebView) findViewById(R.id.webview);
    WebSettings settings = webview.getSettings();
    settings.setJavaScriptEnabled(true);
    webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);

    PdfWebViewClient pdfWebViewClient = new PdfWebViewClient(this, webview);
    pdfWebViewClient.loadPdfUrl(
            "https://www.google.co.in/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0ahUKEwjgwIfp3KXSAhXrhFQKHQqEDHYQFggZMAA&url=http%3A%2F%2Fwww.orimi.com%2Fpdf-test.pdf&usg=AFQjCNERYYcSfMLS5ukBcT2Qy11YxEhXqw&cad=rja");
}


private class PdfWebViewClient extends WebViewClient
{
   private static final String TAG = "PdfWebViewClient";
   private static final String PDF_EXTENSION = ".pdf";
   private static final String PDF_VIEWER_URL = "http://docs.google.com/gview?embedded=true&url=";

   private Context mContext;
   private WebView mWebView;
   private ProgressDialog mProgressDialog;
   private boolean isLoadingPdfUrl;

   public PdfWebViewClient(Context context, WebView webView)
   {
      mContext = context;
      mWebView = webView;
      mWebView.setWebViewClient(this);
   }

   public void loadPdfUrl(String url)
   {
      mWebView.stopLoading();

      if (!TextUtils.isEmpty(url))
      {
          isLoadingPdfUrl = isPdfUrl(url);
          if (isLoadingPdfUrl)
          {
              mWebView.clearHistory();
          }

          showProgressDialog();
       }

      mWebView.loadUrl(url);
  }

  @SuppressWarnings("deprecation")
  @Override
  public boolean shouldOverrideUrlLoading(WebView webView, String url)
  {
      return shouldOverrideUrlLoading(url);
  }

  @SuppressWarnings("deprecation")
  @Override
  public void onReceivedError(WebView webView, int errorCode, String description, String failingUrl)
  {
      handleError(errorCode, description.toString(), failingUrl);
  }

  @TargetApi(Build.VERSION_CODES.N)
  @Override
  public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest request)
  {
      final Uri uri = request.getUrl();
      return shouldOverrideUrlLoading(webView, uri.toString());
  }

  @TargetApi(Build.VERSION_CODES.N)
  @Override
  public void onReceivedError(final WebView webView, final WebResourceRequest request, final WebResourceError error)
  {
      final Uri uri = request.getUrl();
      handleError(error.getErrorCode(), error.getDescription().toString(), uri.toString());
  }

  @Override
  public void onPageFinished(final WebView view, final String url)
  {
      Log.i(TAG, "Finished loading. URL : " + url);
      dismissProgressDialog();
  }

  private boolean shouldOverrideUrlLoading(final String url)
  {
      Log.i(TAG, "shouldOverrideUrlLoading() URL : " + url);

      if (!isLoadingPdfUrl && isPdfUrl(url))
      {
          mWebView.stopLoading();

          final String pdfUrl = PDF_VIEWER_URL + url;

          new Handler().postDelayed(new Runnable()
          {
              @Override
              public void run()
              {
                  loadPdfUrl(pdfUrl);
              }
          }, 300);

          return true;
      }

      return false; // Load url in the webView itself
  }

   private void handleError(final int errorCode, final String description, final String failingUrl)
  {
      Log.e(TAG, "Error : " + errorCode + ", " + description + " URL : " + failingUrl);
  }

  private void showProgressDialog()
  {
      dismissProgressDialog();
      mProgressDialog = ProgressDialog.show(mContext, "", "Loading...");
  }

  private void dismissProgressDialog()
  {
      if (mProgressDialog != null && mProgressDialog.isShowing())
      {
          mProgressDialog.dismiss();
          mProgressDialog = null;
      }
  }

  private boolean isPdfUrl(String url)
  {
      if (!TextUtils.isEmpty(url))
      {
          url = url.trim();
          int lastIndex = url.toLowerCase().lastIndexOf(PDF_EXTENSION);
          if (lastIndex != -1)
          {
              return url.substring(lastIndex).equalsIgnoreCase(PDF_EXTENSION);
          }
      }
    return false;
  }
}
2
Ashish Das

物事の見た目では、あなたが指しているURLには、デバイス固有の場所参照が含まれています。

内部ストアにファイルをダウンロードし、インテントを使用してPDFアプリをインストールした状態で読み込む)を確認できます。

から PDF SDカードからIntent経由で開く方法

File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/example.pdf");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);

または、Web URLを使用してファイルをインスタンス化できます

1
Oliver Hemsted

ファイルをサーバーに配置すると、正常に機能します。これは、URLまたはrobots.txtで発生したGoogleドキュメントの問題です。ドキュメントは問題ありません。 URLの書き換えを使用して、Googleドキュメントが別のフォルダからのものであると思わせられるようにすることができます。パス内のこれらの奇妙な文字が問題になる可能性があります。

Doc loads fine

1
gn1

ここからソースコードをダウンロードします( webview AndroidでPDFを開く );

activity_main.xml

<RelativeLayout Android:layout_width="match_parent"
 Android:layout_height="match_parent"
 xmlns:Android="http://schemas.Android.com/apk/res/Android">

 <WebView
 Android:layout_width="match_parent"
 Android:background="#ffffff"
 Android:layout_height="match_parent"
 Android:id="@+id/webview"></WebView>


 </RelativeLayout>

MainActivity.Java

package com.pdfwebview;

import Android.app.ProgressDialog;
import Android.graphics.Bitmap;
import Android.support.v7.app.AppCompatActivity;
import Android.os.Bundle;
import Android.view.View;
import Android.webkit.WebView;
import Android.webkit.WebViewClient;

public class MainActivity extends AppCompatActivity {

 WebView webview;
 ProgressDialog pDialog;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);

 init();
 listener();
 }

 private void init() {
 webview = (WebView) findViewById(R.id.webview);
 webview.getSettings().setJavaScriptEnabled(true);

 pDialog = new ProgressDialog(MainActivity.this);
 pDialog.setTitle("PDF");
 pDialog.setMessage("Loading...");
 pDialog.setIndeterminate(false);
 pDialog.setCancelable(false);
 webview.loadUrl("https://drive.google.com/file/d/0B534aayZ5j7Yc3RhcnRlcl9maWxl/view");

 }

 private void listener() {
 webview.setWebViewClient(new WebViewClient() {
 @Override
 public void onPageStarted(WebView view, String url, Bitmap favicon) {
 super.onPageStarted(view, url, favicon);
 pDialog.show();
 }

 @Override
 public void onPageFinished(WebView view, String url) {
 super.onPageFinished(view, url);
 pDialog.dismiss();
 }
 });
 }
}
0
Deepshikha Puri

「プレビューなし」問題の解決方法は次のとおりです。正確な問題は、「 http://docs.google.com/gview?url= 」と連結したURLエンコーディングにあります。これは、URLのすべての特殊文字(:、/、&など)をUnicodeに置き換える必要があることを意味します。 Uri.encode( "")は私たちのためにトリックを行います。

String url = Uri.encode("your link");
    String finalUrl = "http://docs.google.com/viewer?url=" + url + "&embedded=true";

    WebSettings webSettings = webView.getSettings();
    webSettings.setBuiltInZoomControls(true);
    webSettings.setJavaScriptEnabled(true);
    webView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);

    webView.getSettings().setBuiltInZoomControls(true);
    webView.getSettings().setUseWideViewPort(true);
    webView.getSettings().setLoadWithOverviewMode(true);

    progressView.setVisibility(View.VISIBLE);
    webView.loadUrl(finalUrl);

    webView.setWebViewClient(new WebViewClient() {

        @Override
        public void onPageFinished(WebView view, String url) {
            view.getSettings().setLoadsImagesAutomatically(true);
            webView.setVisibility(View.VISIBLE);
            //progressView.setVisibility(View.VISIBLE);

            if (progressView != null && progressView.isShown()) {
                progressView.setVisibility(View.GONE);
            }

            Log.v("after load", view.getUrl());
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {

        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            Toast.makeText(getApplicationContext(), description, Toast.LENGTH_SHORT).show();
            Log.e("error", description);

        }
    });
0
Tushar Baweja