简介
- 由于Android给我们提供的Http请求方式之一 :HttpURLConnection,使用起来非常麻烦,所以一般我们实际开发并不会用HttpURLConnection和HttpClient,而是会使用别人封装好的第三方网络请求框架,诸如:Volley,android-async-http,loopj,OkHttp等,因为网络操作涉及到 异步以及多线程,自己动手写的话,很麻烦,所以实际开发还是直接用第三方。
- 这里我们选择的是近来最火的开源HTTP框架——OKHttp,来实现Android客户端的工作。
- GitHub地址:https://github.com/square/okhttp
- 上传功能包含了一个简单的文件选择器
- 下载功能目前做得极不完善,几乎等于没做,后续还会改进
准备工作
- 新建一个安卓工程
- 从官方网站上下载okhttp和okio的jar包 okhttp的下载地址:http://square.github.io/okhttp/ okio的下载地址: https://repo1.maven.org/maven2/com/squareup/okio/okio/1.11.0/okio-1.11.0.jar okio的jar包的下载地址其实就在okhttp的官网上,不一定用我给的链接去下载。 PS.也可以通过Maven或者Gradle来导入,但因为速度太慢,所以我直接下了jar包
3.将这两个jar包导入到工程中,放在libs目录下
右键点击jar包,选择Add As Library就行了,两个包都要添加。
下面是具体代码
package com.example.ywy.mycloud1; import java.io.FileOutputStream; import java.io.IOException; import android.Manifest; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.TimeUnit; import okhttp3.Call; import okhttp3.Callback; import okhttp3.Interceptor; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import okhttp3.ResponseBody; import okio.Buffer; import okio.BufferedSink; import okio.BufferedSource; import okio.ForwardingSink; import okio.ForwardingSource; import okio.Okio; import okio.Sink; import okio.Source; public class MainActivity extends AppCompatActivity { private OkHttpClient okHttpClient; private TextView textView; private File tempFile; private File targetFile; private String path; private Button button1; private Button button2; private Button button3; private Button button4; //private long time; private static final int REQUEST_EXTERNAL_STORAGE = 1; private static final int FILE_SELECT_CODE = 1; private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setTitle("上传文件并显示进度"); //verifyStoragePermissions(MainActivity.this); textView = (TextView) findViewById(R.id.tv1); button1 = (Button) findViewById(R.id.btn_choose); button2 = (Button) findViewById(R.id.btn_upload); button3 = (Button) findViewById(R.id.btn_download); button4 = (Button) findViewById(R.id.btn_display); path = ""; okHttpClient = new OkHttpClient.Builder() .readTimeout(60, TimeUnit.SECONDS) .connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(120, TimeUnit.SECONDS) .build(); button1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showFileChooser(); } }); button2.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startUploadClick(); } }); button3.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startDownloadClick(); } }); button4.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this,DisplayActivity.class); startActivity(intent); } }); } //打开文件选择器 private void showFileChooser() { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("*/*"); intent.addCategory(Intent.CATEGORY_OPENABLE); try { startActivityForResult( Intent.createChooser(intent, "Select a File to Upload"), FILE_SELECT_CODE); } catch (android.content.ActivityNotFoundException ex) { Toast.makeText(this, "Please install a File Manager.", Toast.LENGTH_SHORT).show(); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case FILE_SELECT_CODE: if (resultCode == RESULT_OK) { // Get the Uri of the selected file Uri uri = data.getData(); path = FileUtils.getPath(this, uri); } break; } super.onActivityResult(requestCode, resultCode, data); } public String getFileName(String pathandname){ int start=pathandname.lastIndexOf("/"); //int end=pathandname.lastIndexOf(""); if(start!=-1 ){ return pathandname.substring(start+1); }else{ return null; } } //点击按钮开始上传文件 public void startUploadClick() { //tempFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "test1.txt"); //showFileChooser(); String fileName = ""; tempFile = new File(path); //tempFile = new File("/data/data/upload/man.jpg"); if (tempFile.getName() == null){ Toast.makeText(MainActivity.this, "找不到该文件!", Toast.LENGTH_SHORT).show(); } else { fileName = getFileName(path); } RequestBody requestBody = new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("file", fileName, RequestBody.create(MediaType.parse("image/jpg"), tempFile)) .build(); //ProgressRequestBody progressRequestBody = new ProgressRequestBody(requestBody, progressListener); Request request = new Request.Builder() .url("http://xxx.xxx.xxx.xx/receive_file.php") .post(requestBody) .build(); //上面url中的内容请改成自己php文件的所在地址 okHttpClient.newCall(request).enqueue(callback_upload); } //点击按钮开始下载文件 public void startDownloadClick() { targetFile = new File("/data/data/com.example.ywy.mycloud1/cache/" + "test1.jpg"); Request request = new Request.Builder() .url("http://xxx.xxx.xxx.xx/downloads/woman.jpg") .build(); okHttpClient.newCall(request).enqueue(callback_download); //上面url中的内容请改成自己想要下载的文件的所在地址 } //上传请求后的回调方法 private Callback callback_upload = new Callback() { @Override public void onFailure(Call call, IOException e) { setResult(e.getMessage(), false); } @Override public void onResponse(Call call, Response response) throws IOException { setResult(response.body().string(), true); } }; private Callback callback_download = new Callback() { @Override public void onFailure(Call call, IOException e) { setResult(e.getMessage(),false); } @Override public void onResponse(Call call, Response response) throws IOException { if(response != null) { //下载完成,保存数据到文件 //verifyStoragePermissions(MainActivity.this); InputStream is = response.body().byteStream(); FileOutputStream fos = new FileOutputStream(targetFile); byte[] buf = new byte[1024]; int hasRead = 0; while((hasRead = is.read(buf)) > 0) { fos.write(buf, 0, hasRead); } fos.close(); is.close(); setResult("下载成功", true); } } }; //显示请求返回的结果 private void setResult(final String msg, final boolean success) { runOnUiThread(new Runnable() { @Override public void run() { if (success) { Toast.makeText(MainActivity.this, "请求成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MainActivity.this, "请求失败", Toast.LENGTH_SHORT).show(); } textView.setText(msg); } }); }}FileUtils.java 用来辅助以获取所选文件的目录
package com.example.ywy.mycloud1;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
/**
* Created by YWY on 2016/11/9.
*/
public class FileUtils {
public static String getPath(Context context, Uri uri) {
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = { "_data" };
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection,null, null, null);
int column_index = cursor.getColumnIndexOrThrow("_data");
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
// Eat it
}
}
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
}
DisplayActivity.java 展示下载内容的一个Activity,没什么用
package com.example.ywy.mycloud1;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
public class DisplayActivity extends AppCompatActivity {
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display);
imageView = (ImageView)findViewById(R.id.iv);
Bitmap bitmap = BitmapFactory.decodeFile("/data/data/com.example.ywy.mycloud1/cache/test1.jpg");
imageView.setImageBitmap(bitmap);
}
}
还有两个布局文件就不贴了,很简单,自己写一下就行,无非是一些Button和TextView。
另外,不要忘了在AndroidManifest文件中添加读写存储以及联网的权限
<uses-permission
Android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" />
<uses-permission android:name="androd.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />