Flutter通讯验证插件truecaller_sdk的使用

发布于 1周前 作者 ionicwang 来自 Flutter

Flutter通讯验证插件truecaller_sdk的使用

Truecaller SDK 是一个基于 OAuth 2.0 的行业标准授权协议,用于在Flutter应用程序中实现用户验证。以下是如何集成和使用 truecaller_sdk 插件的详细步骤。

步骤1:更新 pubspec.yaml 文件

首先,在您的 pubspec.yaml 文件中添加 truecaller_sdk 插件:

dependencies:
  ...
  truecaller_sdk: ^1.0.0
  ...

步骤2:生成客户端ID并添加到 AndroidManifest.xml

  • 注册并创建业务账户以管理OAuth项目。
  • 按照官方文档生成客户端ID。
  • /android 模块下的 AndroidManifest.xml 文件中添加一个 meta-data 元素到 application 元素中,内容为您的客户端ID:
<application>  
...  
<meta-data android:name="com.truecaller.android.sdk.ClientId" android:value="PASTE_YOUR_CLIENT_ID_HERE"/>
...  
</application>

步骤3:修改 MainActivity.kt 文件

  • 转到 /android 模块下的 MainActivity.kt 文件。
  • MainActivity.kt 扩展为 FlutterFragmentActivity
  • 覆盖两个函数 configureFlutterEngine(flutterEngine: FlutterEngine)getBackgroundMode()
class MainActivity: FlutterFragmentActivity() {
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine)
    }

    override fun getBackgroundMode(): FlutterActivityLaunchConfigs.BackgroundMode {
        return FlutterActivityLaunchConfigs.BackgroundMode.transparent
    }
}
  • 更新 launchModesingleTask
<activity android:name=".MainActivity"
          android:launchMode="singleTask">
...
</activity>

步骤4:添加必要的权限到 AndroidManifest.xml

根据您初始化SDK时选择的选项,添加相应的权限:

对于 Android 8 及以上版本:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS"/>

对于 Android 7 及以下版本:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>

这些权限是必须的,以便SDK能够自动检测挂断电话并完成验证流程。

示例代码

示例1:仅验证拥有Truecaller应用的用户

以下是验证仅拥有Truecaller应用用户的完整示例代码:

import 'package:flutter/material.dart';
import 'package:truecaller_sdk/truecaller_sdk.dart';
import 'package:uuid/uuid.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late Stream<TcSdkCallback>? _stream;
  late String? codeVerifier;

  @override
  void initState() {
    super.initState();
    _stream = TcSdk.streamCallbackData;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Truecaller SDK example'),
        ),
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              MaterialButton(
                onPressed: () async {
                  await TcSdk.initializeSDK(sdkOption: TcSdkOptions.OPTION_VERIFY_ONLY_TC_USERS);
                  bool isUsable = await TcSdk.isOAuthFlowUsable;

                  if (isUsable) {
                    String oAuthState = Uuid().v1();
                    TcSdk.setOAuthState(oAuthState);
                    TcSdk.setOAuthScopes(['profile', 'phone', 'openid']);
                    
                    String? codeVerifier = await TcSdk.generateRandomCodeVerifier;
                    String? codeChallenge = await TcSdk.generateCodeChallenge(codeVerifier);

                    if (codeChallenge != null) {
                      this.codeVerifier = codeVerifier;
                      TcSdk.setCodeChallenge(codeChallenge);
                      TcSdk.getAuthorizationCode;
                    } else {
                      final snackBar = SnackBar(content: Text("Device not supported"));
                      ScaffoldMessenger.of(context).showSnackBar(snackBar);
                      print("***Code challenge NULL***");
                    }
                  } else {
                    final snackBar = SnackBar(content: Text("Not Usable"));
                    ScaffoldMessenger.of(context).showSnackBar(snackBar);
                    print("***Not usable***");
                  }
                },
                child: Text(
                  "Initialize SDK & Get Authorization Code",
                  style: TextStyle(color: Colors.white),
                ),
                color: Colors.blue,
              ),
              Divider(
                color: Colors.transparent,
                height: 20.0,
              ),
              StreamBuilder<TcSdkCallback>(
                  stream: _stream,
                  builder: (context, snapshot) {
                    if (snapshot.hasData) {
                      switch (snapshot.data!.result) {
                        case TcSdkCallbackResult.success:
                          return MaterialButton(
                              color: Colors.green,
                              child: Text(
                                "Go to OAuth Result",
                                style: TextStyle(color: Colors.white),
                              ),
                              onPressed: () {
                                // 处理成功回调
                              });
                        case TcSdkCallbackResult.failure:
                          return Text(
                              "${snapshot.data!.error!.code} : ${snapshot.data!.error!.message}");
                        case TcSdkCallbackResult.verification:
                          return Text("Verification Required!!");
                        default:
                          return Text("Invalid result");
                      }
                    } else
                      return Text("");
                  }),
            ],
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    _stream?.cancel();
    super.dispose();
  }
}

示例2:验证所有用户(包括非Truecaller用户)

以下是验证所有用户的完整示例代码:

