初级篇,利用 Android 搭建一个简易的人脸识别APP

初级篇,利用 Android 搭建一个简易的人脸识别APP

初始,准备工作安装Android sudio 开发工具搭建android 运行环境(java14)腾讯云OCR产品开通,及其秘钥获取

一、建立一个Android空项目及目录层次介绍(1)android 空项目以及环境搭建,请参考:Windows + Android studio 搭建基础的Android 环境(Java SE 14)(2)目录结构介绍目录结构.gredia以及idea目录 :目录下放置的都是as自动生成的文件,本章无需关系app 目录 : 本章用到的文件目录,仅着重介绍需要使用的文件及目录src > main > java 目录 : 放置所有代码目录,数据交互,事件操作src > main > res 目录 : 资源目录,即android 前端样式 展示界面等前端相关src > main > AndroidMinifest.xml 文件 : 整个项目配置文件,开通权限,首页访问设置,其他页面管理都在此build.gradle文件 :app模块的构建脚本build目录 : 包含编译时自动生成的文件,本章无关gradle目录 :包含gradle wrapper的配置文件,本章无关gitgnore文件 : 文件是用来将制定的目录或文件排除在版本控制之外的,本章无关build.gradle文件 : 全局的gradle构建脚本,通常文件的内容不需要修改,本章无关gradle.properties文件 :全局的gradle配置文件,这里配置的属性将会影响到项目中所有的gradle编译脚本,本章无关gradlew和gradlew.bat 文件 :这两个文件是用来在命令行界面执行gradle命令的,其中gradlew是在linux或mac系统中使用的,gradlew.bat是在windows系统中使用的,本章无关***.iml 文件:iml文件是所有intellij IDEA项目都会自动生成的文件,标识是 intellij IDEA项目,本章无关local.properties文件 : 自动生成用于指定本机sdk的路径,不需要修改,除非sdk路径发生改变,本章无关settings.gradle文件 :指定项目中所有引用的模块,通常情况下模块的引入都是自动生成的,本章无关

小结回顾及知识扩展:(1)创建一个界面创建一个空界面示例(2)加载 GSON 类库

选择项目结构选择给当前项目增加类库选择类库加载应用后再确定二、构建前端页面样式

前端界面展示前端放置资源界面放置 res > layout 文件夹下, 生成示例:activity_face.xml 文件value 目录 : 放置存储值的文件res/drawable-xxxx目录 : 是存放图片的目录

代码示例,(为方便展示与基础学习,前端未拆分样式)

代码语言:javascript复制

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">

xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="56dp"

android:background="#CC0000"

android:paddingLeft="56dp"

android:paddingRight="56dp">

android:id="@+id/nav_title"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:text="人脸识别"

android:textColor="#FDFDFD"

android:textSize="16sp" />

android:layout_width="match_parent"

android:layout_height="44dp"

android:orientation="horizontal"

android:layout_gravity="center_vertical"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:layout_marginTop="30dp">

android:layout_width="200dp"

android:layout_height="match_parent"

android:background="@drawable/ic_launcher_background"

android:backgroundTint="#C52424"

android:textColor="#ffffff"

android:focusable="false"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:text="NeedQualityDetection"

android:textSize="18dp" />

android:id="@+id/needQualityDetection"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@null"

android:hint="0 or 1"

android:text="1"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:textSize="18dp"/>

android:layout_width="match_parent"

android:layout_height="44dp"

android:orientation="horizontal"

android:layout_gravity="center_vertical"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:layout_marginTop="30dp">

android:layout_width="200dp"

android:layout_height="match_parent"

android:background="@drawable/ic_launcher_background"

android:backgroundTint="#C52424"

android:textColor="#ffffff"

android:focusable="false"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:text="FaceModelVersion"

android:textSize="18dp" />

android:id="@+id/paramFaceModel"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@null"

android:hint="2.0 or 3.0"

android:text="3.0"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:textSize="18dp" />

android:id="@+id/photoView"

android:layout_width="wrap_content"

android:layout_height="100dp"

