安卓开发01——上传圆角头像到服务器

安卓上传圆角头像到服务器功能

第一次写技术文章,有啥不对的地方往多多指教。
今天为大家带来一篇上传圆角头像的功能吧。

功能逻辑流程

第一步 选择照片/拍照(选择照片和拍照分别需要文件读取和相机权限)
第二步 剪切圆角
第三部 上传图片
这里我使用的是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;
    }
}

如果觉得有帮助那是最好的,有大神为我指点一下更是极好的,嘿嘿,祝你生活愉快!

你可能感兴趣的:(安卓开发01——上传圆角头像到服务器)