Java 使用android意图从服务器打开pdf文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20603713/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Opening pdf file from server using android intent
提问by ksh
I'm searching on the web how to open pdf file from server with default pdf viewer on android. What I found is download the file first then start it in intent or load it with google docs. I don't want to do all these. I just want to load it directly from server in default pdf viewer from phone. I've tried opening video url with intent and it worked. But opening pdf url with intent is not working. Below is my code;
我在网上搜索如何在 android 上使用默认的 pdf 查看器从服务器打开 pdf 文件。我发现是先下载文件,然后有意启动它或使用谷歌文档加载它。我不想做所有这些。我只想在手机的默认 pdf 查看器中直接从服务器加载它。我试过有意打开视频网址,它奏效了。但是有意打开 pdf url 是行不通的。下面是我的代码;
private void openFilePDF(){
try{
Toast.makeText(getBaseContext(), "Opening PDF... ", Toast.LENGTH_SHORT).show();
Intent inte = new Intent(Intent.ACTION_VIEW);
inte.setDataAndType(
Uri.parse("http://122.248.233.68/pvfiles/Guide-2.pdf"),
"application/pdf");
startActivity(inte);
}catch(ActivityNotFoundException e){
Log.e("Viewer not installed on your device.", e.getMessage());
}
}
Is there any way that I can load pdf url in intent?
有什么方法可以有意加载pdf url?
回答by GrIsHu
First Create a downloader class
首先创建一个下载器类
public class Downloader {
public static void DownloadFile(String fileURL, File directory) {
try {
FileOutputStream f = new FileOutputStream(directory);
URL u = new URL(fileURL);
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
}
f.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
After that create an activity which downloads the PDF file from internet,
之后创建一个从互联网下载 PDF 文件的活动,
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String extStorageDirectory = Environment.getExternalStorageDirectory()
.toString();
File folder = new File(extStorageDirectory, "pdf");
folder.mkdir();
File file = new File(folder, "Read.pdf");
try {
file.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
Downloader.DownloadFile("http://122.248.233.68/pvfiles/Guide-2.pdf", file);
showPdf();
}
public void showPdf()
{
File file = new File(Environment.getExternalStorageDirectory()+"/Mypdf/Read.pdf");
PackageManager packageManager = getPackageManager();
Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType("application/pdf");
List list = packageManager.queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
}
}
Finally at last declare persmissions in AndroidManifest.xml
最后最后声明权限 AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
回答by Shylendra Madda
You can try this using WebView:
您可以使用 WebView 尝试此操作:
public class MyPdfViewActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView mWebView=new WebView(MyPdfViewActivity.this);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setPluginsEnabled(true);
mWebView.loadUrl("https://docs.google.com/gview?embedded=true&url="+LinkTo);
setContentView(mWebView);
}
}
回答by Vaibhav Agarwal
According to me there is no way to directly open your PDF file on device. Because of browser properties of android devices when we try to open PDF file it download to device. There is only Two way to open the PDF file.
据我说,无法直接在设备上打开您的 PDF 文件。由于 Android 设备的浏览器属性,当我们尝试打开它下载到设备的 PDF 文件时。只有两种方法可以打开 PDF 文件。
You can use PDF application Intent to choose app to open file with.
You can append your server url for file with Google docs url and can open it in browser so ur PDF file will open in browser
您可以使用 PDF 应用程序 Intent 选择打开文件的应用程序。
您可以使用 Google docs url 附加文件的服务器 url,并可以在浏览器中打开它,这样您的 PDF 文件将在浏览器中打开
回答by CodeInsideCofee
Download Pdf file from server and once download completed you can open this pdf file using pending intent.
从服务器下载 Pdf 文件,下载完成后,您可以使用待定意图打开此 pdf 文件。
Before you go to code just see below image which show functionality of my attach code.
在开始编写代码之前,请查看下图,其中显示了我的附加代码的功能。
Step - 1:You need to create on Asynchronous task to download file from server url. See below code :
步骤 - 1:您需要创建异步任务以从服务器 url 下载文件。见下面的代码:
public class DownloadFileFromURL extends AsyncTask<String, Integer, String> {
private NotificationManager mNotifyManager;
private NotificationCompat.Builder build;
private File fileurl;
int id = 123;
OutputStream output;
private Context context;
private String selectedDate;
private String ts = "";
public DownloadFileFromURL(Context context, String selectedDate) {
this.context = context;
this.selectedDate = selectedDate;
}
protected void onPreExecute() {
super.onPreExecute();
mNotifyManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
build = new NotificationCompat.Builder(context);
build.setContentTitle("Download")
.setContentText("Download in progress")
.setChannelId(id + "")
.setAutoCancel(false)
.setDefaults(0)
.setSmallIcon(R.drawable.ic_menu_download);
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(id + "",
"Social Media Downloader",
NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("no sound");
channel.setSound(null, null);
channel.enableLights(false);
channel.setLightColor(Color.BLUE);
channel.enableVibration(false);
mNotifyManager.createNotificationChannel(channel);
}
build.setProgress(100, 0, false);
mNotifyManager.notify(id, build.build());
String msg = "Download started";
//CustomToast.showToast(context,msg);
}
@Override
protected String doInBackground(String... f_url) {
int count;
ts = selectedDate.split("T")[0];
try {
URL url = new URL(f_url[0]);
URLConnection conection = url.openConnection();
conection.connect();
int lenghtOfFile = conection.getContentLength();
InputStream input = new BufferedInputStream(url.openStream(),
8192);
// Output stream
output = new FileOutputStream(Environment
.getExternalStorageDirectory().toString()
+ Const.DownloadPath + ts + ".pdf");
fileurl = new File(Environment.getExternalStorageDirectory()
+ Const.DownloadPath + ts + ".pdf");
byte[] data = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
int cur = (int) ((total * 100) / lenghtOfFile);
publishProgress(Math.min(cur, 100));
if (Math.min(cur, 100) > 98) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
Log.d("Failure", "sleeping failure");
}
}
Log.i("currentProgress", "currentProgress: " + Math.min(cur, 100) + "\n " + cur);
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
protected void onProgressUpdate(Integer... progress) {
build.setProgress(100, progress[0], false);
mNotifyManager.notify(id, build.build());
super.onProgressUpdate(progress);
}
@Override
protected void onPostExecute(String file_url) {
build.setContentText("Download complete");
Intent intent = new Intent(context, DownloadBroadcastReceiver.class);
Uri finalurl = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", fileurl);
intent.putExtra("currenturl", finalurl.toString());
intent.putExtra("selectedfilename", ts);
context.sendBroadcast(intent);
build.setProgress(0, 0, false);
mNotifyManager.notify(id, build.build());
} }
Here in Above code i create asynctask using DownloadFileFromURL.javaclass file. here in this class file write a code to displat notification in android O and older version.
在上面的代码中,我使用DownloadFileFromURL.java类文件创建了 asynctask 。这里在这个类文件中编写了一个代码来显示 android O 和旧版本中的通知。
Step -2:Once your download completed i send it to broadcast receiver. With the help of broadcast receiver you can open your PDF file in pending intent easily. You can see broadcast receiver code onPostExecutemethod of asynchronous task.
步骤-2:下载完成后,我将其发送到广播接收器。在广播接收器的帮助下,您可以轻松打开待处理的 PDF 文件。您可以看到异步任务的onPostExecute方法的广播接收器代码。
See the below code to handle pending intent in broadcast receiver.
请参阅以下代码以处理广播接收器中的待处理意图。
public class DownloadBroadcastReceiver extends BroadcastReceiver {
private NotificationManager mNotifyManager;
private NotificationCompat.Builder build;
private int rId=123;
private String localuri="";
private String selectedfilename="";
@Override
public void onReceive(Context context, Intent intent) {
localuri=intent.getStringExtra("currenturl");
selectedfilename=intent.getStringExtra("selectedfilename");
startNotification(context,intent);
}
private void startNotification(Context context, Intent intent) {
Log.e("fat", "startNotification: "+localuri );
File fileurl = new File(Environment.getExternalStorageDirectory()
+ Const.DownloadPath + selectedfilename+".pdf");
Uri finalurl = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID+".provider", fileurl);
Intent downloadintent = new Intent(Intent.ACTION_VIEW);
downloadintent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_CLEAR_TOP);
downloadintent.setDataAndType(finalurl, "application/pdf");
grantAllUriPermissions(context, downloadintent, finalurl);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, downloadintent,
PendingIntent.FLAG_UPDATE_CURRENT);
mNotifyManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
build = new NotificationCompat.Builder(context);
build.setContentTitle("Download Completed")
.setContentText("Open Downloaded FIle")
.setChannelId(rId+"")
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setStyle(new NotificationCompat.DecoratedCustomViewStyle())
.setSmallIcon(R.drawable.ic_menu_download);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(rId+"" ,
"Call Reminder",
NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("With sound");
channel.setSound(null,null);
channel.enableLights(false);
channel.setLightColor(Color.BLUE);
channel.enableVibration(true);
mNotifyManager.createNotificationChannel(channel);
}
mNotifyManager.notify(rId, build.build());
}
private void grantAllUriPermissions(Context context, Intent downloadintent, Uri finalurl) {
List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(downloadintent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
context.grantUriPermission(packageName, finalurl, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
} }
In above code you see that i added pending intent inside notification compact builder.
在上面的代码中,您可以看到我在通知紧凑构建器中添加了待处理的意图。
NOTE:when you add pending intent you have to assign access permission using below code which i already added.
注意:当您添加待处理的意图时,您必须使用我已经添加的以下代码分配访问权限。
downloadintent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_CLEAR_TOP);
grantAllUriPermissions(context, downloadintent, finalurl);
Here GrantAllpermission method is created by which support in all device.
这里的 GrantAllpermission 方法是由所有设备中的支持创建的。
private void grantAllUriPermissions(Context context, Intent downloadintent, Uri finalurl) {
List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(downloadintent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
context.grantUriPermission(packageName, finalurl, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
}
Step -3 :Add your Broadcast receiver in android Manifest file using below code.
第 -3 步:使用以下代码在 android 清单文件中添加您的广播接收器。
<receiver android:name=".services.DownloadBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Step - 4 :Also Add File Provider in Android Manifest File. With the help of File provider you can open file from your device storage.
步骤 - 4:还在 Android 清单文件中添加文件提供程序。在文件提供程序的帮助下,您可以打开设备存储中的文件。
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_path" />
</provider>
Note:if you face issue in Andorid 10(O) device than add below code in your application of android manifest file.
注意:如果您在 Andorid 10(O) 设备中遇到问题,请在您的 android 清单文件应用程序中添加以下代码。
android:requestLegacyExternalStorage="true"
With the help of requestLegacyExternalStorageyou can get list of downloaded file easily.
在requestLegacyExternalStorage的帮助下, 您可以轻松获取下载文件的列表。
Step - 5:Now Last Step is call your Asynchronous class file in your on click event. Here i write code on pdf image click. To call Asynchronous task use below code.
步骤 - 5:现在最后一步是在您的点击事件中调用您的异步类文件。在这里,我在 pdf 图像单击上编写代码。要调用异步任务,请使用以下代码。
new DownloadFileFromURL(fContext,selectedDate).execute(currentResponse.getData());
Your can Download Above code Whole File From below link:
您可以从以下链接下载以上代码整个文件:
DownloadFileFromURL.java class file