Android 头像上传至服务器 (OkHttpClient请求)
发布日期:2021-05-06 03:14:51 浏览次数:30 分类:原创文章

本文共 14182 字,大约阅读时间需要 47 分钟。

Android 头像上传至服务器 (OkHttpClient请求)

1.导入本章内容要使用的第三方库

	implementation 'com.squareup.okhttp3:okhttp:3.12.1'    debugImplementation 'com.squareup.okhttp3:logging-interceptor:3.12.1'    implementation 'com.google.code.gson:gson:2.8.5'    implementation 'com.github.bumptech.glide:glide:4.9.0'    annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'    implementation 'de.hdodenhof:circleimageview:2.1.0'

2.添加权限

    <uses-permission android:name="android.permission.INTERNET" /> <!-- 读写获取网络文件的权限 -->    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

3.界面布局

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context=".MainActivity">    <de.hdodenhof.circleimageview.CircleImageView        android:id="@+id/c1"        android:layout_width="80dp"        android:layout_height="100dp"        android:layout_gravity="center"        android:src="@mipmap/logo">    </de.hdodenhof.circleimageview.CircleImageView>    <TextView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:gravity="center"        android:textSize="20sp"        android:layout_marginTop="10dp"        android:text="点击头像更换"/></LinearLayout>

界面展示
在这里插入图片描述
4.点击头像监听内容
采用弹出底部菜单从而进行选择图片上传样式

界面展示
在这里插入图片描述
界面布局代码

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#fff">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal">        <ImageView            android:layout_width="35dp"            android:layout_height="50dp"            android:src="@mipmap/a1"            android:layout_marginLeft="50dp"/>        <TextView            android:id="@+id/tv_take_photo"            android:layout_width="match_parent"            android:layout_height="50dp"            android:layout_marginRight="50dp"            android:text="拍摄"            android:gravity="center"            android:textSize="16sp"            android:textColor="@android:color/background_dark"/>    </LinearLayout>    <View        android:layout_width="match_parent"        android:layout_height="1dp"        android:background="@android:color/darker_gray"/><LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal">        <ImageView            android:layout_width="35dp"            android:layout_height="50dp"            android:src="@mipmap/a2"            android:layout_marginLeft="50dp"/>    <TextView        android:id="@+id/tv_take_pic"        android:layout_width="match_parent"        android:layout_height="50dp"        android:text="从手机相册选择"        android:layout_marginRight="50dp"        android:gravity="center"        android:textSize="16sp"        android:textColor="@android:color/background_dark"/></LinearLayout>    <View        android:layout_width="match_parent"        android:layout_height="1dp"        android:background="@android:color/darker_gray"/>    <TextView        android:id="@+id/tv_cancel"        android:layout_width="match_parent"        android:layout_height="50dp"        android:text="取消"        android:gravity="center"        android:textSize="16sp"        android:textColor="@android:color/background_dark"/></LinearLayout>

(1)style.xml文件添加样式

    <style name="DialogTheme" parent="@android:style/Theme.Dialog">        <!-- 边框 -->        <item name="android:windowFrame">@null</item>        <!-- 是否浮现在activity之上 -->        <item name="android:windowIsFloating">true</item>        <!-- 半透明 -->        <item name="android:windowIsTranslucent">true</item>        <!-- 无标题 -->        <item name="android:windowNoTitle">true</item>        <item name="android:background">@android:color/transparent</item>        <!-- 背景透明 -->        <item name="android:windowBackground">@android:color/transparent</item>        <!-- 模糊 -->        <item name="android:backgroundDimEnabled">true</item>        <!-- 遮罩层 -->        <item name="android:backgroundDimAmount">0.5</item>    </style>    <style name="main_menu_animStyle">        windowEnterAnimation 进入的动画        代码里面        <item name="android:windowEnterAnimation">@anim/dialog_in_anim</item>        <item name="android:windowExitAnimation">@anim/dialog_out_anim</item>    </style>

(2)添加动画
在res文件下创建命名为anim的文件
在这里插入图片描述
第一个动画文件命名为dialog_in_anim.xml

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" >    <translate        android:duration="500"        android:fromXDelta="0"        android:fromYDelta="1000"        android:toXDelta="0"        android:toYDelta="0" /></set>

