本文主要是介绍Android 头像上传至服务器 (OkHttpClient请求),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
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.CircleImageViewandroid:id="@+id/c1"android:layout_width="80dp"android:layout_height="100dp"android:layout_gravity="center"android:src="@mipmap/logo"></de.hdodenhof.circleimageview.CircleImageView><TextViewandroid: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"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><ImageViewandroid:layout_width="35dp"android:layout_height="50dp"android:src="@mipmap/a1"android:layout_marginLeft="50dp"/><TextViewandroid: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><Viewandroid:layout_width="match_parent"android:layout_height="1dp"android:background="@android:color/darker_gray"/>
<LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><ImageViewandroid:layout_width="35dp"android:layout_height="50dp"android:src="@mipmap/a2"android:layout_marginLeft="50dp"/><TextViewandroid: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><Viewandroid:layout_width="match_parent"android:layout_height="1dp"android:background="@android:color/darker_gray"/><TextViewandroid: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" ><translateandroid: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" ><translateandroid:duration="500"android:fromXDelta="0"android:fromYDelta="0"android:toXDelta="0"android:toYDelta="1000" />
</set>
(3)功能实现
绑定ID,并实现监听器
底部菜单核心代码
private void showBottomDialog(){//1、使用Dialog、设置stylefinal 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() {@Overridepublic void onClick(View view) {}});dialog.findViewById(R.id.tv_take_pic).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {}});dialog.findViewById(R.id.tv_cancel).setOnClickListener(new View.OnClickListener() {@Overridepublic 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){//新建一个表示裁剪的IntentIntent intent = new Intent("com.android.camera.action.CROP");//表明我要裁剪的目标是uri这个地址,文件类型是图片intent.setDataAndType(uri,"image/*");//指定长宽的比例为1:1intent.putExtra("aspectX", 1);intent.putExtra("aspectY", 1);//指定宽高为1000intent.putExtra("outputX", 1000);intent.putExtra("outputY", 1000);intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);startActivityForResult(intent,2);}
保存图片文件路径
private void setHeadPicture(){try {//根据imageUri用getContentResolver来获取流对象 再转化成bitmapBitmap 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){//新建一个表示裁剪的IntentIntent intent = new Intent("com.android.camera.action.CROP");//表明我要裁剪的目标是uri这个地址,文件类型是图片intent.setDataAndType(uri,"image/*");//指定长宽的比例为1:1intent.putExtra("aspectX", 1);intent.putExtra("aspectY", 1);//指定宽高为1000intent.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.定义一个OkhttpClientprivate static OkHttpClient client = new OkHttpClient();public static void doPost(final String url, final File file,JSONObject jsonObject, final com.example.note1.HttpResponseCallBack httpResponseCallBack){//建立bodyRequestBody 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() {@Overridepublic void onFailure(Call call, IOException e) {httpResponseCallBack.error(e);}@Overridepublic 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() {@Overridepublic void response(String response) {//做操作}@Overridepublic 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(),此方法返回的就是Responsecall.enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {httpResponseCallBack.error(e);//错误发生时的处理}@Overridepublic void onResponse(Call call, Response response) throws IOException {String reslt=response.body().string();System.out.println(reslt);}});}
}
监听功能
@Overrideprotected 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() {@Overridepublic void response(String response) {runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(MainActivity4.this,"上传成功",Toast.LENGTH_SHORT).show();}});}@Overridepublic void error(Exception e) {}});}break;}}
实现功能
源代码
https://download.csdn.net/download/Scxioi0/18384366
这篇关于Android 头像上传至服务器 (OkHttpClient请求)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!