安卓上傳圓角頭像到服務(wù)器功能
第一次寫技術(shù)文章,有啥不對的地方往多多指教。
今天為大家?guī)硪黄蟼鲌A角頭像的功能吧。
功能邏輯流程
第一步 選擇照片/拍照(選擇照片和拍照分別需要文件讀取和相機(jī)權(quán)限)
第二步 剪切圓角
第三部 上傳圖片
這里我使用的是OkHttp(一款強(qiáng)大的網(wǎng)絡(luò)請求三方)來進(jìn)行網(wǎng)絡(luò)請求
GitHub地址
代碼如下:
類屬性
// 頁面返回參數(shù)
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;
檢查權(quán)限
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("設(shè)置頭像");
String[] items = { "選擇本地照片", "拍照" };
builder.setNegativeButton("取消", null);
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case CHOOSE_PICTURE: // 選擇本地照片
// 判斷當(dāng)前系統(tǒng)版本
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為一個(gè)臨時(shí)文件,每次拍照后這個(gè)圖片都會被替換
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/*");
// 設(shè)置裁剪
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: 剪切完畢");
}
保存裁剪之后的圖片數(shù)據(jù)
protected void setImageToView(Intent data) {
Bundle extras = data.getExtras();
if (extras != null) {
Bitmap photo = extras.getParcelable("data");
photo = ImgUtils.toRoundBitmap(photo, tempUri); // 這個(gè)時(shí)候的圖片已經(jīng)被處理成圓形的了
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); // 開始對圖片進(jìn)行裁剪處理
break;
case CHOOSE_PICTURE:
startPhotoZoom(data.getData()); // 開始對圖片進(jìn)行裁剪處理
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);
}
好了,到了最后一步,也就是根據(jù)后臺給你的接口上傳圖片到你們服務(wù)器了
public void changeUserInfo() {
// 檢查網(wǎng)絡(luò)狀態(tài)
if (NetUtil.isNetworkAvalible(this)) {
String address = "功能模塊地址";
Map<String, Object> 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, "網(wǎng)絡(luò)請求失敗!", Toast.LENGTH_SHORT).show();
}
});
}
});
} catch (IOException e) {
e.printStackTrace();
}
} else {
NetUtil.checkNetwork(this);
}
}
網(wǎng)絡(luò)請求的方法(比較懶,就把多圖和單圖封裝了一個(gè)方法),可根據(jù)自己后臺的需求改動
/**
* 通用文件網(wǎng)絡(luò)請求
* @param arguments 請求參數(shù)
* @param filesPath 文件列表
*/
public static void sendFileUpdataRequest(Map<String, Object> arguments,
List<String> 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) {
// 這里的多圖上傳規(guī)則需要問你的后臺哈
builder.addFormDataPart(filesKey + "[" + i + "]", f.getName(), RequestBody.create(MEDIA_TYPE_ALL, f));
}
}
}
}
MultipartBody requestBody = builder.build();
//構(gòu)建請求
Request request = new Request.Builder()
.url(serviceUrlStr + address)//serviceUrlStr為你的項(xiàng)目接口地址,address為模塊地址
.post(requestBody)//添加請求體
.build();
Log.d("HttpUtil", "requestBody: " + requestBody);
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 網(wǎng)絡(luò)請求失敗
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();
}
}
});
你以為到這里就結(jié)束了?
這里把需要用的到工具類也貼出來吧,嘿嘿。
網(wǎng)絡(luò)狀態(tài)檢測類:
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;
/**
* 網(wǎng)絡(luò)狀態(tài)檢測工具類
* Created by whm on 2017/6/30.
*/
public class NetUtil {
/**
* 判斷網(wǎng)絡(luò)情況
*
* @param context 上下文
* @return false 表示沒有網(wǎng)絡(luò) true 表示有網(wǎng)絡(luò)
*/
public static boolean isNetworkAvalible(Context context) {
// 獲得網(wǎng)絡(luò)狀態(tài)管理器
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager == null) {
return false;
} else {
// 建立網(wǎng)絡(luò)數(shù)組
NetworkInfo[] net_info = connectivityManager.getAllNetworkInfo();
if (net_info != null) {
for (int i = 0; i < net_info.length; i++) {
// 判斷獲得的網(wǎng)絡(luò)狀態(tài)是否是處于連接狀態(tài)
if (net_info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
}
return false;
}
// 如果沒有網(wǎng)絡(luò),則彈出網(wǎng)絡(luò)設(shè)置對話框
public static void checkNetwork(final Activity activity) {
if (!NetUtil.isNetworkAvalible(activity)) {
TextView msg = new TextView(activity);
msg.setText("當(dāng)前沒有可以使用的網(wǎng)絡(luò),請?jiān)O(shè)置網(wǎng)絡(luò)!");
new AlertDialog.Builder(activity)
.setIcon(R.mipmap.app_icon)
.setTitle("網(wǎng)絡(luò)狀態(tài)提示")
.setView(msg)
.setPositiveButton("確定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// 跳轉(zhuǎn)到設(shè)置界面
activity.startActivityForResult(new Intent(Settings.ACTION_WIRELESS_SETTINGS), 0);
}
}).create().show();
}
return;
}
/**
* 判斷網(wǎng)絡(luò)是否連接
**/
public static boolean netState(Context context) {
ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
// 獲取代表聯(lián)網(wǎng)狀態(tài)的NetWorkInfo對象
NetworkInfo networkInfo = connManager.getActiveNetworkInfo();
// 獲取當(dāng)前的網(wǎng)絡(luò)連接是否可用
boolean available = false;
try {
available = networkInfo.isAvailable();
} catch (Exception e) {
e.printStackTrace();
return false;
}
if (available) {
Log.i("通知", "當(dāng)前的網(wǎng)絡(luò)連接可用");
return true;
} else {
Log.i("通知", "當(dāng)前的網(wǎng)絡(luò)連接可用");
return false;
}
}
/**
* 在連接到網(wǎng)絡(luò)基礎(chǔ)之上,判斷設(shè)備是否是SIM網(wǎng)絡(luò)連接
*
* @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;
}
}
如果覺得有幫助那是最好的,有大神為我指點(diǎn)一下更是極好的,嘿嘿,祝你生活愉快!