第二个动画文件命名为dialog_out_anim.xml

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" >    <translate        android:duration="500"        android:fromXDelta="0"        android:fromYDelta="0"        android:toXDelta="0"        android:toYDelta="1000" /></set>

(3)功能实现
绑定ID,并实现监听器
在这里插入图片描述
底部菜单核心代码

private void showBottomDialog(){           //1、使用Dialog、设置style        final Dialog dialog = new Dialog(this,R.style.DialogTheme);        //2、设置布局        View view = View.inflate(this,R.layout.dialog_custom_layout,null);        dialog.setContentView(view);        Window window = dialog.getWindow();        //设置弹出位置        window.setGravity(Gravity.BOTTOM);        //设置弹出动画        window.setWindowAnimations(R.style.main_menu_animStyle);        //设置对话框大小        window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);        dialog.show();        dialog.findViewById(R.id.tv_take_photo).setOnClickListener(new View.OnClickListener() {               @Override            public void onClick(View view) {               }        });        dialog.findViewById(R.id.tv_take_pic).setOnClickListener(new View.OnClickListener() {               @Override            public void onClick(View view) {               }        });        dialog.findViewById(R.id.tv_cancel).setOnClickListener(new View.OnClickListener() {               @Override            public void onClick(View view) {                   dialog.dismiss();            }        });    }

完成,下面开始实现图片上传到服务器
5.图片上传到服务器
定义
在这里插入图片描述
如果安卓版本为7.0以上,需要添加下面的代码避免打开相机报错

@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)    private void initPhotoError() {           // android 7.0系统解决拍照的问题        StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();        StrictMode.setVmPolicy(builder.build());        builder.detectFileUriExposure();    }

初始化文件
在这里插入图片描述

file = new File(Environment.getExternalStorageDirectory(), "headPicture.jpg");//新建一个文件(路径,文件名称)        if (file.exists())        {               file.delete();        }        try {               file.createNewFile();        } catch (IOException e) {               e.printStackTrace();        }        imageUri = Uri.fromFile(file);

图片裁剪代码

    private void cropPicture(Uri uri)    {           //新建一个表示裁剪的Intent        Intent intent = new Intent("com.android.camera.action.CROP");        //表明我要裁剪的目标是uri这个地址,文件类型是图片        intent.setDataAndType(uri,"image/*");        //指定长宽的比例为1:1        intent.putExtra("aspectX", 1);        intent.putExtra("aspectY", 1);        //指定宽高为1000        intent.putExtra("outputX", 1000);        intent.putExtra("outputY", 1000);        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);        startActivityForResult(intent,2);    }

保存图片文件路径

 private void setHeadPicture()    {           try {               //根据imageUri用getContentResolver来获取流对象 再转化成bitmap            Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));            if (bitmap==null)            {                   //判断bitmap是否为空                Toast.makeText(this,"图像没有存储到sd卡根目录",Toast.LENGTH_SHORT).show();            }            c1.setImageBitmap(bitmap);        } catch (FileNotFoundException e) {           }    }

图片裁剪

 private void cropPicture(Uri uri)    {           //新建一个表示裁剪的Intent        Intent intent = new Intent("com.android.camera.action.CROP");        //表明我要裁剪的目标是uri这个地址,文件类型是图片        intent.setDataAndType(uri,"image/*");        //指定长宽的比例为1:1        intent.putExtra("aspectX", 1);        intent.putExtra("aspectY", 1);        //指定宽高为1000        intent.putExtra("outputX", 200);        intent.putExtra("outputY", 200);        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);        startActivityForResult(intent,2);    }

定义OkhttpUtils类

package com.example.note1;import org.json.JSONObject;import java.io.File;import java.io.IOException;import okhttp3.Call;import okhttp3.Callback;import okhttp3.MediaType;import okhttp3.MultipartBody;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.RequestBody;import okhttp3.Response;public class OkhttpUtils {       //定义一个JSON的MediaType(互联网媒体类型)    private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");    //1.定义一个OkhttpClient    private static OkHttpClient client = new OkHttpClient();    public static void doPost(final String url, final File file,JSONObject jsonObject, final com.example.note1.HttpResponseCallBack httpResponseCallBack)    {           //建立body        RequestBody body = RequestBody.create(JSON,jsonObject.toString());        //建立请求        Request request = new Request.Builder().post(body).url(url).build();        Call call = client.newCall(request);        call.enqueue(new Callback() {               @Override            public void onFailure(Call call, IOException e) {                   httpResponseCallBack.error(e);            }            @Override            public void onResponse(Call call, Response response) throws IOException {                   String s = response.body().string();                httpResponseCallBack.response(s);                if (file!=null)//如果有文件需要传输的话                {                       doPostPicture(url, file,new com.example.note1.HttpResponseCallBack() {                           @Override                        public void response(String response) {                               //做操作                        }                        @Override                        public void error(Exception e) {                               //做操作                        }                    });                }            }        });    }    //参数为要上传的网址,本地照片在本地的地址,我们自己定义的接口    private static void doPostPicture(String url, File file,final com.example.note1.HttpResponseCallBack httpResponseCallBack) {           //2.创建一个请求体        RequestBody body;        //3.创建一个请求体建造器        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);        System.out.println(file);        builder.addFormDataPart("file", "headPicture.jpg", RequestBody.create(MediaType.parse("image/jpg"), file))                .addFormDataPart("port","3")                .build();        body = builder.build();        //3.创建一个请求,利用构建器方式添加url和请求体。        Request request = new Request.Builder()                .post(body)                .addHeader("Authorization", "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wveHVlemkuY2hhbmppYW9yb25nLmNvbVwvYXBpXC9jb21tb25cL2xvZ2luXC9wd2RMb2dpbiIsImlhdCI6MTYyMDEzODMwNCwiZXhwIjoxNjIzMzMwMzA0LCJuYmYiOjE2MjAxMzgzMDQsImp0aSI6IkJFSmI4UFNsdE1wdWRyOEwiLCJzdWIiOjcsInBydiI6IjljMmViNzg4ZjYyM2NlMTE3OWU2NDYzZDE0OTAxZWY1YzY1MTA0YTUiLCJyb2xlIjoiYXBpIn0.-e5EbtMDjokahHtY6lLpEnEegXzlTWyhhQ5my1WyhD8")                .addHeader("Accept","")                .addHeader("port","3")                .url(url)                .build();        //4.定义一个call,利用okhttpclient的newcall方法来创建对象。因为Call是一个接口不能利用构造器实例化。        Call call = client.newCall(request);        //5.这是异步调度方法,上传和接受的工作都在子线程里面运作,如果要使用同步的方法就用call.excute(),此方法返回的就是Response        call.enqueue(new Callback() {               @Override            public void onFailure(Call call, IOException e) {                   httpResponseCallBack.error(e);//错误发生时的处理            }            @Override            public void onResponse(Call call, Response response) throws IOException {                   String reslt=response.body().string();                System.out.println(reslt);            }        });    }}

监听功能

@Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {           super.onActivityResult(requestCode, resultCode, data);        switch (requestCode) {               case 0:                //拍照                if (resultCode == RESULT_OK) {                       cropPicture(imageUri);                }                break;            case 1:                //从相册获取                if (resultCode == RESULT_OK) {                       cropPicture(data.getData());                }                break;            case 2:                //裁剪之后                if (resultCode == RESULT_OK) {                       setHeadPicture();                    //点击以后上传用户id和用户图片到服务器                    JSONObject jsonObject = new JSONObject();                    OkhttpUtils.doPost(url, file, token,jsonObject, new HttpResponseCallBack() {                           @Override                        public void response(String response) {                               runOnUiThread(new Runnable() {                                   @Override                                public void run() {                                       Toast.makeText(MainActivity4.this,"上传成功",Toast.LENGTH_SHORT).show();                                }                            });                        }                        @Override                        public void error(Exception e) {                           }                    });                }                break;        }    }

实现功能
在这里插入图片描述
源代码
https://download.csdn.net/download/Scxioi0/18384366

上一篇:Android 界面左右滑动切换
下一篇:Android 使用腾讯sdk播放视频

发表评论

最新留言

表示我来过!
[***.240.166.169]2025年03月13日 22时57分52秒