Android:设置头像

该文章讲述了Android原生态开发过程中设置用户原型头像的实现过程。主要使用到技术有:Android原生态开发、CircleImageView圆形图片视图、Crop裁剪工具等。

1.业务介绍

业务具体流程可以分为一下几个过程:
1.用户点击进行圆形头像设置,可以选择拍照设置和从本地选择图片进行设置两种设计方案。(一下以拍照设置为例进行说明)
2.调用手机相机进行拍照
3.获取拍照照片后调用Crop工具进行照片裁剪。
4.将照片资源添加到CircleImageView视图中。
下面将对整个过程进行详细讲解。

2.详细过程说明

选择照片来源

头像来源可以时本地也可以时拍照,系统可以为用户提供两种选择途径。该功能的实现方式可以采用Dialog实现。具体可见:一个好看的Dialog样式实现,仿IOS。

获取照片资源

上述已经说明,获取照片的途径有两种,如果进行拍照设置,那么系统应该调用手机相机进行拍照,如果选择本地照片,那么系统应该打开手机本地图库。该过程的具体代码如下:

    /*** 从本地相册选取图片作为头像* 将为用户打开本地图库*/public void choseHeadImageFromGallery() {Intent intentFromGallery = new Intent();// 设置文件类型intentFromGallery.setType("image/*");intentFromGallery.setAction(Intent.ACTION_GET_CONTENT);activity.startActivityForResult(intentFromGallery, CODE_GALLERY_REQUEST);}/*** 启动手机相机拍摄照片作为头像* 将调用本地相机* 注意:该过程中首先判断了系统是否有存储卡,如果有的情况下将为Intent设置一个Uri对象,该对象可以理解为资源标识符。* Uri资源标识符将标识一个资源的存在,可以通过它获取一个资源信息。* 当为Intent设置 MediaStore.EXTRA_OUTPUT 输出位置时onActivityResult方法的intent.getData()方法将获取的时一个null* 否则获取是Bitmap对象*/public void choseHeadImageFromCameraCapture() {Intent intentFromCapture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 判断存储卡是否可用,存储照片文件if (hasSdcard()) {uri = getUriForFile(activity,"head");intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT,uri);}activity.startActivityForResult(intentFromCapture, CODE_CAMERA_REQUEST);}

上述过程中使用了hasSdcard()方法和getUriForFile(activity,“head”)方法,这两个方法的实现过程如下:

    /*** 检查设备是否存在SDCard的工具方法*/public boolean hasSdcard() {String state = Environment.getExternalStorageState();if (state.equals(Environment.MEDIA_MOUNTED)) {// 有存储的SDCardreturn true;} else {return false;}}/** 获取uri资源 **/public static Uri getUriForFile(Context context,String path){// 生成文件makeRootDirectory(basePath + DataTool.sdf_ymd.format(new Date()));// 生成文件File file = new File(basePath +DataTool.sdf_ymd.format(new Date()) , path + ".jpg");PicTool.file = file.getAbsolutePath();return getUriForFile(context,file);};/** 生成文件夹 **/public static boolean makeRootDirectory(String filePath) {File file = null;try {file = new File(filePath);if (!file.exists()) {file.mkdirs();}else{file.delete();file.mkdirs();}return true;} catch (Exception e) {Log.i("error:", e+"");return false;}}/*** 生成URL* @param context* @param file* @return*/public static Uri getUriForFile(Context context, File file) {if (context == null || file == null) {throw new NullPointerException();}Uri uri;if (Build.VERSION.SDK_INT >= 24) {uri = FileProvider.getUriForFile(context.getApplicationContext(), "包名.fileprovider", file);} else {uri = Uri.fromFile(file);}return uri;}

由以上代码可以看出,在生成Uri对象的过程中使用到了FileProvider,这是由于在Android7.0以后使用FileProvider在应用中共享文件资源。在使用FileProvider过程中需要进行配置。配置过程如下:
1.首先在res文件夹下床架xml文件夹,并创建file_path.xml文件。在该文件中做出一下配置:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android"><external-pathname="external"path="." /><external-files-pathname="external_files"path="." /><cache-pathname="cache"path="." /><external-cache-pathname="external_cache"path="." /><files-pathname="files"path="." />
</paths>

2.在AndroidManifest.xml文件中进行配置刚才的xml信息。

        <providerandroid:name="androidx.core.content.FileProvider"android:authorities="包名.fileprovider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_path" /></provider>

以上两个操作可以完成FileProvider使用设置,该过程实际上标识了该应用可获取文件资源的范围。

拍照后的操作

拍照后的结果是由onActivityResult来接受处理的,在前面代码中

 Intent intentFromCapture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 判断存储卡是否可用,存储照片文件if (hasSdcard()) {uri = getUriForFile(activity,"head");intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT,uri);}activity.startActivityForResult(intentFromCapture, CODE_CAMERA_REQUEST);

我们可以看出给Intent对象传入的uri并不是个局部对象,这是由于当intent对象携带uri时,onActivityResult方法的intent对象并不能再次接受到Uri信息。因此需要将Uri对象作为全局变量存储。当调用onActivityResult方法处理照片资源时其实是处理全局的Uri对象。onAcitivityResult方法的具体操作输入:

    public void deal(int requestCode, int resultCode,Intent intent){switch (requestCode) {case CODE_GALLERY_REQUEST: // 从本地获取if (PicTool.hasSdcard()) {Crop.of(intent.getData(), resultUri).asSquare().start(activity);} else {Toast.makeText(activity, "没有SDCard!", Toast.LENGTH_LONG).show();}break;case CODE_CAMERA_REQUEST: // 拍照成功后调用if (PicTool.hasSdcard()) {Uri resultUri =  PicTool.getUriForFile(activity,"headPic");Crop.of(uri, resultUri).asSquare().start(activity);} else {Toast.makeText(activity, "没有SDCard!", Toast.LENGTH_LONG).show();}break;case Crop.REQUEST_CROP://使用Crop裁剪之后调用{if(resultCode == Crop.RESULT_ERROR) {Toast.makeText(activity,"裁剪失败",Toast.LENGTH_SHORT).show();}else{//裁剪成功后调用  如果setImageURL设置的url是同一个值的话  则无法改变前端显示Uri result = Crop.getOutput(intent);view.setImageURI(null);view.setImageURI(result);}break;}}}

调用裁剪

在该过程中,调用裁剪使用了Crop工具。使用该工具需要做出一下引入:

    //圆形头像implementation 'de.hdodenhof:circleimageview:3.1.0'//裁剪照片compile 'com.soundcloud.android:android-crop:1.0.1@aar'compile 'com.github.bumptech.glide:glide:3.7.0'

Crop的实际使用过程相对比较简单,可以分为两个过程,如下:
1.在AndroidManifest.xml文件中进行配置

<activity android:name="com.soundcloud.android.crop.CropImageActivity" />

实际上就是声明了一个acitivity,这是因为在进行裁剪的过程中实际上实在Crop实现的Acitivity上进行的,该Activity已经在crop包中实现了,因此需要在AndroidManifest.xml文件中文件中进行说明。
2.代码中调用

/**
* 在该方法中需要三个参数:uri、resultUri和activity
* uri是需要裁剪的照片资源标识符
* resultUri是存储裁剪后的照片的资源标识符
* activity是调用裁剪的主体
**/
Crop.of(uri, resultUri).asSquare().start(activity);

当裁剪操作接受后,其实还是由onResultActivity进行接受处理,处理过程:

            case Crop.REQUEST_CROP://使用Crop裁剪之后调用{if(resultCode == Crop.RESULT_ERROR) {Toast.makeText(activity,"裁剪失败",Toast.LENGTH_SHORT).show();}else{//裁剪成功后调用  如果setImageURL设置的url是同一个值的话  则无法改变前端显示Uri result = Crop.getOutput(intent);view.setImageURI(null);view.setImageURI(result);}break;}

注意:在该过程中,对view进行设置图片资源,首先执行了view.setImageURI(null);方法。这是由于setImageURI方法做了优化处理,它首先判断Uri指向的是否是同一个资源(路径以及文件名是否相同),如果是同一个资源的话,该方便并不会对view再进行Uri设置。

以上整个过程就完成了,下面进行简单梳理一下:
1.调用dialog显示
2.调用相机或者本地图库(如果调用相机的过程中该Intent设置了Uri,则onResultActivity方法的Intent对象的getData方法将接受不到信息)
3.图片资源信息获取成功后通过Crop进行裁剪
4.裁剪后的信息依旧交由onResultActivity方法进行处理

3.具体实现过程

1.jar包的引入:

    //圆形头像implementation 'de.hdodenhof:circleimageview:3.1.0'//裁剪照片compile 'com.soundcloud.android:android-crop:1.0.1@aar'compile 'com.github.bumptech.glide:glide:3.7.0'

2.在xml视图文件中配置圆形图片信息

    <de.hdodenhof.circleimageview.CircleImageViewandroid:id="@+id/register_user_head_pic"android:layout_width="150dp"android:layout_height="120dp"android:layout_marginTop="50dp"app:civ_border_color="@color/gray"app:civ_border_width="1dp"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@id/toolbar" />

3.配置file_path方法:
在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android"><external-pathname="external"path="." /><external-files-pathname="external_files"path="." /><cache-pathname="cache"path="." /><external-cache-pathname="external_cache"path="." /><files-pathname="files"path="." />
</paths>

AndroidManifest.xml文件

        <providerandroid:name="androidx.core.content.FileProvider"android:authorities="com.baiyang.instant_messaging_based_on_android.fileprovider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_path" /></provider>

provider是和activity标签同级的。此外还需要声明Crop的activity资源:

        <activity android:name="com.soundcloud.android.crop.CropImageActivity" />

4.工具类,下面给将直接给出整个过程中的工具类:

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;import androidx.core.content.FileProvider;import com.soundcloud.android.crop.Crop;import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;import de.hdodenhof.circleimageview.CircleImageView;/***  圆形头像工具类*/
public class CircleImageTool {// 圆形视图private CircleImageView view;// 调用主体private Activity activity;private String fileprovider;/*** 构造函数* @param activity -- 进行头像蛇者的activity* @param view -- 圆形视图对象* @param fileprovider -- AndroidManifest.xml文件中provider资源的所有者:android:authorities*/public CircleImageTool(Activity activity,CircleImageView view,String fileprovider){this.activity = activity;this.view = view;this.fileprovider = fileprovider;}/* 请求识别码 */private static final int CODE_GALLERY_REQUEST = 0xa0; // 本地照片private static final int CODE_CAMERA_REQUEST = 0xa1; // 拍照// 图片资源标识符private Uri uri;/*** 从本地相册选取图片作为头像* 将为用户打开本地图库** 当用户点击从本地获取时直接调用该方法*/public void choseHeadImageFromGallery() {Intent intentFromGallery = new Intent();// 设置文件类型intentFromGallery.setType("image/*");intentFromGallery.setAction(Intent.ACTION_GET_CONTENT);activity.startActivityForResult(intentFromGallery, CODE_GALLERY_REQUEST);}/*** 启动手机相机拍摄照片作为头像* 将调用本地相机* 注意:该过程中首先判断了系统是否有存储卡,如果有的情况下将为Intent设置一个Uri对象,该对象可以理解为资源标识符。* Uri资源标识符将标识一个资源的存在,可以通过它获取一个资源信息。* 当为Intent设置 MediaStore.EXTRA_OUTPUT 输出位置时onActivityResult方法的intent.getData()方法将获取的时一个null* 否则获取是Bitmap对象** 当用户点击拍照时直接调用该方法*/public void choseHeadImageFromCameraCapture() {Intent intentFromCapture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);// 判断存储卡是否可用,存储照片文件if (hasSdcard()) {uri = getUriForFile(activity,"head");intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT,uri);}activity.startActivityForResult(intentFromCapture, CODE_CAMERA_REQUEST);}/*** 接受到返回结果时调用* @param requestCode* @param resultCode* @param intent*/public void deal(int requestCode, int resultCode,Intent intent){switch (requestCode) {case CODE_GALLERY_REQUEST: // 从本地获取if (PicTool.hasSdcard()) {Uri resultUri = getUriForFile(activity,"headPic");// 从本地获取  intent.getData()方法返回选中图片资源Crop.of(intent.getData(), resultUri).asSquare().start(activity);} else {Toast.makeText(activity, "没有SDCard!", Toast.LENGTH_LONG).show();}break;case CODE_CAMERA_REQUEST: // 拍照成功后调用if (hasSdcard()) {Uri resultUri =  getUriForFile(activity,"headPic");Crop.of(uri, resultUri).asSquare().start(activity);} else {Toast.makeText(activity, "没有SDCard!", Toast.LENGTH_LONG).show();}break;case Crop.REQUEST_CROP://使用Crop裁剪之后调用{if(resultCode == Crop.RESULT_ERROR) {Toast.makeText(activity,"裁剪失败",Toast.LENGTH_SHORT).show();}else{//裁剪成功后调用  如果setImageURL设置的url是同一个值的话  则无法改变前端显示Uri result = Crop.getOutput(intent);view.setImageURI(null);view.setImageURI(result);}break;}}}/*** 检查设备是否存在SDCard的工具方法*/private boolean hasSdcard() {String state = Environment.getExternalStorageState();if (state.equals(Environment.MEDIA_MOUNTED)) {// 有存储的SDCardreturn true;} else {return false;}}private static final SimpleDateFormat sdf_ymd = new SimpleDateFormat("yyyy-MM-dd", Locale.CANADA);private Uri getUriForFile(Context context,String path){// 文件管理下:/Android/Data/包名/file/日期/String basePath = activity.getExternalFilesDir("").getAbsolutePath()+ File.separator  + sdf_ymd.format(new Date());// 生成文件makeRootDirectory(basePath);// 生成文件File file = new File(basePath , path + ".jpg");return getUriForFile(context,file);};// 生成文件夹private boolean makeRootDirectory(String filePath) {File file = null;try {file = new File(filePath);if (file.exists()) {file.delete();}file.mkdirs();return true;} catch (Exception e) {Log.i("error:", e+"");return false;}}/*** 生成URL* @param context* @param file* @return*/private Uri getUriForFile(Context context, File file) {if (context == null || file == null) {throw new NullPointerException();}Uri uri;if (Build.VERSION.SDK_INT >= 24) {uri = FileProvider.getUriForFile(context.getApplicationContext(), fileprovider, file);} else {uri = Uri.fromFile(file);}return uri;}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/56261.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

即时聊天中的更换头像功能

摘自&#xff1a;bmob即时通讯个人资料编辑&#xff0c;源码猛击这里 很多人想知道即时聊天的拍照做图像和相册选择做图像的功能怎么实现&#xff0c;这里。我通过拆分bmob即时聊天的案例&#xff0c;介绍大家怎么实现这种功能。 首先我们点击头像弹出上图的窗口&#xff0c;我…

SpringBoot + Spring Security多种登录方式:账号+微信网页授权登录

大家好&#xff0c;我是宝哥&#xff01; 一、概述 实现账号用户名微信网页授权登录集成在Spring Security的思路&#xff0c;最重要的一点是要实现微信登录通过Spring Security安全框架时&#xff0c;不需要验证账号、密码。 二、准备工作 要实现该功能&#xff0c;首先需要掌…

CnOpenDataA股上市公司交易所监管措施数据

一、数据简介 证券市场监管是指证券管理机关运用法律的、经济的以及必要的行政手段&#xff0c;对证券的募集、发行、交易等行为以及证券投资中介机构的行为进行监督与管理。 我国《证券交易所管理办法》第十二条规定&#xff0c;证券交易所应当按照章程、协议以及业务规则的规…

四套上市公司家族、股权关联数据助力公司金融深度研究

四套上市公司家族关联数据&#xff1a;家族企业在我国上市公司中占有庞大比例&#xff0c;已经成为推动我国经济高质量发展的动力之一。家族企业作为民营经济的重要组成部分&#xff0c;在我国的GDP增长、税收以及就业等方面做出的贡献不容小觑。上市公司家族企业的关联、融资、…

新手练习2:人物模型多边形建模流程图解

一&#xff0c;核心布线篇 1&#xff0c;打开Blender&#xff0c;新建一个“常规”文件&#xff0c;按Tab键对立方体进行调整&#xff0c; 2&#xff0c; 按 ~ 键切换视图&#xff0c;按快捷键1切换顶点&#xff0c;选择左边顶点删除&#xff0c;对其添加镜像修改器&#xff0…

CI 与 CD 持续集成与交付(2)

在CI 与 CD持续集成与交付&#xff08;1&#xff09;http://t.csdn.cn/TF3zC 里面简述了要持续集成要哪些基本工具和和工具安装使用&#xff0c;下面我用实验验证 jenkins 怎么去集成这3大工具的使用 第一步先下载Jenkins的war 包 java -jar jenkins.war 启动 Jenkins web应…

快讯 | 低成本开源聊天机器人Vicuna;首批因 AI 失业的人出现

一分钟速览新闻点 首批因 AI 失业的人出现&#xff0c;某游戏公司裁掉半数原画师西安交大开发出基于多功能智能皮肤的自适应变色系统术锐机器人完成数亿元C3轮融资&#xff0c;手术机器人成资本香饽饽谷歌称其 AI 超算系统比英伟达 A100 更快、更节能ChatGPT已经恢复Plus订阅服…

服装连锁店管理系统设计与实现

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a;

基于SSM 技术的服装店管理系统

随着各个服装公司的发展&#xff0c;以及现在的客流量的增加&#xff0c;很多的服装公司的内容管理系统出现了很多的问题&#xff0c;比如说系统的服务不全面&#xff0c;系统高峰时期出现卡顿等一些体验不是十分好的现象。本次毕业设计从服装行业的本身需求出发,服装公司内部的…

基于SSMEasyUI的西服门店管理系统-java门店管理服装管理系统

基于SSM&EasyUI的西服门店管理系统-java门店管理服装管理系统 1.包含源程序&#xff0c;数据库脚本。代码和数据库脚本都有详细注释。2.课题设计仅供参考学习使用&#xff0c;可以在此基础上进行扩展完善开发环境&#xff1a;Eclipse ,MYSQL,JDK1.7,Tomcat 7涉及技术点&…

服装店小程序商城开发,有效帮助门店增加私域流量,提升门店销量

文/江苏微微小程序开发 线下服装店普遍遭遇获客难的问题&#xff0c;主要原因是店铺曝光不足&#xff0c;受限于地理位置&#xff0c;和线上电商冲击。 开发服装小程序商城&#xff0c;可以很好地扩大店铺曝光半径&#xff0c;利用小程序中的附近的小程序功能&#xff0c;服装…

服装租赁与买卖系统设计

其他项目&#xff0c;点击作者主页 目录 1 系统简介 2 系统相关技术 2.1 Java 2.2 MySql数据库 2.3 MyEclipse技术 2. 4 Tomcat服务器 3 需求分析 3.1 系统可行性分析 3.1.1 技术可行性分析 3.1.2 经济可行性分析 3.1.3 社会可行性 3.2 系统功能需求分析 4 系统…

服装零售软件大合集,你想知道的都在这里!

最近总是听到服装零售店老板的诉苦&#xff1a; 1、一年四季更换&#xff0c;服装零售店面临着换季更替&#xff0c;潮流迭代&#xff0c;于是也承担着巨额的库存成本&#xff0c;加上当前运输成本不断上涨&#xff0c;店铺支出压力越来越大&#xff0c;服装零售店的库存消化能…

推荐一款可以设计衣服的软件?零基础小白不可错过的服装设计工具

推荐一款可以设计衣服的手机软件&#xff1f;服装设计中设计绘画是个很重要的步骤&#xff0c;服装画主要是表达设计师所设计的时装整体效果及感觉&#xff0c;通过设计来表达设计师的设计理念及风格&#xff0c;其中包括对衣服的设计、面料、廓形等等的表达所以对于服装设计的…

衣橱管理APP——《衣橱管家》页面设计

目录 一、界面总体设计二、详细界面说明1.登录注册2.日历3.智能推荐4.我的5.衣橱6.时尚 三、附录 一、界面总体设计 《衣橱管家》有五大核心模块&#xff1a;衣橱管理、智能穿搭推荐、智能购买推荐、时尚社区、日常穿搭记录&#xff1b;界面设计将围绕这五大核心模块与登录注册…

服装店商家不离手的十大服装进销存管理软件,功能大对比

随着管理成本的提高&#xff0c;加上信息技术的发展&#xff0c;各行各业都要求应用专业的技术软件来提高管理效率&#xff0c;中小商户也不例外。 进销存软件是时代的产物&#xff0c;也是中小商户们想要做大做强生意的必然要求。然而市面上的进销存软件高达上百款&#xff0…

中小型服装店如何选择管理软件?

中小型服装店在发展中逐渐建立属于门店的会员管理、员工管理、商品管理体系&#xff0c;使用管理软件来提高门店经营效率&#xff0c;那么选择服装店管理软件要看哪些方面? 小编给大家一些中小型服装店选择软件时考虑的方面&#xff1a; 软件价格。中小型门店服装店规模小&…

基于C#的服装店进销存管理系统设计与实现

目 录 第一章 前言 1 1.1 选题背景 1 1.2 毕业论文的主要内容 1 第二章 服装连锁管理系统开发环境 3 2.1 开发环境选择 3 2.2 代码管理工具 3 2.3 项目代码命名空间规划 3 2.4 系统结构分析 4 第三章 服装连锁管理系统数据库设计 6 3.1 数据库的选择 6 3.2 系统数据库的设计 6 …

服装店如何建立系统的会员制度?

服装店要在竞争中立于不败之地&#xff0c;就要让自己的经营管理适应现代竞争的需要。服装店的核心就是会员&#xff0c;要不断开发新顾客&#xff0c;并维护老顾客。使单个顾客创造的利润最大化&#xff0c;并且能够长期循环&#xff0c;是服装店老板最想看到的。 会员制&…

服装实体店运营需要的所有软件,合集在此!(建议收藏)实体店运营 实体店运营干货 实体店运营全流程所需系统推荐

随着信息化普及程度越来越高&#xff0c;各行各业的运转速度都在加快&#xff0c;做生意的老板们也开始发现&#xff0c;单靠以前的人工管理已经完全不够用了。 尤其是服装实体店&#xff0c;款式分类多&#xff0c;库存又容易挤压&#xff0c;更加需要有科学的手段去管控日常的…