很气愤,凭什么同样的需求,给个pdf网页,ios就可以直接打开,android偏偏不能,本来就挺大的app,为了这一个小功能,不值得再去导jar包,求助我们的大神,最终做成的结果是——先下载到本地,再利用本地支持pdf的应用打开。
废话不多说,上代码!
URL url = null;
try {
url = new URL(docUrl);//docUrl为pdf地址
String path = Environment.getExternalStorageDirectory()
+ "/Download/";
String[] splitStrings = docUrl.split("/");
String[] nameStrings = splitStrings[splitStrings.length - 1]
.split(".pdf");
String fileName = nameStrings[0] + ".pdf";//当pdf的url带签名时,文件名过长下载会失败
File file = new File(path + fileName);
ExecutorService executorService = Executors
.newSingleThreadExecutor();
Downloader downloader = new Downloader();
downloader.setUrlAndFile(url, file);
File downloadFile = executorService.submit(downloader)
.get();
// loadingDialog.dismiss();
Uri path1 = Uri.fromFile(downloadFile);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setDataAndType(path1, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
ToastUtil.showToast(context, "打开失败");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
其中用到的两个工具类:
package com.md.apic.utils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.concurrent.Callable;
public class Downloader implements Callable<File> {
protected int connectTimeout = 30 * 1000;
protected int readTimeout = 1 * 1000 * 1000;
protected int speedRefreshInterval = 500;
protected byte[] buffer;
private URL url;
private File file;
private float averageSpeed;
private float currentSpeed;
public Downloader() {
buffer = new byte[8 * 1024];
}
public void setUrlAndFile(URL url, File file) {
this.url = url;
this.file = file;
this.averageSpeed = 0;
this.currentSpeed = 0;
}
public URL getUrl() {
return url;
}
public File getFile() {
return file;
}
public float getAverageSpeed() {
return averageSpeed;
}
public float getCurrentSpeed() {
return currentSpeed;
}
@Override
public File call() throws Exception {
StopWatch watch = new StopWatch();
watch.start();
InputStream in = null;
OutputStream out = null;
try {
URLConnection conn = url.openConnection();
conn.setConnectTimeout(connectTimeout);
conn.setReadTimeout(readTimeout);
conn.connect();
in = conn.getInputStream();
out = new FileOutputStream(file);
int time = 0;
int bytesInTime = 0;
for (;;) {
watch.split();
int bytes = in.read(buffer);
if (bytes == -1) {
break;
}
out.write(buffer, 0, bytes);
time += watch.getTimeFromSplit();
if (time >= speedRefreshInterval) {
currentSpeed = getSpeed(bytesInTime, time);
time = 0;
bytesInTime = 0;
}
}
} catch (IOException e) {
file.delete();
throw e;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
if (out != null) {
try {
out.flush();
out.close();
} catch (IOException e) {
}
}
}
watch.stop();
averageSpeed = getSpeed(file.length(), watch.getTime());
return file;
}
private static float getSpeed(long bytesInTime, long time) {
return (float) bytesInTime / 1024 / ((float) time / 1000);
}
}
package com.md.apic.utils;
import java.util.concurrent.TimeUnit;
public class StopWatch {
private long startTime;
private long stopTime;
private State state;
private boolean split;
public StopWatch() {
reset();
}
public void start() {
if (state == State.UNSTARTED) {
startTime = System.nanoTime();
state = State.RUNNING;
return;
}
throw new RuntimeException("Stopwatch already started or stopped.");
}
public void stop() {
switch (state) {
case RUNNING: {
stopTime = System.nanoTime();
}
case SUSPENDED: {
state = State.STOPPED;
split = false;
return;
}
}
throw new RuntimeException("Stopwatch is not running.");
}
public void reset() {
state = State.UNSTARTED;
split = false;
}
public void split() {
if (state == State.RUNNING) {
stopTime = System.nanoTime();
split = true;
return;
}
throw new RuntimeException("Stopwatch is not running.");
}
public void suspend() {
if (state == State.RUNNING) {
stopTime = System.nanoTime();
state = State.SUSPENDED;
return;
}
throw new RuntimeException("Stopwatch must be running to suspend.");
}
public void resume() {
if (state == State.SUSPENDED) {
startTime += System.nanoTime() - stopTime;
state = State.RUNNING;
return;
}
throw new RuntimeException("Stopwatch must be suspended to resume.");
}
public long getTime() {
return TimeUnit.NANOSECONDS.toMillis(getNanoTime());
}
public long getNanoTime() {
switch (state) {
case RUNNING: {
return System.nanoTime() - startTime;
}
case STOPPED:
case SUSPENDED: {
return stopTime - startTime;
}
case UNSTARTED: {
return 0;
}
}
throw new RuntimeException("Should never get here.");
}
public long getSplitTime() {
return TimeUnit.NANOSECONDS.toMillis(getSplitNanoTime());
}
public long getSplitNanoTime() {
if (split) {
return stopTime - startTime;
}
throw new RuntimeException(
"Stopwatch must be running and split to get the split time.");
}
public long getTimeFromSplit() {
return TimeUnit.NANOSECONDS.toMillis(getNanoTimeFromSplit());
}
public long getNanoTimeFromSplit() {
if (state == State.RUNNING && split) {
return System.nanoTime() - stopTime;
}
throw new RuntimeException(
"Stopwatch must be running and split to get the time from split.");
}
enum State {
UNSTARTED, RUNNING, STOPPED, SUSPENDED
}
}
由于代码是大神给的,出处不可考证了,若有人发现,望告知,谢谢啦!