1.布局
<Button
android:id="@+id/bt_open"
android:text="打开相机"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/bt_tack"
android:text="打开相册"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/img"
android:layout_width="100dp"
android:layout_height="100dp" />
2.创建实体类
public class UpLoadBean {
/**
* code : 200
* res : 上传文件成功
* data : {"url":"http://yun918.cn/study/public/uploadfiles/123/944365-ee747d1e331ed5a4.png"}
*/
private int code;
private String res;
private DataBean data;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getRes() {
return res;
}
public void setRes(String res) {
this.res = res;
}
public DataBean getData() {
return data;
}
public void setData(DataBean data) {
this.data = data;
}
public static class DataBean {
/**
* url : http://yun918.cn/study/public/uploadfiles/123/944365-ee747d1e331ed5a4.png
*/
private String url;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
}
3.retrofit接口
public interface MyServer {
public String Url = "http://yun918.cn/study/public/";
@Multipart
@POST("file_upload.php")
Observable<UpLoadBean> upload(@Part("key") RequestBody requestBody, @Part MultipartBody.Part
file);
}
4.清单文件
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
在activity之下
......
</activity>
<provider
android:authorities="com.baidu.upload.provider"
android:name="android.support.v4.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
</application>
5.创建@xml/file_paths布局
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<root-path path="" name="camera_photos" />
</PreferenceScreen>
6.实现代码
import android.Manifest;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.google.gson.Gson;
import java.io.File;
import java.io.IOException;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
private Button bt_open;
private Button bt_tack;
private ImageView img;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
bt_open = (Button) findViewById(R.id.bt_open);
bt_tack = (Button) findViewById(R.id.bt_tack);
bt_open.setOnClickListener(this);
bt_tack.setOnClickListener(this);
img = (ImageView) findViewById(R.id.img);
img.setOnClickListener(this);
}
private static final int CAMERA_CODE = 200;
private static final int ALBUM_CODE = 100;
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_open:
takePhoto();
break;
case R.id.bt_tack:
takesD();
break;
}
}
private void takesD() {
//权限判断
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
openAlbum();
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission
.WRITE_EXTERNAL_STORAGE}, 100);
}
}
private void openAlbum() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
startActivityForResult(intent,ALBUM_CODE);
}
//处理权限
private void takePhoto() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) ==
PackageManager.PERMISSION_GRANTED) {
openCamera();
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA}, 200);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (permissions[0] == Manifest.permission.CAMERA){
openCamera();
}else if (permissions[0] == Manifest.permission.WRITE_EXTERNAL_STORAGE){
openAlbum();
}
}
}
private File mFile;
private Uri mImageUri;
private void openCamera() {
//创建文件用于保存图片
mFile = new File(getExternalCacheDir(), System.currentTimeMillis() + ".jpg");
if (!mFile.exists()) {
try {
mFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
//适配7.0
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
mImageUri = Uri.fromFile(mFile);
} else {
//第二个参数要和清单文件中的配置保持一致
mImageUri = FileProvider.getUriForFile(this, "com.baidu.upload.provider", mFile);
}
//启动相机
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);//将拍照图片存入mImageUri
startActivityForResult(intent, CAMERA_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_CODE) {
if (resultCode == RESULT_OK) {
try {
//Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver()
// .openInputStream(mImageUri));
//img.setImageBitmap(bitmap);
//处理照相之后的结果并上传
uploadOk(mFile);
} catch (Exception e) {
e.printStackTrace();
}
}
}else if (requestCode == ALBUM_CODE){
//相册
if (resultCode == RESULT_OK){
Uri imageUri = data.getData();
//处理uri,7.0以后的fileProvider 把URI 以content provider 方式 对外提供的解析方法
File file = getFileFromUri(imageUri, this);
if (file.exists()){
updateFile(file);
}
}
}
}
public File getFileFromUri(Uri uri, Context context) {
if (uri == null) {
return null;
}
switch (uri.getScheme()) {
case "content":
return getFileFromContentUri(uri, context);
case "file":
return new File(uri.getPath());
default:
return null;
}
}
/**
通过内容解析中查询uri中的文件路径
*/
private File getFileFromContentUri(Uri contentUri, Context context) {
if (contentUri == null) {
return null;
}
File file = null;
String filePath;
String[] filePathColumn = {MediaStore.MediaColumns.DATA};
ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(contentUri, filePathColumn, null,
null, null);
if (cursor != null) {
cursor.moveToFirst();
filePath = cursor.getString(cursor.getColumnIndex(filePathColumn[0]));
cursor.close();
if (!TextUtils.isEmpty(filePath)) {
file = new File(filePath);
}
}
return file;
}
/**
* 文件上传
*/
private void uploadOk(File file) {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.build();
//设置上传文件以及文件对应的MediaType类型
RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
//MultipartBody文件上传
/**区别:
* addFormDataPart: 上传key:value形式
* addPart: 只包含value数据
*/
RequestBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)//设置文件上传类型
.addFormDataPart("key", "img")//文件在服务器中保存的文件夹路径
.addFormDataPart("file", file.getName(), requestBody)//包含文件名字和内容
.build();
Request request = new Request.Builder()
.url("http://yun918.cn/study/public/file_upload.php")
.post(body)
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String str = response.body().string();
Gson gson = new Gson();
final UpLoadBean upLoadBean = gson.fromJson(str, UpLoadBean.class);
runOnUiThread(new Runnable() {
@Override
public void run() {
if (upLoadBean != null && upLoadBean.getCode() == 200) {
Log.d("xxx", upLoadBean.getData().getUrl());
success(upLoadBean);
} else {
Toast.makeText(MainActivity.this, "上传失败", Toast.LENGTH_SHORT).show();
}
}
});
}
});
}
private void updateFile(File file) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(MyServer.Url)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
MyServer myServer = retrofit.create(MyServer.class);
//文件封装
RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpg"),file);
MultipartBody.Part filePart = MultipartBody.Part.createFormData(
"file", file.getName(), requestBody);
//文本封装
RequestBody requestBody1 = RequestBody.create(MediaType.parse("multipart/form-data"),"img");
final Observable<UpLoadBean> upload = myServer.upload(requestBody1,filePart);
upload.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<UpLoadBean>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(UpLoadBean upLoadBean) {
if (upLoadBean != null && upLoadBean.getCode() == 200) {
Log.d("lzj", upLoadBean.getData().getUrl());
success(upLoadBean);
} else {
Toast.makeText(MainActivity.this, "上传失败", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
private void success(UpLoadBean upLoadBean) {
Toast.makeText(MainActivity.this, upLoadBean.getRes(), Toast.LENGTH_SHORT).show();
Glide.with(this).load(upLoadBean.getData().getUrl()).into(img);
}
7.用到依赖
implementation 'com.github.bumptech.glide:glide:3.7.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.google.code.gson:gson:2.2.4'
implementation 'com.squareup.okhttp3:okhttp:3.2.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' //RXjava2
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
implementation 'com.amitshekhar.android:rx2-android-networking:1.0.0'