android:layout_gravity="center"

android:layout_margin="20dp"

/>

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="44dp"

android:orientation="horizontal"

android:layout_gravity="center_vertical"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:layout_marginTop="10dp">

android:id="@+id/albumBtnEvt"

android:layout_width="wrap_content"

android:layout_height="44dp"

android:background="#FF5722"

android:text="打 开 相 册"

android:textColor="#FFFEFE"

android:onClick="getImageFromAlbum"/>

android:layout_width="wrap_content"

android:layout_height="44dp"

android:background="#FF5722"

android:text="拍 照"

android:textColor="#FFFEFE"

android:layout_marginLeft="20dp"

android:onClick="toCamera"/>

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="right"

android:background="#A52A2A"

android:text="发 送 请 求"

android:textColor="#FFFEFE"

android:layout_marginLeft="20dp"

android:onClick="onFormBtnClick"/>

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="44dp"

android:orientation="horizontal"

android:layout_gravity="center_vertical"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:layout_marginTop="5dp">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:background="@null"

android:text="年 龄"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:textSize="18dp"

android:focusable="false"/>

android:id="@+id/ageEvt"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@null"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:textSize="18dp"

android:focusable="false"/>

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="44dp"

android:orientation="horizontal"

android:layout_gravity="center_vertical"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:layout_marginTop="5dp">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:background="@null"

android:text="性 别"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:textSize="18dp"

android:focusable="false"/>

android:id="@+id/sexEvt"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@null"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:textSize="18dp"

android:focusable="false"/>

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="44dp"

android:orientation="horizontal"

android:layout_gravity="center_vertical"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:layout_marginTop="5dp">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:background="@null"

android:text="装 束"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:textSize="18dp"

android:focusable="false"/>

android:id="@+id/markEvt"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@null"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:textSize="18dp"

android:focusable="false"/>

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="44dp"

android:orientation="horizontal"

android:layout_gravity="center_vertical"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:layout_marginTop="5dp">

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:background="@null"

android:text="表 情"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:textSize="18dp"

android:focusable="false"/>

android:id="@+id/ExpressionEvt"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@null"

android:paddingLeft="12dp"

android:paddingRight="12dp"

android:textSize="18dp"

android:focusable="false"/>

三、后端响应代码 (src > main > java > com.xxxxx 下)代码语言:javascript复制package com.example.faceiai;

import androidx.core.app.ActivityCompat;

import androidx.core.content.ContextCompat;

import android.Manifest;

import android.app.Activity;

import android.content.Intent;

import android.content.pm.PackageManager;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.drawable.BitmapDrawable;

import android.net.Uri;

import android.os.Bundle;

import android.os.Environment;

import android.os.Handler;

import android.os.StrictMode;

import android.provider.MediaStore;

import android.util.Base64;

import android.util.Log;

import android.view.View;

import android.widget.ImageView;

import android.widget.TextView;

import com.google.gson.Gson;

import org.json.JSONException;

import org.json.JSONObject;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.IOException;

import java.util.HashMap;

import java.util.Map;

public class MainActivity extends Activity {

//申明前端布局属性

private TextView needQualityDetectionEvt, paramFaceModelVersionEvt, markEvt, ageEvt, sexEvt, ExpressionEvt;

//设置需要的拍照、相册权限

private static String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA };//权限

//申明前端图片展示属性

private ImageView photoViewEvt;

//申明人脸检测属性

private String response;

final Handler handler = new Handler();

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

init();

}

/**

* 加载初始化

*/

private void init(){

// android 7.0系统解决拍照的问题

StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();

StrictMode.setVmPolicy(builder.build());

builder.detectFileUriExposure();

//初始化控件 findViewById 用R.id到前端通过android:id指定的id 获取当前选中属性

needQualityDetectionEvt = findViewById(R.id.needQualityDetection);

paramFaceModelVersionEvt = findViewById(R.id.paramFaceModel);

photoViewEvt = findViewById(R.id.photoView);

sexEvt = findViewById(R.id.sexEvt);

ageEvt = findViewById(R.id.ageEvt);

markEvt = findViewById(R.id.markEvt);

ExpressionEvt = findViewById(R.id.ExpressionEvt);

}

/**

* 表单提交点击事件

* 前端通过android:onClick 指定点击时间触发方法

* @param v

*/

public void onFormBtnClick(View v){

//android4.0 以后不能在主线程发起网络请求,该异步网络请求

new Thread(new Runnable()

{

@Override

public void run()

{

//获取前端 needQualityDetection 的 value

int needQualityDetection = Integer.parseInt(needQualityDetectionEvt.getText().toString());

//获取前端 paramFaceModelVersion 的 value

String paramFaceModelVersion = paramFaceModelVersionEvt.getText().toString();

//获取前端相册或者拍照时间生成的缩略图的Bitmap值

Bitmap photoBitmap = ((BitmapDrawable) photoViewEvt.getDrawable()).getBitmap();

//图片Bitmap -转化-> base64

String photoBase64 = bitmapToBase64(photoBitmap);

Map params = new HashMap<>();

params.put("Image", photoBase64);

params.put("FaceModelVersion", paramFaceModelVersion);

params.put("NeedFaceAttributes", 1);

params.put("NeedQualityDetection", needQualityDetection);

Gson gson = new Gson();

String param = gson.toJson(params);

Log.e("request", param);

// TODO Auto-generated method stub

//发送请求 本地封装的https 请求

response = AuthFace.getAuthTC3("DetectFace", param, AuthFace.Version);

//response = "{\"Response\":{\"ImageWidth\":1080,\"ImageHeight\":1440,\"FaceInfos\":[{\"X\":119,\"Y\":18,\"Width\":558,\"Height\":721,\"FaceAttributesInfo\":{\"Gender\":1,\"Age\":24,\"Expression\":28,\"Hat\":false,\"Glass\":false,\"Mask\":true,\"Hair\":{\"Length\":3,\"Bang\":0,\"Color\":0},\"Pitch\":5,\"Yaw\":17,\"Roll\":2,\"Beauty\":79,\"EyeOpen\":true},\"FaceQualityInfo\":{\"Score\":29,\"Sharpness\":43,\"Brightness\":34,\"Completeness\":{\"Eyebrow\":98,\"Eye\":99,\"Nose\":94,\"Cheek\":64,\"Mouth\":71,\"Chin\":35}}}],\"FaceModelVersion\":\"3.0\",\"RequestId\":\"4c1ebdb5-7a96-405e-a9bc-0a329ea26cda\"}}";

handler.post(new Runnable() {

@Override

public void run() {

try {

//处理json 数据 把JSON数据转化为对象

JSONObject jsonObject = new JSONObject(response.toString());

//返回错误提示

if (jsonObject.getJSONObject("Response").has("Error")){

String Message = jsonObject.getJSONObject("Response").getJSONObject("Error").getString("Message");

String RequestId = jsonObject.getJSONObject("Response").getString("RequestId");

String Code = jsonObject.getJSONObject("Response").getJSONObject("Error").getString("Code");

//给前端设置值

sexEvt.setText(Message);

ageEvt.setText(Message);

markEvt.setText(Code);

ExpressionEvt.setText(RequestId);

} else {

//正确的人脸检测反馈

JSONObject FaceAttributesInfo = jsonObject.getJSONObject("Response").getJSONArray("FaceInfos").getJSONObject(0).getJSONObject("FaceAttributesInfo");

int Gender = FaceAttributesInfo.getInt("Gender");

int Age = FaceAttributesInfo.getInt("Age");

int Expression = FaceAttributesInfo.getInt("Expression");

Boolean Mark = FaceAttributesInfo.getBoolean("Mask");

//给前端设置值

sexEvt.setText(FaceUtilsJson.getGenderName(Gender));

ageEvt.setText(String.valueOf(Age));

markEvt.setText(FaceUtilsJson.getMask(Mark));

ExpressionEvt.setText(FaceUtilsJson.getExpressionName(Expression));

}

}catch (JSONException e){

Log.e("JSON error", e.getMessage());

}

}

});

}

}).start();

}

/**

* 获取相册事件

* @param v

*/

public void getImageFromAlbum(View v) {

Intent intent = new Intent(Intent.ACTION_PICK);

intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");

startActivityForResult(intent, 100);// 100: 相册的返回码参数(随便一个值就行,只要不冲突就好)

}

//跳转相机

public void toCamera(View v) {

//查看相机权限 用户手动授权

if(ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ){

Log.e("camera","提示是否要授权");

ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, 3);

}else{

Log.e("camera","直接打开相机");

//已经有权限

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //跳转到 ACTION_IMAGE_CAPTURE

//判断内存卡是否可用,可用的话就进行存储

//putExtra:取值,Uri.fromFile:传一个拍照所得到的文件,fileImg.jpg:文件名

intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES),"fileImg.jpg")));

startActivityForResult(intent,101); // 101: 相机的返回码参数(随便一个值就行,只要不冲突就好)

}

}

/**

* 自带方法,相册更相机时间确定后,返回回来指定的方法

* @param requestCode

* @param resultCode

* @param data

*/

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data){

switch (requestCode){

case 100: //相册返回的数据(相册的返回码)

if (data == null) {

Log.e("onActivityResult", "暂无内容");

return;

}

Uri uriPath = data.getData();

//方案一

//photoViewEvt.setImageURI(uriPath);

//方案二

try {

//获取相册的图片bitmap值

Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uriPath));

//质量压缩

ByteArrayOutputStream bos = new ByteArrayOutputStream();

bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);

byte[] bytes = bos.toByteArray();

Bitmap mSrcBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);

photoViewEvt.setImageBitmap(mSrcBitmap);

} catch (IOException e) {

Log.e("onActivityResult 100", e.getMessage());

e.printStackTrace();

}

break;

case 101: //相机返回的数据(相机的返回码)

try {

File tempFile = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES),"fileImg.jpg"); //相机取图片数据文件

Uri uri = Uri.fromFile(tempFile); //图片文件

Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));

//质量压缩

ByteArrayOutputStream bos = new ByteArrayOutputStream();

bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);

byte[] bytes = bos.toByteArray();

Bitmap mSrcBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);

photoViewEvt.setImageBitmap(mSrcBitmap);

} catch (IOException e) {

Log.e("onActivityResult", e.getMessage());

e.printStackTrace();

}

break;

}

}

/*

* bitmap转base64

* */

private static String bitmapToBase64(Bitmap bitmap) {

String result = null;

ByteArrayOutputStream baos = null;

try {

if (bitmap != null) {

baos = new ByteArrayOutputStream();

bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);

baos.flush();

baos.close();

byte[] bitmapBytes = baos.toByteArray();

result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);

}

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

if (baos != null) {

baos.flush();

baos.close();

}

} catch (IOException e) {

e.printStackTrace();

}

}

return result;

}

}

人脸识别V3鉴权接口请求代码示例 (src > main > java > com.xxx > AuthFace.java)代码语言:javascript复制package com.example.faceiai;

import android.text.TextUtils;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.HttpURLConnection;

import java.net.URL;

import java.net.URLEncoder;

import java.security.MessageDigest;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.HashMap;

import java.util.Map;

import java.util.TimeZone;

import javax.crypto.Mac;

import javax.crypto.spec.SecretKeySpec;

/**

* 人脸识别V3鉴权

*/

public class AuthFace {

private static String SecretId = "";

private static String SecretKey = "";

private static String Url = "https://iai.tencentcloudapi.com";

//规范请求串

private static String HTTPRequestMethod = "POST";

private static String CanonicalURI = "/";

private static String CanonicalQueryString = "";

private static String CanonicalHeaders = "content-type:application/json; charset=utf-8\nhost:iai.tencentcloudapi.com\n";

private static String SignedHeaders = "content-type;host";//参与签名的头部信息

//签名字符串

private static String Algorithm = "TC3-HMAC-SHA256";

private static String Service = "iai";

private static String Stop = "tc3_request";

//版本

public static String Version = "2018-03-01";

/**

* v3鉴权

* @param action 人脸识别接口名 例如 DetectFace

* @param paramJson json化的参数

* @param version 版本号 2018-03-01

* @return

*/

public static String getAuthTC3(String action, String paramJson, String version){

try{

String hashedRequestPayload = HashEncryption(paramJson);

String CanonicalRequest =

HTTPRequestMethod + '\n' +

CanonicalURI + '\n' +

CanonicalQueryString + '\n' +

CanonicalHeaders + '\n' +

SignedHeaders + '\n' +

hashedRequestPayload;

//时间戳

Date date = new Date();

//微秒->秒

String timestamp = String.valueOf(date.getTime() / 1000);

//格林威治时间转化

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

formatter.setTimeZone(TimeZone.getTimeZone("GMT+0"));

String dateString = formatter.format(date.getTime());

//签名字符串

String credentialScope = dateString + "/" + Service + "/" + Stop;

String hashedCanonicalRequest = HashEncryption(CanonicalRequest);

String stringToSign = Algorithm + "\n" +

timestamp + "\n" +

credentialScope + "\n" +

hashedCanonicalRequest;

//计算签名

byte[] secretDate = HashHmacSha256Encryption(("TC3" + SecretKey).getBytes("UTF-8"), dateString);

byte[] secretService = HashHmacSha256Encryption(secretDate, Service);

byte[] secretSigning = HashHmacSha256Encryption(secretService, Stop);

//签名字符串

byte[] signatureHmacSHA256 = HashHmacSha256Encryption(secretSigning, stringToSign);

//替换java DatatypeConverter.printHexBinary(d).toLowerCase()

StringBuilder builder = new StringBuilder();

for (byte b : signatureHmacSHA256) {

String hex = Integer.toHexString(b & 0xFF);

if (hex.length() == 1) {

hex = '0' + hex;

}

builder.append(hex);

}

String signature = builder.toString().toLowerCase();

//组装签名字符串

String authorization = Algorithm + ' ' +

"Credential=" + SecretId + '/' + credentialScope + ", " +

"SignedHeaders=" + SignedHeaders + ", " +

"Signature=" + signature;

//创建header 头部

Map headers = new HashMap<>();

headers.put("Authorization", authorization);

headers.put("Host", "iai.tencentcloudapi.com");

headers.put("Content-Type", "application/json; charset=utf-8");

headers.put("X-TC-Action", action);

headers.put("X-TC-Version", version);

headers.put("X-TC-Timestamp", timestamp);

//headers.put("X-TC-Region", "ap-chengdu");

//request 请求

String response = resquestPostData(Url, paramJson, headers);

return response;

}catch(Exception e){

return e.getMessage();

}

}

/*

* Function : 发送Post请求到服务器

* Param : params请求体内容,encode编码格式

*/

public static String resquestPostData(String strUrlPath, String data, Map headers) {

try {

URL url = new URL(strUrlPath);

HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();

httpURLConnection.setConnectTimeout(3000); //设置连接超时时间

httpURLConnection.setDoInput(true); //打开输入流,以便从服务器获取数据

httpURLConnection.setDoOutput(true); //打开输出流,以便向服务器提交数据

httpURLConnection.setRequestMethod("POST"); //设置以Post方式提交数据

httpURLConnection.setUseCaches(false); //使用Post方式不能使用缓存

//设置header

if (headers.isEmpty()) {

//设置请求体的类型是文本类型

httpURLConnection.setRequestProperty("Content-Type", "application/json");

} else {

for (Map.Entry entry : headers.entrySet()) {

String key = entry.getKey();

String value = entry.getValue();

httpURLConnection.setRequestProperty(key, value);

}

}

//设置请求体的长度

httpURLConnection.setRequestProperty("Content-Length", String.valueOf(data.length()));

//获得输出流,向服务器写入数据

if (data != null && !TextUtils.isEmpty(data)) {

byte[] writebytes = data.getBytes();

// 设置文件长度

OutputStream outputStream = httpURLConnection.getOutputStream();

outputStream.write(data.getBytes());

outputStream.flush();

}

int response = httpURLConnection.getResponseCode(); //获得服务器的响应码

if(response == HttpURLConnection.HTTP_OK) {

InputStream inptStream = httpURLConnection.getInputStream();

return dealResponseResult(inptStream); //处理服务器的响应结果

}

} catch (IOException e) {

return "err: " + e.getMessage().toString();

}

return "-1";

}

/*

* Function : 封装请求体信息

* Param : params请求体内容,encode编码格式

*/

public static StringBuffer getRequestData(Map params, String encode) {

StringBuffer stringBuffer = new StringBuffer(); //存储封装好的请求体信息

try {

for(Map.Entry entry : params.entrySet()) {

stringBuffer.append(entry.getKey())

.append("=")

.append(URLEncoder.encode(entry.getValue(), encode))

.append("&");

}

stringBuffer.deleteCharAt(stringBuffer.length() - 1); //删除最后的一个"&"

} catch (Exception e) {

e.printStackTrace();

}

return stringBuffer;

}

/*

* Function : 处理服务器的响应结果(将输入流转化成字符串)

* Param : inputStream服务器的响应输入流

*/

public static String dealResponseResult(InputStream inputStream) {

String resultData = null; //存储处理结果

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

byte[] data = new byte[1024];

int len = 0;

try {

while((len = inputStream.read(data)) != -1) {

byteArrayOutputStream.write(data, 0, len);

}

} catch (IOException e) {

e.printStackTrace();

}

resultData = new String(byteArrayOutputStream.toByteArray());

return resultData;

}

/**

*

*/

private static String HashEncryption(String s) throws Exception {

MessageDigest sha = MessageDigest.getInstance("SHA-256");

sha.update(s.getBytes());

//替换java DatatypeConverter.printHexBinary(d).toLowerCase()

StringBuilder builder = new StringBuilder();

for (byte b : sha.digest()) {

String hex = Integer.toHexString(b & 0xFF);

if (hex.length() == 1) {

hex = '0' + hex;

}

builder.append(hex);

}

return builder.toString().toLowerCase();

}

private static byte[] HashHmacSha256Encryption(byte[] key, String msg) throws Exception {

Mac mac = Mac.getInstance("HmacSHA256");

SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());

mac.init(secretKeySpec);

return mac.doFinal(msg.getBytes("UTF-8"));

}

}

人脸检测数据分析接口(src > main > java > com.xxx > FaceUtilsJson.java)代码语言:javascript复制package com.example.faceiai;

/**

* 人脸检测与分析

*/

public class FaceUtilsJson{

public static String getGenderName(int Age) {

//性别处理

if (Age > 49) {

return "男性";

} else {

return "女性";

}

}

public static String getExpressionName(int Expression) {

if (Expression < 50) {

return "正常";

} else {

return "微笑";

}

}

public static String getMask(Boolean Mask){

if (Mask) {

return "佩戴口罩";

} else {

return "未佩戴口罩";

}

}

}

四、权限赋予 (src > main > AndroidManifest.xml)代码语言:javascript复制

package="com.example.faceiai">

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:roundIcon="@mipmap/ic_launcher_round"

android:supportsRtl="true"

android:theme="@style/AppTheme">

五、调用及其展示

调用方法效果展示图搭建成功的话,记得给个赞,支持下小编 !!!!!

🎀 相关推荐

剑网3怀旧服怎么拜师
🎯 365bet中文比分

剑网3怀旧服怎么拜师

📅 08-26 👀 9309
UBC大学被指学术质量差 SFU排名跌史上最低
🎯 365体育备用网站

UBC大学被指学术质量差 SFU排名跌史上最低

📅 02-02 👀 1010
联想乐檬miniStation测评:适合全家人娱乐的游戏盒子
🎯 365bet中文比分

联想乐檬miniStation测评:适合全家人娱乐的游戏盒子

📅 02-04 👀 4719