mianActivity
String mUpFileUrl = "http://yun918.cn/study/public/file_upload.php";
@BindView(R.id.img)
ImageView mImg;
@BindView(R.id.btn_retrofit)
Button mBtnRetrofit;
@BindView(R.id.btn_HttpUrlConnection)
Button mBtnHttpUrlConnection;
private ProgressBar mPb;
private TextView mTxtProgress;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
ButterKnife.bind(this);
EventBus.getDefault().register(this);//注册EventBus,才能接收消息
checkPermiss();
}
@Subscribe(threadMode = ThreadMode.MAIN)//设置eventbus接收方法为主线程,才能更新UI组件
public void getMsg(ProgressMsg msg) {
if (msg.getFlag() == 0) {//设置进度条的最大进度值
mPb.setMax(msg.getMax());
} else if (msg.getFlag() == 1) {//设置进度条的当前进度
mPb.setProgress(msg.getProgress());
//计算百分比
int progress = mPb.getProgress();//得到进度
int max = mPb.getMax();//得到最大进度
int b = (int)(((float)progress/max)*100);//0.33444 * 100 = 33.444 得到百分比
mTxtProgress.setText(b+"%");
}
}
private void checkPermiss() {
int i = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
if (i != PackageManager.PERMISSION_GRANTED) {//没有授权,申请权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 100);
}
}
@OnClick({R.id.btn_retrofit, R.id.btn_HttpUrlConnection})
public void onClick(View v) {
switch (v.getId()) {
default:
break;
case R.id.btn_retrofit:
retrofitUpload();//retrofit上传
break;
case R.id.btn_HttpUrlConnection:
httpurlconnectionUpload();//原始的HttpUrlConnection上传,可以加进度条
break;
}
}
private void httpurlconnectionUpload() {
File file = new File("/storage/emulated/0/mm.png");///storage/emulated/0/ 真机的内存存储的位置,mm.png是在下面放的一张图片
if (file.exists()) {//文件存在则上传
//启动子线程进行上传,因为是耗时操作
new Thread() {
@Override
public void run() {
super.run();
//第2参数表示是上传文件 3表示上传的文件 4文件的名字 5是上传文件的路径url
uploadForm(null, "file", file, file.getName(), mUpFileUrl);
}
}.start();
} else {
Toast.makeText(this, "文件不存在,请检查", Toast.LENGTH_SHORT).show();
}
}
// 分割符,自己定义即可
private static final String BOUNDARY = "----1111WebKitFormBoundaryT1HoybnYeFOGFlBRqwe";
//原始的http上传
public void uploadForm(Map<String, String> params, String fileFormName, File uploadFile, String newFileName, String urlStr) {
try {
if (newFileName == null || newFileName.trim().equals("")) {
newFileName = uploadFile.getName();
}
StringBuilder sb = new StringBuilder();//比StringBuffer的性能更高,更快 因为是 线程不安全
/**
* 普通的表单数据
*/
if (params != null) {
for (String key : params.keySet()) {
sb.append("--" + BOUNDARY + "\r\n");
sb.append("Content-Disposition: form-data; name=\"" + key + "\"" + "\r\n");
sb.append("\r\n");
sb.append(params.get(key) + "\r\n");
}
}
/**
* 上传文件的头
*/
sb.append("--" + BOUNDARY + "\r\n");
sb.append("Content-Disposition: form-data; name=\"" + fileFormName + "\"; filename=\"" + newFileName + "\""
+ "\r\n");
sb.append("Content-Type: application/octet-stream" + "\r\n");// 如果服务器端有文件类型的校验,必须明确指定ContentType
sb.append("\r\n");
byte[] headerInfo = sb.toString().getBytes("UTF-8");
byte[] endInfo = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("UTF-8");
//开始和服务器的连接
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");//上传是post请求,设置为post请求
// 设置传输内容的格式,以及长度
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
conn.setRequestProperty("Content-Length", String.valueOf(headerInfo.length + uploadFile.length() + endInfo.length));
conn.setDoOutput(true);//允许向服务器传输数据
OutputStream out = conn.getOutputStream();//得到服务器的输出流,用于向服务器输出文件信息
InputStream in = new FileInputStream(uploadFile);//创建文件的输入流,获得上传文件信息,写入到out 输出流,,数据流
out.write(headerInfo); // 写入头部 (包含了普通的参数,以及文件的标示等)
int count = 0;//上传的数据的大小
int max = in.available();//in.available()得到上传文件的总大小总长度
EventBus.getDefault().post(new ProgressMsg(0, max, 0));//通过eventbus把文件的长度发送到主线程,设置为进度条的最大进度值
// 写入文件
byte[] buf = new byte[1024];//1k 每次上传1k
int len;
while ((len = in.read(buf)) != -1) {//循环读取本地的文件的内容,!= -1表示读取到新内容,继续上传
count = count + len;//当前读取的文件信息的长度
EventBus.getDefault().post(new ProgressMsg(1, max, count));//把当前上传的长度发送到主线程设置到进度条上
out.write(buf, 0, len);//读取一次信息,向服务器写入一次信息
Thread.sleep(1000);//上传1k睡一秒,总共9k需要9秒 真实项目一定把此行干掉
}
// 写入尾部
out.write(endInfo);
in.close();//上传完成,关闭输入流
out.close();//关闭输出流
//上传后,获得服务器响应的结果,判断是否成功
if (conn.getResponseCode() == 200) {
Log.i("111", "文件上传成功");
String s = stream2String(conn.getInputStream());//得到上传成功后,服务器返回的信息
Log.d("111", "uploadForm--上传成功: " + s);
String[] strs = s.split("<br />");
String json = strs[strs.length - 1];
UploadResultsBean bean = new Gson().fromJson(json, UploadResultsBean.class);
//切换到主线程,加载上传后的网络图片
runOnUiThread(new Runnable() {
@Override
public void run() {
Glide.with(MainActivity.this).load(bean.getData().getUrl()).into(mImg);
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
public String stream2String(InputStream is) {
int len;
byte[] bytes = new byte[1024];
StringBuffer sb = new StringBuffer();
try {
while ((len = is.read(bytes)) != -1) {
sb.append(new String(bytes, 0, len));
}
is.close();
return sb.toString();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
private void retrofitUpload() {
MediaType mediaType = MediaType.parse("application/octet-stream");
File file = new File("/storage/emulated/0/mm.png");///storage/emulated/0/ 真机的内存存储的位置,mm.png是在下面放的一张图片
if (file.exists()) {//图片文件存在则上传
RequestBody requestBody = RequestBody.create(mediaType, file);
// "file" 固定的写法,服务器进行识别
MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), requestBody);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ApiService.BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
ApiService apiService = retrofit.create(ApiService.class);
Observable<ResponseBody> observable = apiService.upFile(part);
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ResponseBody>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(ResponseBody responseBody) {
try {
String string = responseBody.string();//得到上传成功后服务器返回的字符串
String[] strs = string.split("<br />");
String json = strs[strs.length - 1];
UploadResultsBean bean = new Gson().fromJson(json, UploadResultsBean.class);
Glide.with(MainActivity.this).load(bean.getData().getUrl()).into(mImg);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
}
private void initView() {
mPb = (ProgressBar) findViewById(R.id.pb);
mTxtProgress = (TextView) findViewById(R.id.txt_progress);
}
这是数据进度proagree
public class ProgressMsg {
private int flag;//标记 0 表示设置最大进度值 1表示设置当前进度
private int max;//进度条的最大进度
private int progress;//当前进度
public ProgressMsg(int flag, int max, int progress) {
this.flag = flag;
this.max = max;
this.progress = progress;
}
public int getFlag() {
return flag;
}
public void setFlag(int flag) {
this.flag = flag;
}
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
}
public int getProgress() {
return progress;
}
public void setProgress(int progress) {
this.progress = progress;
}
}