安卓上传圆角头像到服务器功能
第一次写技术文章,有啥不对的地方往多多指教。
今天为大家带来一篇上传圆角头像的功能吧。
功能逻辑流程
第一步 选择照片/拍照(选择照片和拍照分别需要文件读取和相机权限)
第二步 剪切圆角
第三部 上传图片
这里我使用的是OkHttp(一款强大的网络请求三方)来进行网络请求
GitHub地址
代码如下:
类属性
// 页面返回参数
private final int CHOOSE_PICTURE = 0;
private final int TAKE_PICTURE = 1;
private final int CROP_SMALL_PICTURE = 2;
private final int MY_PERMISSIONS_REQUEST_CALL_PHONE = 6;
// 圆角图片地址
private Uri tempUri;
检查权限
public void choosePhone(){
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_CALL_PHONE);
}else {
showChoosePicDialog();
}
}
弹出选择框
protected void showChoosePicDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("设置头像");
String[] items = { "选择本地照片", "拍照" };
builder.setNegativeButton("取消", null);
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case CHOOSE_PICTURE: // 选择本地照片
// 判断当前系统版本
String intentactiong = "";
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {//4.4版本前
intentactiong = Intent.ACTION_GET_CONTENT;
} else {//4.4版本后
intentactiong = Intent.ACTION_PICK;
}
Intent openAlbumIntent = new Intent(intentactiong);
openAlbumIntent.setDataAndType(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(openAlbumIntent, CHOOSE_PICTURE);
break;
case TAKE_PICTURE: // 拍照
Intent openCameraIntent = new Intent(
MediaStore.ACTION_IMAGE_CAPTURE);
tempUri = Uri.fromFile(new File(Environment
.getExternalStorageDirectory(), "image.jpg"));
// 指定照片保存路径(SD卡),image.jpg为一个临时文件,每次拍照后这个图片都会被替换
openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
startActivityForResult(openCameraIntent, TAKE_PICTURE);
break;
}
}
});
builder.create().show();
}
裁剪圆角方法
protected void startPhotoZoom(Uri uri) {
if (uri == null) {
Log.i(TAG, "The uri is not exist.");
}
tempUri = uri;
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
// 设置裁剪
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// outputX outputY 是裁剪图片宽高
intent.putExtra("outputX", 150);
intent.putExtra("outputY", 150);
intent.putExtra("return-data", true);
startActivityForResult(intent, CROP_SMALL_PICTURE);
Log.d(TAG, "startPhotoZoom: 剪切完毕");
}
保存裁剪之后的图片数据
protected void setImageToView(Intent data) {
Bundle extras = data.getExtras();
if (extras != null) {
Bitmap photo = extras.getParcelable("data");
photo = ImgUtils.toRoundBitmap(photo, tempUri); // 这个时候的图片已经被处理成圆形的了
avatar.setImageBitmap(photo);
// 上传头像文件
imgUriList.clear();
String imagePath = ImgUtils.savePhoto(photo, Environment
.getExternalStorageDirectory().getAbsolutePath(), String
.valueOf(System.currentTimeMillis()));
// 这里我是封装的多文件上传,所以使用list保存文件地址;
imgUriList.add(imagePath);
}
}
重写页面返回值方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "onActivityResult: resultCode=" + resultCode);
if (resultCode == RESULT_OK) { // 如果返回码是可以用的
switch (requestCode) {
case TAKE_PICTURE:
startPhotoZoom(tempUri); // 开始对图片进行裁剪处理
break;
case CHOOSE_PICTURE:
startPhotoZoom(data.getData()); // 开始对图片进行裁剪处理
break;
case CROP_SMALL_PICTURE:
if (data != null) {
setImageToView(data); // 让刚才选择裁剪得到的图片显示在界面上
}
break;
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
{
if (requestCode == MY_PERMISSIONS_REQUEST_CALL_PHONE)
{
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
choosePhone();
} else
{
// Permission Denied
Toast.makeText(SettingAccounts.this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
好了,到了最后一步,也就是根据后台给你的接口上传图片到你们服务器了
public void changeUserInfo() {
// 检查网络状态
if (NetUtil.isNetworkAvalible(this)) {
String address = "功能模块地址";
Map map = new HashMap<>();
map.put("键", 值);
try {
HttpUtil.sendFileUpdataRequest(map, imgUriList, "pic", address, this, new HttpResponseInfo() {
@Override
public void responseOk() {
}
@Override
public void responseErr() {
runOnUiThread(new Runnable() {
@Override
public void run() {
loadingDialog.dismiss();
Toast.makeText(SettingAccounts.this, "修改失败!", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void responseInfo(final String response) {
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
Toast.makeText(SettingAccounts.this, "修改成功!", Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
@Override
public void requestErr() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(SettingAccounts.this, "网络请求失败!", Toast.LENGTH_SHORT).show();
}
});
}
});
} catch (IOException e) {
e.printStackTrace();
}
} else {
NetUtil.checkNetwork(this);
}
}
网络请求的方法(比较懒,就把多图和单图封装了一个方法),可根据自己后台的需求改动
/**
* 通用文件网络请求
* @param arguments 请求参数
* @param filesPath 文件列表
*/
public static void sendFileUpdataRequest(Map arguments,
List filesPath,
String filesKey,
String address,
Context context,
final HttpResponseInfo responseInfo
) throws IOException {
// mImgUrls为存放图片的url集合
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
// 遍历map
for (String key : arguments.keySet()) {
builder.addFormDataPart(key, arguments.get(key).toString());
}
ImageFactoryUtil imageFactoryUtil = new ImageFactoryUtil();
if (filesKey != null && address != null) {
if (filesPath.size() == 1) {
// 单图上传
imageFactoryUtil.compressAndGenImage(filesPath.get(0),
filesPath.get(0),
DensityUtil.dip2px(context, 125),
false);
File f = new File(filesPath.get(0));
if (f != null) {
builder.addFormDataPart(filesKey, f.getName(), RequestBody.create(MEDIA_TYPE_ALL, f));
}
} else {
// 多图上传
for (int i = 0; i < filesPath.size() ; i++) {
// 单图上传
imageFactoryUtil.compressAndGenImage(filesPath.get(i),
filesPath.get(i),
DensityUtil.dip2px(context, 125),
false);
File f = new File(filesPath.get(i));
if (f != null) {
// 这里的多图上传规则需要问你的后台哈
builder.addFormDataPart(filesKey + "[" + i + "]", f.getName(), RequestBody.create(MEDIA_TYPE_ALL, f));
}
}
}
}
MultipartBody requestBody = builder.build();
//构建请求
Request request = new Request.Builder()
.url(serviceUrlStr + address)//serviceUrlStr为你的项目接口地址,address为模块地址
.post(requestBody)//添加请求体
.build();
Log.d("HttpUtil", "requestBody: " + requestBody);
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 网络请求失败
responseInfo.requestErr();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseStr = response.body().string();
try {
JSONObject obj = new JSONObject(responseStr);
if (Integer.valueOf(obj.getString("code")) == 1) {
responseInfo.responseOk();
responseInfo.responseInfo(responseStr);
} else {
responseInfo.responseErr();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
你以为到这里就结束了?
这里把需要用的到工具类也贴出来吧,嘿嘿。
网络状态检测类:
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.provider.Settings;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.widget.TextView;
import com.anhukeji.hellodoctor.R;
/**
* 网络状态检测工具类
* Created by whm on 2017/6/30.
*/
public class NetUtil {
/**
* 判断网络情况
*
* @param context 上下文
* @return false 表示没有网络 true 表示有网络
*/
public static boolean isNetworkAvalible(Context context) {
// 获得网络状态管理器
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager == null) {
return false;
} else {
// 建立网络数组
NetworkInfo[] net_info = connectivityManager.getAllNetworkInfo();
if (net_info != null) {
for (int i = 0; i < net_info.length; i++) {
// 判断获得的网络状态是否是处于连接状态
if (net_info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
}
return false;
}
// 如果没有网络,则弹出网络设置对话框
public static void checkNetwork(final Activity activity) {
if (!NetUtil.isNetworkAvalible(activity)) {
TextView msg = new TextView(activity);
msg.setText("当前没有可以使用的网络,请设置网络!");
new AlertDialog.Builder(activity)
.setIcon(R.mipmap.app_icon)
.setTitle("网络状态提示")
.setView(msg)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// 跳转到设置界面
activity.startActivityForResult(new Intent(Settings.ACTION_WIRELESS_SETTINGS), 0);
}
}).create().show();
}
return;
}
/**
* 判断网络是否连接
**/
public static boolean netState(Context context) {
ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
// 获取代表联网状态的NetWorkInfo对象
NetworkInfo networkInfo = connManager.getActiveNetworkInfo();
// 获取当前的网络连接是否可用
boolean available = false;
try {
available = networkInfo.isAvailable();
} catch (Exception e) {
e.printStackTrace();
return false;
}
if (available) {
Log.i("通知", "当前的网络连接可用");
return true;
} else {
Log.i("通知", "当前的网络连接可用");
return false;
}
}
/**
* 在连接到网络基础之上,判断设备是否是SIM网络连接
*
* @param context
* @return
*/
public static boolean IsMobileNetConnect(Context context) {
try {
ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo.State state = connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState();
if (NetworkInfo.State.CONNECTED == state)
return true;
else
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
然后是处理图片圆角工具类:
/**
* Created by whm on 2017/6/30.
*/
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.PorterDuff.Mode;
import android.net.Uri;
import android.os.Environment;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class ImgUtils {
public ImgUtils() {
}
public static String savePhoto(Bitmap photoBitmap, String path, String photoName) {
String localPath = null;
if(Environment.getExternalStorageState().equals("mounted")) {
File dir = new File(path);
if(!dir.exists()) {
dir.mkdirs();
}
File photoFile = new File(path, photoName + ".png");
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(photoFile);
if(photoBitmap != null && photoBitmap.compress(CompressFormat.PNG, 100, fileOutputStream)) {
localPath = photoFile.getPath();
fileOutputStream.flush();
}
} catch (FileNotFoundException var18) {
photoFile.delete();
localPath = null;
var18.printStackTrace();
} catch (IOException var19) {
photoFile.delete();
localPath = null;
var19.printStackTrace();
} finally {
try {
if(fileOutputStream != null) {
fileOutputStream.close();
fileOutputStream = null;
}
} catch (IOException var17) {
var17.printStackTrace();
}
}
}
return localPath;
}
public static Bitmap toRoundBitmap(Bitmap bitmap, Uri tempUri) {
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float roundPx;
float left;
float top;
float right;
float bottom;
float dst_left;
float dst_top;
float dst_right;
float dst_bottom;
if(width <= height) {
roundPx = (float)(width / 2);
left = 0.0F;
top = 0.0F;
right = (float)width;
bottom = (float)width;
height = width;
dst_left = 0.0F;
dst_top = 0.0F;
dst_right = (float)width;
dst_bottom = (float)width;
} else {
roundPx = (float)(height / 2);
float output = (float)((width - height) / 2);
left = output;
right = (float)width - output;
top = 0.0F;
bottom = (float)height;
width = height;
dst_left = 0.0F;
dst_top = 0.0F;
dst_right = (float)height;
dst_bottom = (float)height;
}
Bitmap output1 = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas(output1);
int color = -12434878;
Paint paint = new Paint();
Rect src = new Rect((int)left, (int)top, (int)right, (int)bottom);
Rect dst = new Rect((int)dst_left, (int)dst_top, (int)dst_right, (int)dst_bottom);
new RectF(dst);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(-12434878);
canvas.drawCircle(roundPx, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, src, dst, paint);
return output1;
}
}
如果觉得有帮助那是最好的,有大神为我指点一下更是极好的,嘿嘿,祝你生活愉快!