2013-12-18 35 views
0

我想从url下载PDF并且还想在没有检测到PDF Viewer时触发catch短语。ActivityNotFoundException不会触发打开下载的PDF文件

这里是我的代码:

try { 
     startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(materialPdfUrl))); 
    } catch (ActivityNotFoundException e) { 
     openDialog(getString(R.string.error), 
       getString(R.string.no_pdf_reader)); 
    } 

现在的问题是,ActivityNotFoundException永远不会触发因为它总是下载PDF即使周围没有PDF浏览器。你如何建议我这样做?

编辑: 这是我的旧代码:

Intent pdfIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(materialPdfUrl)); 
pdfIntent.setType("application/pdf"); 
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 
startActivity(pdfIntent); 
+0

告诉我你的openDialog(的getString(R.string.error), 的getString(R.string.no_pdf_reader)代码 –

+0

@ ManishPatel我的''openDialog'与发布内容类似[这里](http://stackoverflow.com/a/20653259/1968739)。 –

回答

1

功能startActivity()您使用不上的PDF阅读器是不存在的条件下,它只是下载从PDF格式URL,如果有PDF阅读器,那么它将提供一个选择器,就像点击PDF文件的功能一样。

+0

这正是我发生的事情,其实我编辑了我的代码,我发布了我的旧代码它发生了什么** DID **触发了“catch”短语,但它没有下载PDF。所以当我有了我时d已经是一个PDF查看器,例如Adobe PDF Viewer,它已经打开了Adobe,但它并没有打开该文件,因为它没有下载。因此,我的新代码。 –

0

使用startActivityForResult(..)。

See the link here.

Intent intent = new Intent(Intent.ACTION_VIEW); 
intent.setDataAndType(Uri.fromFile(file), "application/pdf"); 
startActivityForResult(intent, REQUEST_CODE); 

你会得到你的活动的结果在onActivityResult(..)。

0

这是因为您的设备或模拟器没有能够查看本地PDF文件的应用程序。

每当你开始一个意图,你应该在模拟器上安装本地应用程序来处理该意图。防爆。如果您使用地图作为动作调用意图,则必须使用基于Google API的模拟器。默认情况下,android模拟器没有PDF阅读器。你可以在带有PDF阅读器的设备上测试它,它应该可以正常工作。

+0

这是发生了什么,我没有PDF阅读器。但它仍然触发了'try'短语并下载了PDF。 –

1

你可以试试这段代码。这可能对你有帮助。

Intent intent = new Intent(); 


          intent.setClassName("com.adobe.reader", "com.adobe.reader.AdobeReader"); 

          intent.setAction(android.content.Intent.ACTION_VIEW); 
          intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 

          Uri uri = Uri.fromFile(file); 
          intent.setDataAndType(uri, "application/pdf"); 

           try { 

            startActivity(intent); 
           } catch (Exception e) { 

            AlertDialog.Builder builder = new AlertDialog.Builder(
              getApplicationContext()); 
            builder.setTitle("No Application Found"); 
            builder.setMessage("Download application from Android Market?"); 
            builder.setPositiveButton(
              "Yes, Please", 
              new DialogInterface.OnClickListener() { 
               @Override 
               public void onClick(
                 DialogInterface dialog, 
                 int which) { 
                Intent marketIntent = new Intent(
                  Intent.ACTION_VIEW); 
                marketIntent.setData(Uri 
                  .parse("market://details?id=com.adobe.reader")); 
                mProgressDialog.dismiss(); 

                startActivity(marketIntent); 
               } 
              }); 
            builder.setNegativeButton("No, Thanks", 
              null); 
            builder.create().show(); 
           } 
+0

这与我的旧代码类似,如果我没有PDF查看器并且打开查看器(如果有),它会触发'catch'短语。问题是它只能打开查看器,但它并没有下载PDF本身,所以没有显示。这条线是做什么的? ('intent.setClassName(“com.adobe.reader”,“com.adobe.reader.AdobeReader”);') –

+0

好吧,所以你想先下载PDF然后打开它,对不对? –

+0

是的,如果没有,它会触发对话框。 –

1

我建议使用PackageManager来检测系统是否会为您处理PDF意图。

PackageManager packageManager = context.getPackageManager(); 
Intent intent = new Intent(Intent.ACTION_VIEW) 
    .setType("application/pdf"); 
List<ResolveInfo> list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY; 
if (list.size() > 0) { 
    // Happy days a PDF reader exists 
    startActivity(intent); 
} else { 
    // No PDF reader, ask the user to download one first 
    // or just open it in their browser like this 
    intent = new Intent(Intent.ACTION_VIEW) 
     .setData(Uri.parse("http://docs.google.com/gview?embedded=true&url=" + pdfUrl); 
    startActivity(intent); 
} 

有关查看意向的更多信息,请参阅此blog post。这种方法的附加好处是,你可以在应用程序尝试执行Intent之前灰掉/删除菜单选项。然后,您可以以更友好的方式向用户解释他们需要获取PDF查看器应用程序,或者实际上应用一些逻辑来回退到基于Web的PDF查看器。

已经用福昕阅读器和Adobe Reader试用了这种方法后,它们似乎都有不同的行为。 Foxit不会为您下载PDF,它会将您重定向到浏览器并下载文件。 Adobe会为你下载文件然后显示它。

因此,一旦您检测到PDF阅读器可用,那么您可能需要将PDF下载到SD卡,例如下载文件夹。这可能是在AsyncTask中最好实现的,或者您可以使用DownloadManager。然后在首选阅读器中打开本地文件Uri。这应该消除行为上的差异。也许与福昕公司打开一张票让它与Adobe一致?;)

+0

这似乎没有检测到我刚刚安装的PDF查看器,因为它触发了'else'语句。可能是什么问题呢? –

+0

可能值得尝试'setType(“application/pdf”)'而不是'setDataAndType()'。 –

+0

对不起第二条评论,我错过了编辑窗口... 我试过setType和东西似乎工作,因为它检测到Adobe Reader和Kitkat提供的Quick Office。 –

2
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(materialPdfUrl))); 

正在开始Implicit Intent,因此不会抛出ActivityNotFoundException

如果你读这http://developer.android.com/guide/components/intents-filters.html#ccases

考虑,例如,当使用者在网页上的链接,浏览器应用程序的功能。它首先尝试显示数据(就像链接到HTML页面时那样)。如果它无法显示数据,它会将隐含意图与方案和数据类型放在一起,并尝试启动可以完成这项工作的活动。如果没有收件人,它会要求下载管理器下载数据。这将其置于内容提供者的控制之下,因此可能会有更大的活动池(具有仅指定数据类型的过滤器)。

因此,如果没有找到PDF查看器,Android下载管理器将尝试下载文件(而不是抛出该异常)。

如果您想要查看pdf或被告知无法查看(而不是下载),那么您需要使用PackageManager手动查询系统,以确定应用程序是否会响应您的意图,而不是仅仅触发并忘记。


FYI ActivityNotFoundException将抛出Explicit Intent's类似:

Intent intent = new Intent(); 
intent.setComponent(new ComponentName("com.facebook","NewsFeedActivity.java")); 
startActivity(intent);``` 
+0

我也尝试过,你提到'PackageManager'来检测响应我的意图的应用程序。 [Here](http://pastebin.com/m7HvcBK8)的代码,但令人惊讶的是它没有检测到一些着名的PDF阅读器(Adobe和Foxit)。 –