文章目录
1.在ActicityMain中,创建变量
- camera用来保存从相机传回的文件
- file用来保存文件流
- Uri存储获取图片的绝对路径
- TAKE常量保存状态码:拍照
- PICK用来保存状态码:从相册选取
2.申请权限
在AndroidManifest.xml中申请权限
-
READ_EXTERNAL_STORAGE读取外部存储
-
WRITE_EXTERNAL_STORAGE写入外部存储
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
3.在MainActicity中,处理图片
- take()
- pick()
- takePic()
- pickPic()
/**
* 函数名称:take()
*/
@TargetApi(23)
public void take() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission_group.STORAGE) == PackageManager.PERMISSION_GRANTED) {
takePic();
} else {
requestPermissions(new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE},
1);
}
} else takePic();
}
/**
* 函数名称:pick
*/
@TargetApi(23)
private void pick() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission_group.STORAGE) == PackageManager.PERMISSION_GRANTED) {
pickPic();
} else {
requestPermissions(new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE}, 2);
}
} else {
pickPic();
}
}
/**
* 函数名称:takePic
*/
private void takePic() {
file = new File(camera, SystemClock.elapsedRealtime() + ".jpg");
if (file.exists()) {
file.delete();
}
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(this, "edu.qau.phone.fileprovider", file);
} else {
uri = Uri.fromFile(file);
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, TAKE);
}
/**
* 函数名称:pickPic()
*/
public void pickPic() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, PICK);
}
4.在项目文件中,设置保存文件路径
- 在res下创建xml文件夹
- 创建file_paths.xml文件
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="pic"
path="" />
</paths>
5.在Manifests中,注册内容提供器
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="edu.qau.phone.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths">
</meta-data>
</provider>
6.在MainActicity中,检查权限函数
/**
* 函数名称:checkPermissionAllGranted()
* 判断是否有权限
*
* @param grantResults
* @return granted
*/
private boolean checkPermissionAllGranted(int[] grantResults) {
boolean granted = true;
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
granted = false;
break;
}
}
return granted;
}
7.在MainActicity中,获取申请结果
/**
* 函数名称:onRequestPermissionsResult()
*获取权限申请结果
* @param requestCode
* @param permissions
* @param grantResults
*/
@TargetApi(23)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 1:
if (checkPermissionAllGranted(grantResults)) {
takePic();
}
break;
case 2:
if (checkPermissionAllGranted(grantResults)) {
pickPic();
}
break;
}
}
8.在MainActicity中,获取活动回调
/**
* 函数名称:onActivityResult
*
* @param requestCode
* @param resultCode
* @param data
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
count++;
image = createImageView();
group.addView(image, count - 1);
switch (requestCode) {
case TAKE:
Picasso.get()
.load(file)
.resizeDimen(R.dimen.preview_width, R.dimen.preview_height)
.placeholder(R.drawable.w)
.error(R.drawable.e)
.centerCrop()
.into(image);
//处理相片
Image imageFromTake = new Image();
imageFromTake.setName(file.getName());
imageFromTake.setPath(file.getAbsolutePath());
imageFromTake.setFlag(TAKE);
list.add(imageFromTake);
break;
case PICK:
Uri uri = data.getData();
String path = ImageUtils.getPath(this, uri);
if (path != null) {
file = new File(path);
Picasso.get()
.load(file)
.resizeDimen(R.dimen.preview_width, R.dimen.preview_height)
.centerCrop()
.into(image);
Image imageFromPick = new Image();
imageFromPick.setName(file.getName());
imageFromPick.setPath(file.getAbsolutePath());
imageFromPick.setFlag(TAKE);
list.add(imageFromPick);
}
break;
}
}
}
9.在MainActicity中,设置图片显示样式
/**
* 函数名称:createImageView
* 设置展示图片样式
*
* @return iv
*/
private ImageView createImageView() {
ImageView iv = new ImageView(this);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
getResources().getDimensionPixelOffset(R.dimen.preview_width),
getResources().getDimensionPixelOffset(R.dimen.preview_height));
layoutParams.setMargins(
0,
0,
getResources().getDimensionPixelOffset(R.dimen.preview_margin_right),
0);
iv.setLayoutParams(layoutParams);
return iv;
}
10.导入依赖
- Eclips中
寻找jar包的网址 https://www.findjar.com/index.x - Android Studio中
//okHttp
implementation 'com.squareup.okhttp3:okhttp:4.0.0-RC1'
//picasso
implementation 'com.squareup.picasso:picasso:2.71828'
11.在drawable文件夹中,导入资源图片
- 资源见文章末尾
12.在ActicityMain中重写方法
/**
* 函数名称:onConfigurationChanged()
*
* @param newConfig
*/
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
13.在Manifest中,修改配置
14.此时MainActicity源码
package edu.qau.phone;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.content.FileProvider;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
import com.orhanobut.dialogplus.DialogPlus;
import com.orhanobut.dialogplus.OnItemClickListener;
import com.squareup.picasso.Picasso;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import edu.qau.bean.Image;
import edu.qau.bean.Talk;
import edu.qau.utils.ImageUtils;
import edu.qau.utils.NetWorkUtils;
import edu.qau.utils.OkHttpUtils;
import okhttp3.Call;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.BufferedSink;
public class MainActivity extends Activity {
public static final int TAKE = 1;//拍照状态码
public static final int PICK = 2;//相册选取状态码
private LayoutInflater inflater;//布局生成器
private DialogPlus dialog;//对话框
private File camera;//保存拍照图片
private File file;//文件流
private Uri uri;//从拍照的intent中传回文件路径
private int count = 0;//图片数量
private LinearLayout group;//图片显示布局
private ArrayList<Image> list;//图片存放集合
private EditText talkEditText;
private MediaType JPEG = MediaType.parse("image/jpeg");
private Handler handler;
//自定义
private ImageView image;//图片视图
/**
* 函数名称:onCreate
*
* @param savedInstanceState
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
/**
* 函数名称:init()
* 函数功能:初始化布局及设置动作响应
*/
public void init() {
list = new ArrayList<Image>();
inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
talkEditText = findViewById(R.id.talk);
group = findViewById(R.id.preview_group);
DialogAdapter adapter = new DialogAdapter();
// 新建Dialog对话框
dialog = DialogPlus.newDialog(this).setAdapter(adapter)
.setContentBackgroundResource(R.color.dialog_bg)
.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(@NonNull DialogPlus dialog, @NonNull Object item,
@NonNull View view, int position) {
if (position == 1) {
dialog.dismiss();
take();//拍照
} else if (position == 0) {
pick();//相册
} else {
dialog.dismiss();
}
}
}).setExpanded(false).create();
//创建handler
handler = new Handler(getMainLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
if (msg.what == 1) {
Toast.makeText(MainActivity.this, "上传成功", Toast.LENGTH_LONG).show();
} else if (msg.what == 2) {
Toast.makeText(MainActivity.this, "上传失败", Toast.LENGTH_LONG).show();
}
return false;
}
});
File dcim = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
if (!dcim.exists()) {
dcim.mkdir();
}
camera = new File(dcim, "camera");
if (!camera.exists()) {
camera.mkdir();
}
}
/**
* 函数名称:takePic
*/
private void takePic() {
file = new File(camera, SystemClock.elapsedRealtime() + ".jpg");
if (file.exists()) {
file.delete();
}
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(this, "edu.qau.phone.fileprovider", file);
} else {
uri = Uri.fromFile(file);
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, TAKE);
}
/**
* 函数名称:pickPic()
*/
public void pickPic() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, PICK);
}
/**
* 函数名称:take()
*/
@TargetApi(23)
public void take() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission_group.STORAGE) == PackageManager.PERMISSION_GRANTED) {
takePic();
} else {
requestPermissions(new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE},
1);
}
} else takePic();
}
/**
* 函数名称:pick
*/
@TargetApi(23)
private void pick() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission_group.STORAGE) == PackageManager.PERMISSION_GRANTED) {
pickPic();
} else {
requestPermissions(new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE}, 2);
}
} else {
pickPic();
}
}
/**
* 函数名称:createImageView
* 设置展示图片样式
*
* @return iv
*/
private ImageView createImageView() {
ImageView iv = new ImageView(this);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
getResources().getDimensionPixelOffset(R.dimen.preview_width),
getResources().getDimensionPixelOffset(R.dimen.preview_height));
layoutParams.setMargins(
0,
0,
getResources().getDimensionPixelOffset(R.dimen.preview_margin_right),
0);
iv.setLayoutParams(layoutParams);
return iv;
}
/**
* 函数名称:checkPermissionAllGranted()
* 判断是否有权限
*
* @param grantResults
* @return granted
*/
private boolean checkPermissionAllGranted(int[] grantResults) {
boolean granted = true;
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
granted = false;
break;
}
}
return granted;
}
/**
* 函数名称:submit()
* 函数功能:上传图片
*
* @param view
*/
public void submit(View view) {
int netType = NetWorkUtils.getAPNType(this);
if (netType == 0) {
Toast.makeText(this, "无法连接到网络", Toast.LENGTH_LONG).show();
} else {
String temp = talkEditText.getText().toString();
Talk talk = new Talk();
talk.setTalk(temp);
talk.setList(list);
Gson gson = new Gson();
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.addFormDataPart("json", gson.toJson(talk));
for (int i = 0; i < list.size(); i++) {
final Image image = list.get(i);
if (netType == 1) {
File uploadFile = new File(image.getPath());
builder.addFormDataPart("File" + i, uploadFile.getName(), RequestBody.create(JPEG, uploadFile));
} else {
RequestBody os = new RequestBody() {
@Nullable
@Override
public MediaType contentType() {
return JPEG;
}
@Override
public void writeTo(@NotNull BufferedSink sink) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = ImageUtils.compressImage(image.getPath(), 300);
sink.write(byteArrayOutputStream.toByteArray());
byteArrayOutputStream.close();
byteArrayOutputStream.reset();
byteArrayOutputStream = null;
}
};
builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"file" + i + "\""), os);
}
}
//IP地址自定义
final Request request = new Request.Builder().url("http://192.168.43.146.8080/Server/file")
.post(builder.build()).build();
OkHttpUtils.CLIENT.newCall(request).enqueue(new okhttp3.Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Toast.makeText(MainActivity.this, "访问网络失败", Toast.LENGTH_LONG).show();
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
String result = response.body().string();
try {
JSONObject json = new JSONObject(result);
if ("success".equals(json.getString("result"))) {
handler.sendEmptyMessage(1);
} else {
handler.sendEmptyMessage(2);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
}
/**
* 函数名称:addImg()
* 函数功能:onClick方法,检查最大图片上传数
*
* @param view
*/
public void addImg(View view) {
if (count < 9) {
dialog.show();
} else {
Toast.makeText(this, "最多上传九张", Toast.LENGTH_LONG).show();
}
}
/**
* 函数名称:onActivityResult
*
* @param requestCode
* @param resultCode
* @param data
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
count++;
image = createImageView();
group.addView(image, count - 1);
switch (requestCode) {
case TAKE:
Picasso.get()
.load(file)
.resizeDimen(R.dimen.preview_width, R.dimen.preview_height)
.placeholder(R.drawable.w)
.error(R.drawable.e)
.centerCrop()
.into(image);
//处理相片
Image imageFromTake = new Image();
imageFromTake.setName(file.getName());
imageFromTake.setPath(file.getAbsolutePath());
imageFromTake.setFlag(TAKE);
list.add(imageFromTake);
break;
case PICK:
Uri uri = data.getData();
String path = ImageUtils.getPath(this, uri);
if (path != null) {
file = new File(path);
Picasso.get()
.load(file)
.resizeDimen(R.dimen.preview_width, R.dimen.preview_height)
.centerCrop()
.into(image);
Image imageFromPick = new Image();
imageFromPick.setName(file.getName());
imageFromPick.setPath(file.getAbsolutePath());
imageFromPick.setFlag(TAKE);
list.add(imageFromPick);
}
break;
}
}
}
/**
* 函数名称:onConfigurationChanged()
*
* @param newConfig
*/
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
/**
* 函数名称:onRequestPermissionsResult()
* 获取权限申请结果
*
* @param requestCode
* @param permissions
* @param grantResults
*/
@TargetApi(23)
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 1:
if (checkPermissionAllGranted(grantResults)) {
takePic();
}
break;
case 2:
if (checkPermissionAllGranted(grantResults)) {
pickPic();
}
break;
}
}
/**
* 重写适配器
*/
private class DialogAdapter extends BaseAdapter {
@Override
public int getCount() {
return 3;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if (position == 0 || position == 1) {
view = inflater.inflate(R.layout.dialog_item, parent, false);
} else {
view = inflater.inflate(R.layout.dialog_cancel, parent, false);
}
TextView tv = view.findViewById(R.id.dialog_item);
tv.setText(position == 0 ? "从相册选择" : position == 1 ? "拍照" : "取消");
return view;
}
}
//-------------------------------自定义-----------------------------------
}
14.附件
我的github地址:https://github.com/uda97/Android_Project
寻找jarv包的网址:https://www.findjar.com/index.x