import 'package:flutter/material.dart';
import 'package:truecaller_sdk/truecaller_sdk.dart';
import 'package:uuid/uuid.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late Stream<TcSdkCallback>? _stream;
  late String? codeVerifier;

  @override
  void initState() {
    super.initState();
    _stream = TcSdk.streamCallbackData;
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Truecaller SDK example'),
        ),
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              MaterialButton(
                onPressed: () async {
                  await TcSdk.initializeSDK(sdkOption: TcSdkOptions.OPTION_VERIFY_ALL_USERS);
                  bool isUsable = await TcSdk.isOAuthFlowUsable;

                  if (isUsable) {
                    String oAuthState = Uuid().v1();
                    TcSdk.setOAuthState(oAuthState);
                    TcSdk.setOAuthScopes(['profile', 'phone', 'openid']);
                    
                    String? codeVerifier = await TcSdk.generateRandomCodeVerifier;
                    String? codeChallenge = await TcSdk.generateCodeChallenge(codeVerifier);

                    if (codeChallenge != null) {
                      this.codeVerifier = codeVerifier;
                      TcSdk.setCodeChallenge(codeChallenge);
                      TcSdk.getAuthorizationCode;
                    } else {
                      final snackBar = SnackBar(content: Text("Device not supported"));
                      ScaffoldMessenger.of(context).showSnackBar(snackBar);
                      print("***Code challenge NULL***");
                    }
                  } else {
                    final snackBar = SnackBar(content: Text("Not Usable"));
                    ScaffoldMessenger.of(context).showSnackBar(snackBar);
                    print("***Not usable***");
                  }
                },
                child: Text(
                  "Initialize SDK & Get Authorization Code",
                  style: TextStyle(color: Colors.white),
                ),
                color: Colors.blue,
              ),
              Divider(
                color: Colors.transparent,
                height: 20.0,
              ),
              StreamBuilder<TcSdkCallback>(
                  stream: _stream,
                  builder: (context, snapshot) {
                    if (snapshot.hasData) {
                      switch (snapshot.data!.result) {
                        case TcSdkCallbackResult.success:
                          return MaterialButton(
                              color: Colors.green,
                              child: Text(
                                "Go to OAuth Result",
                                style: TextStyle(color: Colors.white),
                              ),
                              onPressed: () {
                                // 处理成功回调
                              });
                        case TcSdkCallbackResult.failure:
                          return Text(
                              "${snapshot.data!.error!.code} : ${snapshot.data!.error!.message}");
                        case TcSdkCallbackResult.verification:
                          return Column(
                            children: [
                              Text("Verification Required : "
                                  "${snapshot.data!.error != null ? snapshot.data!.error!.code : ""}"),
                              MaterialButton(
                                color: Colors.green,
                                onPressed: () async {
                                  await TcSdk.requestVerification(phoneNumber: "PHONE_NUMBER");
                                },
                                child: Text(
                                  "Do manual verification",
                                  style: TextStyle(color: Colors.white),
                                ),
                              )
                            ],
                          );
                        default:
                          return Text("Invalid result");
                      }
                    } else
                      return Text("");
                  }),
            ],
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    _stream?.cancel();
    super.dispose();
  }
}

自定义选项

您可以根据需要自定义SDK的行为和UI,例如设置语言、调整按钮颜色等。具体可以参考官方文档中的自定义选项

支持与帮助

如果您有任何技术或流程相关的问题,请通过支持渠道联系我们,以获得快速和专业的响应。

希望这些信息对您有所帮助!如果有任何问题或需要进一步的帮助,请随时提问。


更多关于Flutter通讯验证插件truecaller_sdk的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter通讯验证插件truecaller_sdk的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter项目中集成和使用truecaller_sdk进行通讯验证,你需要按照以下步骤进行。这些步骤包括添加依赖、配置Android和iOS平台、以及实现通讯验证功能。下面是一个详细的代码案例:

1. 添加依赖

首先,在你的pubspec.yaml文件中添加truecaller_sdk依赖:

dependencies:
  flutter:
    sdk: flutter
  truecaller_sdk: ^最新版本号  # 请替换为实际的最新版本号

然后运行flutter pub get来获取依赖。

2. 配置Android平台

android/app/src/main/AndroidManifest.xml文件中添加必要的权限和配置:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

    <application
        ... >
        <meta-data
            android:name="com.truecaller.sdk.API_KEY"
            android:value="你的Truecaller SDK API Key"/>
        ...
    </application>
</manifest>

确保替换你的Truecaller SDK API Key为你的实际API Key。

3. 配置iOS平台

ios/Runner/Info.plist文件中添加必要的配置(如果需要的话,具体配置请参考Truecaller SDK的iOS集成文档)。

4. 实现通讯验证功能

在你的Flutter代码中,你可以按照以下方式使用truecaller_sdk插件:

import 'package:flutter/material.dart';
import 'package:truecaller_sdk/truecaller_sdk.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String verificationStatus = '';

  @override
  void initState() {
    super.initState();
    _initializeTruecallerSDK();
  }

  Future<void> _initializeTruecallerSDK() async {
    try {
      // 初始化Truecaller SDK
      await TruecallerSdk.initialize(
        apiKey: '你的Truecaller SDK API Key',
        onVerificationCompleted: (result) {
          setState(() {
            verificationStatus = result ? 'Verification Successful' : 'Verification Failed';
          });
        },
        onError: (error) {
          setState(() {
            verificationStatus = 'Error: $error';
          });
        },
      );

      // 请求通讯验证
      await TruecallerSdk.startVerification(phoneNumber: '+1234567890'); // 替换为实际的电话号码
    } catch (e) {
      setState(() {
        verificationStatus = 'Initialization Error: $e';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Truecaller SDK Demo'),
        ),
        body: Center(
          child: Text(verificationStatus),
        ),
      ),
    );
  }
}

在这个示例中,我们初始化了Truecaller SDK,并请求了通讯验证。验证结果会通过回调函数onVerificationCompleted返回,你可以在UI中显示验证状态。

注意事项

  1. API Key:确保你已经在Truecaller开发者平台上注册并获取了API Key。
  2. 电话号码格式:电话号码应该使用国际格式(例如:+1234567890)。
  3. 权限处理:在实际应用中,你可能需要处理Android和iOS的权限请求,特别是读取电话状态的权限。

这个代码案例提供了一个基本的集成示例,你可以根据需要进行扩展和修改。

回到顶部