对于想了解AndroidHttp下载文件到手机内存与SDCard的读者,本文将提供新的信息,我们将详细介绍android下载文件保存到本地,并且为您提供关于androidasynHttp下载PDF文件
对于想了解Android Http下载文件到手机内存与SDCard的读者,本文将提供新的信息,我们将详细介绍android下载文件保存到本地,并且为您提供关于android asynHttp下载PDF文件时报空指针、android JNI C 代码对 sdcard 中文件的操作、android JNI C代码对sdcard中文件的操作、Android OkHttp + Retrofit 下载文件与进度监听的有价值信息。
本文目录一览:- Android Http下载文件到手机内存与SDCard(android下载文件保存到本地)
- android asynHttp下载PDF文件时报空指针
- android JNI C 代码对 sdcard 中文件的操作
- android JNI C代码对sdcard中文件的操作
- Android OkHttp + Retrofit 下载文件与进度监听
Android Http下载文件到手机内存与SDCard(android下载文件保存到本地)
访问Internet和保存文件到SDCard上,首先要在mainifest.xml文件中加上下面的权限。
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
gettextfilestring(String url)获取文本文件内容
public String gettextfilestring(String url){
InputStream input =getinputStream(url);
StringBuffer sb = new StringBuffer("");
BufferedReader bfr = new BufferedReader(new InputStreamReader(input));
String line = "";
try {
while((line=bfr.readLine())!=null){
sb.append(line);
}
} catch (IOException e) {
toasterror("流文件读写错误");
e.printStackTrace();
}finally{
try {
bfr.close();
} catch (IOException e) {
toasterror("流文件未能正常关闭");
e.printStackTrace();
}
}
return sb.toString();
}
downFiletoDecive(String url,String filename)方法下载文件到设备内存,下载的文件在应用的路径file下
public void downFiletoDecive(String url,String filename){
if((url!=null&&!"".equals(url))&&(filename!=null&&!"".equals(filename))){
InputStream input = getinputStream(url);
FileOutputStream outStream = null;
try {
outStream = c.openFileOutput(filename, Context.MODE_WORLD_READABLE|Context.MODE_WORLD_WRITEABLE);
int temp = 0;
byte[] data = new byte[1024];
while((temp = input.read(data))!=-1){
outStream.write(data, 0, temp);
}
} catch (FileNotFoundException e) {
toasterror("请传入正确的上下文");
e.printStackTrace();
} catch (IOException e) {
toastemessage("读写错误");
e.printStackTrace();
}finally{
try {
outStream.flush();
outStream.close();
} catch (IOException e) {
toasterror("流文件未能正常关闭");
e.printStackTrace();
}
}
}
toastemessage("下载成功");
}
downFiletoSDCard(String url,String path,String filename)下载文件到SDCard中,自定义保存路径
public void downFiletoSDCard(String url,String path,String filename){
if((url!=null&&!"".equals(url))&&(path!=null)&&(filename!=null&&!"".equals(filename))){
InputStream input = getinputStream(url);
downloader(input, path, filename);
}else{
/*
* 对不合发的参数做处理
*/
if(url==null||"".equals(url)){
toasterror("url不能为空或为“”");
}
if(path==null){
toasterror("path不能为空");
}
if(filename==null||"".equals(filename)){
toasterror("filename不能为空");
}
}
}
android asynHttp下载PDF文件时报空指针
手机端下载服务端的pdf文件,代码如下:
// PDF文件下载 String[] allowedContentTypes = new String[] { "application/pdf", "image/png", "image/jpeg" }; HttpUtil.get(url, params, new BinaryHttpResponseHandler( allowedContentTypes) { @Override public void onSuccess(byte[] binaryData) { super.onSuccess(binaryData); Log.i("-----pdf onSuccess-------", binaryData.toString()); } @Override public void onFailure(Throwable error, String content) { super.onFailure(error, content); Log.i("-----pdf error-------", content); } });报错如下:
请问这是什么原因呢?求指教
android JNI C 代码对 sdcard 中文件的操作
- 所有操作除路径不同其它全部相同,如:fopen, fclose, fread ...
- 别忘记把权限加上,如下:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
- 路径:mnt/sdcard/ 如:fopen ("mnt/sdcard/test.txt", "w");
以上完成后基本在手机上可以操作 SD 卡中的文件
接下来需要在 android 模拟器上使用
- 找到 sdcard.img 文件(一般在 C 盘下,不同版本 API 下都有该文件,找到自己正在使用的 API 下的该文件),用 UltraISO 打开,把自己的文件拖进去。
完成以上步骤后你就可以象在真机上一样操作 SD 卡中的文件了。
android JNI C代码对sdcard中文件的操作
- 所有操作除路径不同其它全部相同,如:fopen, fclose, fread ...
- 别忘记把权限加上,如下:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
- 路径:mnt/sdcard/ 如:fopen("mnt/sdcard/test.txt", "w");
以上完成后基本在手机上可以操作SD卡中的文件
接下来需要在android模拟器上使用
- 找到sdcard.img文件(一般在C盘下,不同版本API下都有该文件,找到自己正在使用的API下的该文件),用UltraISO打开,把自己的文件拖进去。
完成以上步骤后你就可以象在真机上一样操作SD卡中的文件了。
Android OkHttp + Retrofit 下载文件与进度监听
本文链接
下载文件是一个比较常见的需求。给定一个url,我们可以使用URLConnection下载文件。
使用OkHttp也可以通过流来下载文件。
给OkHttp中添加拦截器,即可实现下载进度的监听功能。
使用流来实现下载文件
代码可以参考:https://github.com/RustFisher/android-Basic4/tree/master/appdowloadsample
获取并使用字节流,需要注意两个要点,一个是服务接口方法的 @Streaming 注解,另一个是获取到ResponseBody。
获取流(Stream)。先定义一个服务ApiService。给方法添加上@Streaming的注解。
private interface ApiService {
@Streaming
@GET
Observable<ResponseBody> download(@Url String url);
}
初始化OkHttp。记得填入你的baseUrl。
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(8,TimeUnit.SECONDS)
.build();
retrofit = new Retrofit.Builder()
.client(okHttpClient)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl("https://yourbaseurl.com")
.build();
发起网络请求。获取到ResponseBody。
String downUrl = "xxx.com/aaa.apk";
retrofit.create(ApiService.class)
.download(downUrl)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.doOnNext(new Consumer<ResponseBody>() {
@Override
public void accept(ResponseBody responseBody) throws Exception {
// 处理 ResponseBody 中的流
}
})
.doOnError(new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.e(TAG,"accept on error: " + downUrl,throwable);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ResponseBody>() {
@Override
public void onSubscribe(disposable d) {
}
@Override
public void onNext(ResponseBody responseBody) {
}
@Override
public void onError(Throwable e) {
Log.e(TAG,"Download center retrofit onError: ",e);
}
@Override
public void onComplete() {
}
});
通过ResponseBody拿到字节流 body.byteStream()。这里会先创建一个临时文件tmpFile,把数据写到临时文件里。
下载完成后再重命名成目标文件targetFile。
public void saveFile(ResponseBody body) {
state = DownloadTaskState.DOWNLOADING;
byte[] buf = new byte[2048];
int len;
FileOutputStream fos = null;
try {
Log.d(TAG,"saveFile: body content length: " + body.contentLength());
srcInputStream = body.byteStream();
File dir = tmpFile.getParentFile();
if (dir == null) {
throw new FileNotFoundException("target file has no dir.");
}
if (!dir.exists()) {
boolean m = dir.mkdirs();
onInfo("Create dir " + m + "," + dir);
}
File file = tmpFile;
if (!file.exists()) {
boolean c = file.createNewFile();
onInfo("Create new file " + c);
}
fos = new FileOutputStream(file);
long time = System.currentTimeMillis();
while ((len = srcInputStream.read(buf)) != -1 && !isCancel) {
fos.write(buf,len);
int duration = (int) (System.currentTimeMillis() - time);
int overBytes = len - downloadBytePerMs() * duration;
if (overBytes > 0) {
try {
Thread.sleep(overBytes / downloadBytePerMs());
} catch (Exception e) {
e.printstacktrace();
}
}
time = System.currentTimeMillis();
if (isCancel) {
state = DownloadTaskState.CLOSING;
srcInputStream.close();
break;
}
}
if (!isCancel) {
fos.flush();
boolean rename = tmpFile.renameto(targetFile);
if (rename) {
setState(DownloadTaskState.DONE);
onSuccess(url);
} else {
setState(DownloadTaskState.ERROR);
onError(url,new Exception("Rename file fail. " + tmpFile));
}
}
} catch (FileNotFoundException e) {
Log.e(TAG,"saveFile: FileNotFoundException ",e);
setState(DownloadTaskState.ERROR);
onError(url,e);
} catch (Exception e) {
Log.e(TAG,"saveFile: IOException ",e);
} finally {
try {
if (srcInputStream != null) {
srcInputStream.close();
}
if (fos != null) {
fos.close();
}
} catch (IOException e) {
Log.e(TAG,"saveFile",e);
}
if (isCancel) {
onCancel(url);
}
}
}
每次读数据的循环,计算读了多少数据和用了多少时间。超过限速后主动sleep一下,达到控制下载速度的效果。
要注意不能sleep太久,以免socket关闭。
这里控制的是网络数据流与本地文件的读写速度。
下载进度监听
OkHttp实现下载进度监听,可以从字节流的读写那里入手。也可以使用拦截器,参考官方的例子。
这里用拦截器的方式实现网络下载进度监听功能。
定义回调与网络拦截器
先定义回调。
public interface ProgressListener {
void update(String url,long bytesRead,long contentLength,boolean done);
}
自定义ProgressResponseBody。
public class ProgressResponseBody extends ResponseBody {
private final ResponseBody responseBody;
private final ProgressListener progressListener;
private BufferedSource bufferedSource;
private final String url;
ProgressResponseBody(String url,ResponseBody responseBody,ProgressListener progressListener) {
this.responseBody = responseBody;
this.progressListener = progressListener;
this.url = url;
}
@Override
public MediaType contentType() {
return responseBody.contentType();
}
@Override
public long contentLength() {
return responseBody.contentLength();
}
@Override
public BufferedSource source() {
if (bufferedSource == null) {
bufferedSource = Okio.buffer(source(responseBody.source()));
}
return bufferedSource;
}
private Source source(final Source source) {
return new ForwardingSource(source) {
long totalBytesRead = 0L;
@Override
public long read(Buffer sink,long byteCount) throws IOException {
long bytesRead = super.read(sink,byteCount);
// read() returns the number of bytes read,or -1 if this source is exhausted.
totalBytesRead += bytesRead != -1 ? bytesRead : 0;
progressListener.update(url,totalBytesRead,responseBody.contentLength(),bytesRead == -1);
return bytesRead;
}
};
}
}
定义拦截器。从Response中获取信息。
public class ProgressInterceptor implements Interceptor {
private ProgressListener progressListener;
public ProgressInterceptor(ProgressListener progressListener) {
this.progressListener = progressListener;
}
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.body(new ProgressResponseBody(chain.request().url().url().toString(),originalResponse.body(),progressListener))
.build();
}
}
添加拦截器
在创建OkHttpClient时添加ProgressInterceptor。
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(8,TimeUnit.SECONDS)
.addInterceptor(new ProgressInterceptor(new ProgressListener() {
@Override
public void update(String url,boolean done) {
// tellProgress(url,bytesRead,contentLength,done);
}
}))
.build();
值得注意的是这里的进度更新非常频繁。并不一定每次回调都要去更新UI。
今天关于Android Http下载文件到手机内存与SDCard和android下载文件保存到本地的讲解已经结束,谢谢您的阅读,如果想了解更多关于android asynHttp下载PDF文件时报空指针、android JNI C 代码对 sdcard 中文件的操作、android JNI C代码对sdcard中文件的操作、Android OkHttp + Retrofit 下载文件与进度监听的相关知识,请在本站搜索。
本文标签: