前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用腾讯OCR光学识别名片集成至ZOHO CRM-总结-安卓开发

使用腾讯OCR光学识别名片集成至ZOHO CRM-总结-安卓开发

原创
作者头像
no怕不了木
发布于 2023-08-07 07:31:06
发布于 2023-08-07 07:31:06
6940
举报
文章被收录于专栏:未来码迹未来码迹

安卓软件开发-使用腾讯OCR光学识别名片集成至ZOHO CRM

腾讯OCR光学识别官网介绍:(https://cloud.tencent.com/document/product/866/36214)

注:全程使用java开发

1.界面开发

界面需求(需要两个界面):

第一个界面:需要两个按钮。一个用来触发拍照,另外一个用来确定识别的效果,触发识别,需要一个ImageView用来显示图片

第二个界面:

七个TextView,用来标识名片字段,

七个EditText。存放识别信息

界面效果如下:

界面1

代码如下:

代码语言:html
AI代码解释
复制
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:background="@drawable/btn"
            android:id="@+id/btn_original"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="拍照/重拍"
            android:textColor="@color/black"
            android:textSize="17sp"/>
        <Button
            android:id="@+id/btn_ocr"
            android:background="@drawable/btn"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="确定"
            android:textColor="@color/black"
            android:textSize="17sp"/>
    </LinearLayout>
    <ImageView
        android:id="@+id/iv_photo"
        android:layout_width="match_parent"
        android:layout_height="360dp"
        android:scaleType="fitCenter"/>
</LinearLayout>

界面2

代码如下:

代码语言:html
AI代码解释
复制
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/allinfo"
    android:orientation="vertical">
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <LinearLayout
            android:id="@+id/lin_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="姓名"
                android:textSize="17sp"/>
            <EditText
                android:id="@+id/Last_name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="17sp"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="職務"
                android:textSize="17sp"/>
            <EditText
                android:id="@+id/Title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="17sp"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="公司"
                android:textSize="17sp"/>
            <EditText
                android:id="@+id/Account_Name"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="17sp"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="地址"
                android:textSize="17sp"/>
            <EditText
                android:id="@+id/Mailing_Country"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="17sp"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="郵箱"
                android:textSize="17sp"/>
            <EditText
                android:id="@+id/Email"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="17sp"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="手機"
                android:textSize="17sp"/>
            <EditText
                android:id="@+id/Mobile"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="17sp"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="電話"
                android:textSize="17sp"/>
            <EditText
                android:id="@+id/Phone"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="17sp"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="主要生產產品"
                android:textSize="17sp"/>
            <EditText
                android:id="@+id/edit_field20"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="17sp"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="所屬產業"
                android:textSize="17sp"/>
            <Spinner
                android:id="@+id/sp_Industry"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:spinnerMode="dialog"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="引合來源"
                android:textSize="17sp"/>
            <Spinner
                android:id="@+id/sp_Lead_Source"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:spinnerMode="dialog"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="線索狀態"
                android:textSize="17sp"/>
            <Spinner
                android:id="@+id/sp_Lead_Status"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:spinnerMode="dialog"/>
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="客戶等級"
                android:textSize="17sp"/>
            <Spinner
                android:id="@+id/sp_Rating"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:spinnerMode="dialog"/>
            <View
                android:layout_width="16dp"
                android:layout_height="30dp" />
            <Button
                android:id="@+id/btn_sub"
                android:background="@drawable/btn"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="同步至CRM"/>
            <View
                android:layout_width="16dp"
                android:layout_height="15dp" />
        </LinearLayout>
    </ScrollView>

</LinearLayout>

2.集成腾讯云OCR识别

在模块build.gradle中添加包

代码语言:java
AI代码解释
复制
dependencies {

    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.8.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    implementation 'com.tencentcloudapi:tencentcloud-sdk-java-ocr:3.1.777'
    implementation 'xerces:xercesImpl:2.12.0'
}

建立BusinessCardOCR,用于识别照片文件,代码如下

代码语言:Java
AI代码解释
复制
package com.example.ocr.util;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.ocr.v20181119.OcrClient;
import com.tencentcloudapi.ocr.v20181119.models.*;
public class BusinessCardOCR {
    public String ocrJson(String encodedImage){
        try{
            // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential cred = new Credential("秘钥ID", "秘钥Key");
            // 实例化一个http选项,可选的,没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("ocr.tencentcloudapi.com");
            // 实例化一个client选项,可选的,没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            OcrClient client = new OcrClient(cred, "ap-shanghai", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            BusinessCardOCRRequest req = new BusinessCardOCRRequest();
            req.setImageBase64(encodedImage);
            // 返回的resp是一个BusinessCardOCRResponse的实例,与请求对象对应
            BusinessCardOCRResponse resp = client.BusinessCardOCR(req);
            // 输出json格式的字符串回包
            return BusinessCardOCRResponse.toJsonString(resp);
        } catch (TencentCloudSDKException e) {
            return e.toString();
        }
    }
}

在Credential cred = new Credential("秘钥ID", "秘钥Key");填写自己的秘钥

因为识别照片需要将照片转换为base64编码,故在函数中传入形参String,也就是base64编码,还需要返回一个String用来返回识别结果,识别的结果是json数据

3.权限声明

在AndroidManifest.xml/manifest标签下面声明权限

代码语言:Java
AI代码解释
复制
<uses-permission android:name="android.permission.CAMERA" /> <!-- 录音 -->
    <uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- 存储卡读写 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> <!-- 获取网络状态 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 互联网 -->
    <uses-permission android:name="android.permission.INTERNET" />

权限声明代码:

代码语言:Java
AI代码解释
复制
//检查相机权限
    private boolean checkCameraPermission() {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                == PackageManager.PERMISSION_GRANTED;
    }

    private void requestCameraPermission() {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
            // 显示权限说明对话框
            // 可以使用一个对话框或其他方式向用户解释为什么需要相机权限,并在用户同意后请求权限
            Toast.makeText(MainActivity.this,"未授權相機權限",Toast.LENGTH_SHORT).show();
        } else {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
                    REQUEST_CAMERA_PERMISSION);
        }
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CAMERA_PERMISSION) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                takeOriginalPhoto();
            } else {
                // 相机权限被拒绝,可以显示一条消息或执行其他操作
                Toast.makeText(MainActivity.this,"未授權相機權限",Toast.LENGTH_SHORT).show();
            }
        }
    }
    // 拍照时获取原始图片
    private void takeOriginalPhoto() {
        // Android10开始必须由系统自动分配路径,同时该方式也能自动刷新相册
        ContentValues values = new ContentValues();
        // 指定图片文件的名称
        values.put(MediaStore.Images.Media.DISPLAY_NAME, "photo_" + DateUtil.getNowDateTime());
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");// 类型为图像
        // 通过内容解析器插入一条外部内容的路径信息
        mImageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

        launcherOriginal.launch(mImageUri);
    }
}

4.识别图片

说明,判断mImageUri也就是图片是不是空的,不是空的就是已经有图片,进行返回,并将图片放置在ImageView下面。声明一个意图,将识别的名片信息,包裹在意图中,并跳转到第二个界面

代码语言:Java
AI代码解释
复制
if (mImageUri != null){
                try {
                    Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), mImageUri);
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos);
                    byte[] imageBytes = baos.toByteArray();
                    baos.close();
                    bitmap.recycle();
                    String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);

                    // 在单独的线程上执行网络请求
                    new Thread(() -> {
                        BusinessCardOCR businessCardOCR = new BusinessCardOCR();
                        String result = businessCardOCR.ocrJson(encodedImage);
//                    判断是否是json的数据格式
                        isjson json = new isjson();
                        boolean ISJSON =json.json_Str(result);
                        if (ISJSON){
                            Intent intent = new Intent(this,sendDate.class);
                            Bundle bundle = new Bundle();
                            bundle.putString("result",result);
                            intent.putExtras(bundle);
                            startActivity(intent);
                        }else {
                            runOnUiThread(() ->{
                                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                                builder.setTitle("未識別到名片資訊,請重新拍攝");
                                builder.setPositiveButton("確認",(dialog, which) -> {
                                    dialog.dismiss();
                                });
                                AlertDialog alert = builder.create();
                                alert.show();
                            });
                        }
                    }).start();
                } catch (IOException e) {
                    e.printStackTrace();
                }

解析识别结果并填充至相应位置

5.识别提取信息

注意,识别的结果比如电话有多个,姓名中可能有中文姓名和英文姓名,但我们只需要一个姓名,所以使用先进行全部解析

代码如下:

代码语言:Java
AI代码解释
复制
jsonObject = new JSONObject(request);
JSONArray businessCardInfos = jsonObject.getJSONArray("BusinessCardInfos");
System.out.println(request);
for (int i = 0; i < businessCardInfos.length(); i++) {
    JSONObject info = businessCardInfos.getJSONObject(i);
    String infoname = info.getString("Name");
    String infoValue = info.getString("Value");

在代码中声明Hashsat<>

代码语言:java
AI代码解释
复制
Set<String> ocrLast_name = new HashSet<>();

判断infoname中是否包含“姓名”如果有,就将值给到ocrLast_name,这样我们就拿到了相应的值

代码语言:Java
AI代码解释
复制
if (infoname.contains("姓名")) {
                    ocrLast_name.add(infoValue);
                }

其他的如法炮制

还需要判断ocrLast_name大小是不是大于0,只有大于0时才获取,不然不报错,角标越界

代码语言:java
AI代码解释
复制
if (ocrLast_name.size() > 0) {
    Last_name.setText((CharSequence) ocrLast_name.toArray()[0]);
}

以上是逻辑

6.发送网络请求

6.1查看返回的数据

并查看返回的数据的状态,执行相应情况

代码语言:java
AI代码解释
复制
{
//                    获取刷新的code
                    RefreshToken refreshToken = new RefreshToken();
                    String refresh = RefreshToken.refresh_token();
//                    判断执行的结果
                    if (!refresh.equals("error")) {
                        ZodoData zodoData = new ZodoData();
                        String zoho = null;
                        System.out.println("开始检测信息" + Last_name_value + Title_value + Account_Name_value + Mailing_Country_value + Email_value + Mobile_value + Phone_value);
                        try {
                            zoho = ZodoData.zodoData(refresh, Last_name_value, Title_value, Account_Name_value, Mailing_Country_value, Email_value, Mobile_value, Phone_value,field20value,spIndustryvalue,spLead_Sourcevalue,spLead_Statusvalue,spRatingvalue);
                            if (zoho.equals("SUCCESS")) {
                                runOnUiThread(() -> {
                                    AlertDialog.Builder builder = new AlertDialog.Builder(sendDate.this);
                                    builder.setTitle("上傳至CRM成功");
                                    builder.setPositiveButton("確認", (dialog, which) -> {
                                        dialog.dismiss();
                                        finish();
                                    });
                                    AlertDialog alert = builder.create();
                                    alert.show();
                                });
                            }
6.2RefreshToken刷新获取Token

RefreshToken文件代码,属性Token,填写client_id,client_secret、refresh_token

代码语言:java
AI代码解释
复制
package com.example.ocr.util;

import java.io.IOException;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class RefreshToken {

    public static String refresh_token() {
        // 定义客户端ID,客户端密钥和刷新令牌
        String client_id = "xxxxxxxxxxxxxxxxxxxxx";
        String client_secret = "xxxxxxxxxxxxxxxxxxxxxxxx";
        String refresh_token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

        // 构建请求
        String url = "https://accounts.zoho.com.cn/oauth/v2/token";
        RequestBody formBody = new FormBody.Builder()
                .add("grant_type", "refresh_token")
                .add("client_id", client_id)
                .add("client_secret", client_secret)
                .add("refresh_token", refresh_token)
                .build();
        Request request = new Request.Builder()
                .url(url)
                .post(formBody)
                .build();

        // 创建OkHttpClient对象
        OkHttpClient client = new OkHttpClient();

        // 发送请求
        try (Response response = client.newCall(request).execute()) {
            // 解析响应
            if (response.isSuccessful()) {
                String acc = response.body().string();
                String access_token = acc.substring(acc.indexOf("access_token") + 15, acc.indexOf("scope") - 3);
                return access_token;
            } else {
                return "error";
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "error";
        }
    }

}

ZodoData文件构建请求,封包数据发送

代码语言:java
AI代码解释
复制
package com.example.ocr.util;

import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONObject;
public class ZodoData {

    public static String zodoData(String AUTH_TOKEN, String Last_name, String Title,String Account_name, String Mailing_Country,String emailvalue,String Moblievalue,String phonevalue,String field20value,String Industryvalue,String Lead_Sourcevalue,String  Lead_Statusvalue,String Ratingvalue) throws JSONException {
        // 定义授权令牌和API端点
        String ZOHOCRM_AUTH_TOKEN = AUTH_TOKEN;
        String ZOHOCRM_API_ENDPOINT = "https://www.zohoapis.com.cn/crm/v2/Leads";

        // 构建扫描信息
        JSONObject scanned_info = new JSONObject();
        scanned_info.put("name", Last_name);//姓名
        scanned_info.put("jobtitle", Title);// 工作职称
        scanned_info.put("company", Account_name); // 公司名称
        scanned_info.put("address", Mailing_Country); // 公司地址
        scanned_info.put("emailvalue", emailvalue);
        scanned_info.put("Moblievalue", Moblievalue);
        scanned_info.put("phonevalue", phonevalue);
        scanned_info.put("field20value", field20value);
        scanned_info.put("Industryvalue", Industryvalue);
        scanned_info.put("Lead_Sourcevalue", Lead_Sourcevalue);
        scanned_info.put("Lead_Statusvalue", Lead_Statusvalue);
        scanned_info.put("Ratingvalue", Ratingvalue);

        // 构建联系人信息
        JSONObject contact_info = new JSONObject();
        contact_info.put("Last_Name", scanned_info.getString("name")); // 姓名
        contact_info.put("Designation", scanned_info.getString("jobtitle")); // 工作职称
        contact_info.put("Company", scanned_info.getString("company")); // 公司名称
        contact_info.put("Country", scanned_info.getString("address")); // 公司地址
        contact_info.put("Email", scanned_info.getString("emailvalue")); // 邮箱地址
        contact_info.put("Mobile", scanned_info.getString("Moblievalue")); // 手机号码
        contact_info.put("Phone", scanned_info.getString("phonevalue")); // 手机号码

        contact_info.put("field20", scanned_info.getString("field20value")); // 主要生產產品
        contact_info.put("Industry", scanned_info.getString("Industryvalue")); // 所屬產業
        contact_info.put("Lead_Source", scanned_info.getString("Lead_Sourcevalue")); // 引合來源
        contact_info.put("Lead_Status", scanned_info.getString("Lead_Statusvalue")); // 線索狀態
        contact_info.put("Rating", scanned_info.getString("Ratingvalue")); // 客戶等級

        JSONArray data = new JSONArray();
        data.put(contact_info);
        JSONObject lead_info = new JSONObject();
        lead_info.put("data", data);

        // 构建请求
        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(JSON, lead_info.toString());
        Request request = new Request.Builder()
                .url(ZOHOCRM_API_ENDPOINT)
                .addHeader("Authorization", "Zoho-oauthtoken " + ZOHOCRM_AUTH_TOKEN)
                .addHeader("Content-Type", "application/json")
                .post(body)
                .build();

        // 创建OkHttpClient对象
        OkHttpClient client = new OkHttpClient();

        // 发送请求
        try (Response response = client.newCall(request).execute()) {
            // 解析响应
            if (response.isSuccessful()) {
                String jsonStr = response.body().string();
                JSONObject jsonObject = new JSONObject(jsonStr);
                JSONArray  businessCardInfos =jsonObject.getJSONArray("data");
                JSONObject firstBusinessCardInfo = businessCardInfos.getJSONObject(0);
                String status = firstBusinessCardInfo.getString("code");
                System.out.println(jsonStr);
                return status;
            } else {
                String err = response.body().string();
                return err;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "error";
        }
    }

}

7.常用的代码总结

7.1调用相机识别信息
代码语言:java
AI代码解释
复制
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), mImageUri);
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos);
                    byte[] imageBytes = baos.toByteArray();
                    baos.close();
                    bitmap.recycle();
                    String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);

长时间执行的任务需要创建一个线程执行,比如在上述的代码中,识别图片信息,这样的工作必须的创建线程执行,不然会让界面闪退

代码语言:java
AI代码解释
复制
new Thread(() -> {
                        BusinessCardOCR businessCardOCR = new BusinessCardOCR();
                        String result = businessCardOCR.ocrJson(encodedImage);
//                    判断是否是json的数据格式
                        isjson json = new isjson();
                        boolean ISJSON =json.json_Str(result);
                        if (ISJSON){
                            Intent intent = new Intent(this,sendDate.class);
                            Bundle bundle = new Bundle();
                            bundle.putString("result",result);
                            intent.putExtras(bundle);
                            startActivity(intent);
                        }else {
                            runOnUiThread(() ->{
                                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                                builder.setTitle("未識別到名片資訊,請重新拍攝");
                                builder.setPositiveButton("確認",(dialog, which) -> {
                                    dialog.dismiss();
                                });
                                AlertDialog alert = builder.create();
                                alert.show();
                            });
                        }
                    }).start();
7.2弹窗提醒

依据情况可能需要在线程中执行

代码语言:txt
AI代码解释
复制
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("請先拍攝照片");
builder.setPositiveButton("確認",(dialog, which) -> {
    dialog.dismiss();
});
AlertDialog alert = builder.create();
alert.show();
7.3声明一个下拉列表
代码语言:java
AI代码解释
复制
private String [] RatingArray = {"A級(產業符合度:高)","B級(產業符合度:中)","C級(產業符合度:低)","不確定"};

ArrayAdapter<String> Rating_value = new ArrayAdapter<String>(this,
                androidx.appcompat.R.layout.support_simple_spinner_dropdown_item, RatingArray);
        // 从布局文件中获取名叫sp_dropdown的下拉框
        Spinner sp_Rating = findViewById(R.id.sp_Rating);//   引合來源列表
        // 设置下拉框的标题。对话框模式才显示标题,下拉模式不显示标题
        sp_Rating.setPrompt("請選擇客戶等級");
        sp_Rating.setAdapter(Rating_value); // 设置下拉框的数组适配器
        sp_Rating.setSelection(0); // 设置下拉框默认显示第一项


which) -> {
    dialog.dismiss();
});
AlertDialog alert = builder.create();
alert.show();

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
跨链桥是否有安全的未来?
Chainalysis估计,在13次单独的跨链桥黑客攻击中,有20亿美元的加密货币被盗,其中大部分是今年被盗的。到目前为止,对跨链桥的攻击占2022年被盗资金总额的69%。
小将
2022/10/11
7510
跨链桥是否有安全的未来?
什么是跨链桥?
    在过去的几年里,许多新的支持智能合约的公共区块链已经上线,这就产生了加密货币领域跨链互操作性的需求。目前,该领域的开发人员正在努力构建跨链架构,以促进不同区块链之间的通信。 
终有链响
2024/07/29
1530
跨链桥怎么了?谈跨链桥的风险、现在及未来
文章中提到的项目有: 以太坊 2.0[6], Cosmos[7], IBC[8], Layer Zero[9], Solana[10], Serum[11], Optimistic Roll-ups[12], StarkNet[13] , [Terra] (https://www.terra. money/), [THORChain](https://thorchain.org/ "Terra] (https://www.terra. money/ "Terra] (https://www.terra. money/), [THORChain"), [THORChain"), Osmosis[14], Anyswap,[15] Wormhole[16], Ronin Bridge[17], Terra Bridge[18], Avalanche Bridge[19], Ren Bridge, [20] Axie Infinity[21]
Tiny熊
2022/11/07
1.7K0
跨链桥怎么了?谈跨链桥的风险、现在及未来
150亿数字加密货币被盗的真相之后,还能拿什么拯救你,我的交易所!
从去年年底开始,我就一直关注数字加密货币的动态。因为之前有9年的算法对冲基金的从业经验,很自然的,我被加密货币交易动态所吸引了。虽然我并不是加密货币的忠实信徒,但是,我希望对新的交易技术有一个全新的认识。除了ICO狂热之外,加密货币技术中还有一些有趣的创新,尤其是在去中心化交易所的概念。
区块链大本营
2018/08/03
5810
150亿数字加密货币被盗的真相之后,还能拿什么拯救你,我的交易所!
一个月疯狂窃取5.4亿美元,Lazarus Group黑客组织拿钱造火箭
近日,美国财政部指控有朝鲜政府背景的黑客组织Lazarus Group3月从Axie Infinity 侧链 Ronin Network疯狂盗窃了5.4亿美元。
FB客服
2022/06/08
5170
一个月疯狂窃取5.4亿美元,Lazarus Group黑客组织拿钱造火箭
10 大趋势带你预见 DeFi 2020!
本文是加密货币研究平台 Messair 近日发布的《Crypto Theses for 2020》报告的节选部分,将探讨 DeFi(Decentralized Finance,去中心化金融)在接下来的2020年具有哪些趋势,观点仅代表原作者,不构成任何投资意见或建议。Enjoy~
区块链大本营
2020/02/21
5550
10 大趋势带你预见 DeFi 2020!
Plutos 网络简介
Plutos Network 是一个跨链合成发行和衍生品交易平台,为用户引入挖矿激励和 Staking 奖励。通过整合Polkadot、BSC 和 Solana等区块链,实现链上和跨链流动性和交易,Plutos Network 将为用户提供各种可持续、盈利和颠覆性的合成产品的合成发行和交易服务到传统的衍生品市场。
公众号---人生代码
2021/07/08
8000
Plutos 网络简介
跨链桥为什么在DeFi中非常重要?
在区块链生态系统中,最令人兴奋的领域之一是去中心化金融(DeFi),甚至引发了传统金融机构的关注和革新。但是,试图将BNB与ETH进行相互转换的经历,实际上并不像看起来的那么简单。
小将
2022/04/16
3400
跨链桥为什么在DeFi中非常重要?
NFT在DeFi中的用例 NFT相关软件开发
NFTs是在区块链上经过验证的独特数字资产,可以代表从数字艺术到虚拟房地产的任何事物。它们还可以用作抵押品以在 DeFi 中获得贷款,从而创造一种获取资金和为创意项目融资的新方式。NFT 贷款协议的主要好处之一是它们允许更高效的贷款流程。在传统金融中,贷款过程可能漫长而繁琐,涉及大量中介机构和大量文书工作。在 DeFi 中,贷款可以通过 NFT 进行担保,整个过程可以自动化,从而使其更快、更高效。使用 NFT 作为抵押品是它们提供了一种新型资产,可用于在 DeFi 中抵押贷款。与股票或房地产等传统资产不同,NFT 是独一无二的,无法复制。
飞机号dapp119
2023/02/15
8230
NFT在DeFi中的用例 NFT相关软件开发
大会前瞻 | 全能美女王奇君带你认识稳定币及其应用
2018以太坊技术及应用大会·中国 倒计时 2 天 6月3日,中国年度最具影响力的以太坊技术社区大趴:2018以太坊技术及应用大会·中国,将在北京·悠唐皇冠假日酒店举行。邀请到众多国内外顶级开发者参加,以太坊的创立者Vitalik Buterin本人届时也会亲临现场! 这里,有1000+以太坊开发者,以及优质的资本、项目和法律机构,让你一站打尽以太坊全生态! 她曾是4A数字营销广告公司的策略师,也是新东方的雅思讲师;她是资深行业翻译的口译员;也曾担任过全球最大的比特币钱包和区块链浏览器blockchain
区块链大本营
2018/06/19
5160
100 多家 Web3 公司重构互联网的未来
投资者正在向热门的 Web3 技术投入资金。但是 Web3 是如何运作的,谁在构建?从去中心化金融到靠玩游戏赚钱的游戏,我们分析了当今的 Web3 及其对消费者和创作者的意义。
点滴科技资讯
2023/03/01
1.5K0
100 多家 Web3 公司重构互联网的未来
2019年度区块链安全复盘总结
如果说2018年,我们做区块链安全拥有了“上帝视角”,那过去的2019年,我们则收获了“圣母心态”。
区块链大本营
2020/02/21
6110
2019年度区块链安全复盘总结
关于区块链,你绝不能忽视的4个安全问题和5招应对方法!
内容 | 万涛 IDF极安客实验室联合创始人 整理 | Aholiab 说起区块链,虽然为人大肆谈论,却一直绕不过一个令人尴尬的问题——关于数字资产的丢失、被盗问题屡见不鲜,包括之前币安的安全事件也引起了业界的轰动。 那么,区块链安全的现状到底是什么?区块链与加密货币究竟存在哪些安全问题?如何构建安全的智能合约?IDF极安客实验室联合创始人万涛认为,如果不顾安全大谈区块链都是「耍流氓」;如果以安全的名义去鼓吹区块链,却没有实质的行动,则属厚颜无耻。近日,万涛给「区块链大本营」讲了区块链安全的那些事儿。 那
区块链大本营
2018/05/11
1.3K0
2024 年加密领域需要注意的 5 大网络安全威胁
让我们深入研究2023年加密领域的一些关键网络安全趋势,预计这些趋势将持续到 2024 年,对更多加密货币用户造成威胁。
星尘安全
2024/09/15
1380
2024 年加密领域需要注意的 5 大网络安全威胁
什么是加密货币中的流动性挖矿?
在去中心化金融(DeFi)出现之前,加密货币的所有者只能持有或交易它们以从其资产中获利。然而,DeFi 流动性挖矿地出现在某种程度上改变了游戏规则。
小将
2022/09/30
1.6K0
什么是加密货币中的流动性挖矿?
加密货币: 数字货币如何改变金融
上周,Twitter首席执行官Jack Dorsey宣布,他同时经营的金融公司Square将推出一个新的平台,将使用比特币创建去中心化金融项目。在这些天马斯克围绕加密货币习惯性的、持续的网络噪音输出中,你能不给Dorsey的举动以时间吗?Square的项目最终可能会作为一个分水岭被记住,而那也会是去中心化金融,或 "DeFi",最终进入主流的时刻。
用户7358413
2021/07/25
1.3K0
2024 年加密货币领域需要注意的 5 大网络安全威胁
加密货币世界主要存在于数字领域,面临着众多不断变化的网络威胁,这些威胁所带来的风险,给个人和企业组织造成了重大损失。
FB客服
2024/01/04
2980
2024 年加密货币领域需要注意的 5 大网络安全威胁
DeFi中的De是什么意思?这对区块链行业意味着什么?
作者 | Oscar W 翻译 | 火火酱,责编 | Carol 出品 | 区块链大本营(ID:blockchain_camp) 区块链这一概念最早是由Stuart Haber和Scott Stornetta在1991年提出的。直到2008年,中本聪(Nakamoto Satoshi)将第一个区块链概念化,并创造了比特币。从那时起,无数的项目涌现出来,希望能够彻底改变区块链领域。 然而,直到2015年,一位名为 Vitalik Buterin(V 神)的天才创造了以太坊,才迈出了改变的关键性一步。以太坊
区块链大本营
2023/03/31
7480
DeFi中的De是什么意思?这对区块链行业意味着什么?
2019年区块链安全事件总结,全球损失超60亿美元 | 盘点
随着现代化信息技术和应用的快速发展,数字资产这种以计算机信息技术为基础的货币形式应运而生。其可追溯、防伪造、防篡改的特性,提升了交易安全性,2019年已成为业界关注的热点,发展十分迅速。
区块链大本营
2019/12/23
4.4K0
2019年区块链安全事件总结,全球损失超60亿美元 | 盘点
Solana 是 DeFi 的未来吗?
最近几周,区块链 Solana 的本地货币 SOL 的价格飙升。从 8 月 25 日星期三的略高于 67 美元,SOL 已飙升至目前的 145 美元(截至 9 月 6 日),在短短 12 天内上涨了 100% 以上。
公众号---人生代码
2021/09/18
1.4K0
Solana 是 DeFi 的未来吗?
推荐阅读
相关推荐
跨链桥是否有安全的未来?
更多 >
目录
  • 安卓软件开发-使用腾讯OCR光学识别名片集成至ZOHO CRM
    • 1.界面开发
    • 2.集成腾讯云OCR识别
    • 3.权限声明
    • 4.识别图片
    • 5.识别提取信息
    • 6.发送网络请求
      • 6.1查看返回的数据
      • 6.2RefreshToken刷新获取Token
    • 7.常用的代码总结
      • 7.1调用相机识别信息
      • 7.2弹窗提醒
      • 7.3声明一个下拉列表
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档