【问题标题】:Android - Detect URL mime type?Android - 检测 URL mime 类型?
【发布时间】:2011-12-01 15:13:34
【问题描述】:

在我的 Android 应用程序中,我有各种从数据库访问的 URL,然后打开 WebView 以显示该 URL。通常,url 看起来像这样:

http://www.mysite.com/referral.php?id=12345

这些推荐链接总是重定向/转发到另一个网址。有时生成的 url 直接指向图像。有时它是PDF。有时它只是另一个 HTML 页面。

无论如何,我需要能够区分这些不同类型的页面。例如,如果生成的 URL 链接到 PDF 文件,我想使用 Google Docs Viewer 技巧来显示它。如果它只是一个纯 HTML 页面,我想简单地显示它,如果它是图像,我计划下载图像并以某种方式在我的应用程序中显示它。

我认为解决此问题的最佳方法是确定生成的 url 的 mime 类型。你怎么做到这一点?有没有更好的方法来完成我想要的?

【问题讨论】:

    标签: android url webview mime-types


    【解决方案1】:

    您可以通过这种方式找出什么 mime 类型的内容:

    webView.setDownloadListener(new DownloadListener() {
        @Override
        public void onDownloadStart(String url, String userAgent,
                String contentDisposition, String mimetype,
                long contentLength) {
    
            //here you getting the String mimetype
            //and you can do with it whatever you want
        }
    });
    

    在此方法中,您可以检查 mimetype 是否为 pdf,并使用修改后的 url 在 WebView 中通过 Google Docs 显示它:

    String pdfPrefixUrl = "https://docs.google.com/gview?embedded=true&url="
    
    if ("application/pdf".equals(mimetype)) {
         String newUrl = pdfPrefixUrl + url;
         webView.loadUrl(newUrl);
    }    
    

    希望对您有所帮助!

    【讨论】:

    • 你救了我@Yazon2006。谢谢
    • 这仅适用于下载的文件。对于通常直接在浏览器中显示的内容,例如图像,它不起作用。
    【解决方案2】:

    这是我获取 mime 类型的解决方案。

    它也适用于主线程 (UI) 并提供 B 计划 来猜测 mime 类型(虽然不是 100% 确定)

    import java.net.URL;
    import java.net.URLConnection;
    
    public static String getMimeType(String url)
    {
        String mimeType = null;
    
        // this is to handle call from main thread
        StrictMode.ThreadPolicy prviousThreadPolicy = StrictMode.getThreadPolicy();
    
        // temporary allow network access main thread
        // in order to get mime type from content-type
    
        StrictMode.ThreadPolicy permitAllPolicy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(permitAllPolicy);
    
        try
        {
            URLConnection connection = new URL(url).openConnection();
            connection.setConnectTimeout(150);
            connection.setReadTimeout(150);
            mimeType = connection.getContentType();
            Log.i("", "mimeType from content-type "+ mimeType);
        }
        catch (Exception ignored)
        {
        }
        finally
        {
            // restore main thread's default network access policy
            StrictMode.setThreadPolicy(prviousThreadPolicy);
        }
    
        if(mimeType == null)
        {
            // Our B plan: guessing from from url
            try
            {
                mimeType = URLConnection.guessContentTypeFromName(url);
            }
            catch (Exception ignored)
            {
            }
            Log.i("", "mimeType guessed from url "+ mimeType);
        }
        return mimeType;
    }
    

    注意事项:

    • 我添加了 150 毫秒 超时:随意调整它,或者如果您从主线程外部调用它,则将其删除(您可以等待 URLCconnection 执行这是工作)。此外,如果您在主线程之外使用 ThreadPolicy 的东西,它也是无用的。关于那个...

    • 对于那些想知道为什么我允许主线程上的网络的人,原因如下:

      我必须找到一种从主线程获取 mime 类型的方法,因为 WebViewClient. shouldOverrideKeyEvent (WebView view, KeyEvent event) 在主线程中被调用,并且我的实现需要知道 mime 类型才能返回适当的值(对或错)

    【讨论】:

      【解决方案3】:

      我认为内容类型 http 标头应该可以解决问题:

      Content type

      【讨论】:

      • 任何线索如何访问 Android 中的标头?
      • 您正在使用 AndroidHTTPClient 或类似的东西来获取这些链接的内容?如果是,那么您应该在 HTTP 客户端类返回的 HttpResponse 对象中有 getHeaders 方法。
      • 我想通了。我使用HttpClientHttpGetHttpResponse 来检索标题并寻找Content-Type 标题。谢谢!
      猜你喜欢
      • 2015-12-04
      • 2015-10-05
      • 2010-10-13
      • 2012-04-11
      • 1970-01-01
      • 1970-01-01
      • 2011-07-13
      • 2013-04-17
      • 2016-05-20
      相关资源
      最近更新 更多