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

2023-11-04 22:18

本文主要是介绍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请求)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/345517

相关文章

ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法

《ElasticSearch+Kibana通过Docker部署到Linux服务器中操作方法》本文介绍了Elasticsearch的基本概念,包括文档和字段、索引和映射,还详细描述了如何通过Docker... 目录1、ElasticSearch概念2、ElasticSearch、Kibana和IK分词器部署

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Linux流媒体服务器部署流程

《Linux流媒体服务器部署流程》文章详细介绍了流媒体服务器的部署步骤,包括更新系统、安装依赖组件、编译安装Nginx和RTMP模块、配置Nginx和FFmpeg,以及测试流媒体服务器的搭建... 目录流媒体服务器部署部署安装1.更新系统2.安装依赖组件3.解压4.编译安装(添加RTMP和openssl模块

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

JavaWeb-WebSocket浏览器服务器双向通信方式

《JavaWeb-WebSocket浏览器服务器双向通信方式》文章介绍了WebSocket协议的工作原理和应用场景,包括与HTTP的对比,接着,详细介绍了如何在Java中使用WebSocket,包括配... 目录一、概述二、入门2.1 POM依赖2.2 编写配置类2.3 编写WebSocket服务2.4 浏

查询SQL Server数据库服务器IP地址的多种有效方法

《查询SQLServer数据库服务器IP地址的多种有效方法》作为数据库管理员或开发人员,了解如何查询SQLServer数据库服务器的IP地址是一项重要技能,本文将介绍几种简单而有效的方法,帮助你轻松... 目录使用T-SQL查询方法1:使用系统函数方法2:使用系统视图使用SQL Server Configu

nginx-rtmp-module构建流媒体直播服务器实战指南

《nginx-rtmp-module构建流媒体直播服务器实战指南》本文主要介绍了nginx-rtmp-module构建流媒体直播服务器实战指南,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录1. RTMP协议介绍与应用RTMP协议的原理RTMP协议的应用RTMP与现代流媒体技术的关系2

mysqld_multi在Linux服务器上运行多个MySQL实例

《mysqld_multi在Linux服务器上运行多个MySQL实例》在Linux系统上使用mysqld_multi来启动和管理多个MySQL实例是一种常见的做法,这种方式允许你在同一台机器上运行多个... 目录1. 安装mysql2. 配置文件示例配置文件3. 创建数据目录4. 启动和管理实例启动所有实例