Two days ago, I just learned the native Android Mobile communication TPNS and found that the Flutter_Plugin is also available. Today, I will try to support the Flutter.

Flutter TPNS

1. Basic access

1.1 Environment Configuration

To access the Flutter TPNS, plug-ins need to be installed and configured on both the Flutter and Android interfaces.

  • Flutter

Introduce tpNS_Flutter_plugin in project pubspec. Yaml under dependencies;

dependencies:
  flutter:
    sdk: flutter
  tpns_flutter_plugin:
    git:
      url: https://github.com/TencentCloud/TPNS-Flutter-Plugin
      ref: V1.0.7
Copy the code
  • Android

In the app build.gradle file, configure the ID and KEY and the supported.so library.

defaultConfig {
    applicationId "com.ace.plugin.flutter_app07"
    minSdkVersion 16
    targetSdkVersion 28
    versionCode flutterVersionCode.toInteger()
    versionName flutterVersionName
    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    ndk {
        abiFilters 'armeabi', 'armeabi-v7a', 'x86', 'x86_64', 'mips', 'mips64', 'arm64-v8a', 'arm6'
    }
    manifestPlaceholders = [
        XG_ACCESS_ID : "1500018481",
        XG_ACCESS_KEY : "AW8Y2K3KXZ38",
    ]
}
Copy the code

1.2 Method Usage

According to the introduction of the official website, the side dish has tried some common API methods, which are mainly divided into three APIS: application, account and tag. There is no application account and tag module in the side dish business, so it has not been studied in depth yet.

  • Application Interface API
A. Register for push services

For service registration initialization, it can be directly initialized in the application initState() for the first time, or it can be initialized in a fixed location according to the business logic. The ID and KEY of the applied account need to be passed. After a successful registration, onRegisteredDone() is called back and the unique Token of the corresponding device is obtained.

XgFlutterPlugin().startXg("1500018481", "AW8Y2K3KXZ38"); // Register callback to XgFlutterPlugin().addeventhandler (onRegisteredDone: (String msg) async { print("HomePage -> onRegisteredDone -> $msg"); _showDialog(' registered successfully ', MSG); });Copy the code

B. Log out of the push service

Service logout method can be processed by stopXg() and callback listening at unRegistered;

XgFlutterPlugin().stopXg(); // Logout callback XgFlutterPlugin().addeventhandler (unRegistered: (String msg) async { print("HomePage -> unRegistered -> $msg"); });Copy the code
C. Device push ID

The unique device identifier can be obtained after successful registration and initialization, or the unique Token can be obtained through xgFlutterPlugin.xgToken.

Future<void> getTPNSToken(title) async { try { String xgToken = await XgFlutterPlugin.xgToken; print('HomePage -> getTPNSToken -> $xgToken'); _showDialog(title, xgToken); } catch (e) { print(e.toString()); }}Copy the code

D. Report the number of Angle marks

For desktop ICONS, in the notification class messagehuaweimilletAfter the permission is enabled, the notification will be updated by the desktop icon. whileTPNSTo provide thesetBadge()Only in theiOSEnvironment support, forAndroidUnder the environment of equipment support passthrough type or those of other manufacturers can get through itFlutterNativeCommunication by native implementation;

E. the SDK version

TPNS SDK version by XgFlutterPlugin. XgSdkVersion access;

Future<void> getTPNSSDKVersion(title) async { try { String sdkVersion = await XgFlutterPlugin.xgSdkVersion; print('HomePage -> getTPNSSDKVersion -> $sdkVersion'); _showDialog(title, sdkVersion); } catch (e) { print(e.toString()); }}Copy the code

  • Account Interface API

TPNS provides personalized services, such as account binding and unbinding, which can be processed according to specific business logic.

String inputStr = "ACE_Flutter"; // Set the account XgFlutterPlugin().setAccount(inputStr, accountType.unknown); // Unbind the account XgFlutterPlugin().deleteAccount(inputStr, accountType.unknown); // Clear the account XgFlutterPlugin().cleanAccounts(); XgFlutterPlugin().addEventHandler( xgPushDidBindWithIdentifier: (String msg) async { print("HomePage -> xgPushDidBindWithIdentifier -> $msg"); _showDialog(' bind tag $inputStr', MSG); }, xgPushDidUnbindWithIdentifier: (String msg) async { print("HomePage -> xgPushDidUnbindWithIdentifier -> $msg"); _showDialog(' unbind account ', MSG); }, xgPushDidClearAllIdentifiers: (String msg) async { print("HomePage -> xgPushDidClearAllIdentifiers -> $msg"); _showDialog(' clear all accounts ', MSG); })Copy the code
  • Label Interface API

The user tag function of TPNS is relatively powerful, which can be targeted to push geo-fencing or tag distribution; TPNS provides functions such as binding and unbinding labels, updating and cleaning labels to facilitate targeted data push.

String inputStr = "ACE_Flutter"; // Bind the tag XgFlutterPlugin().addtags ([inputStr]); XgFlutterPlugin().deletetags ([inputStr]); // Update the tag XgFlutterPlugin().settags ([inputStr]); // Clear the tag XgFlutterPlugin().cleantags ();Copy the code

2. Notification messages

In the previous article, Xiaolai introduced the TPNS message publishing background, which is consistent regardless of the way of integration;

2.1 Reception & Presentation

Notification class Push will automatically display notifications after receiving messages when the permission is enabled on the device, which is implemented by TPNS SDK and consistent with the native one. The title and content of notification class Push can only be published through the message background and cannot be changed freely. The notifier Push receive through onReceiveNotificationResponse callback () method to monitor;

XgFlutterPlugin().addEventHandler( onReceiveNotificationResponse: (Map<String, dynamic> msg) async { print("HomePage -> onReceiveNotificationResponse -> $msg"); _showDialog(' notification class message received ', msg.toString()); });Copy the code

2.2 click

Notification class Push message click is callback through the xgPushClickAction() method, after which the business logic can be processed according to the information returned by the message; In order to adapt to other Push types, the operation after clicking has been adjusted. By default, the app is started. Usually, Json is added in [Additional Parameters] for data analysis and later business processing.

XgFlutterPlugin().addEventHandler( xgPushClickAction: (Map<String, dynamic> msg) async { print("HomePage -> xgPushClickAction -> $msg"); _showDialog(' notifying class message click ', msg.toString()); });Copy the code

3. Transparent transmission of messages

    Passthrough PushCompared with theNotify the class PushIt’s a little more complicated,TPNSProvided onlyPassthrough PushReceive, will not proceedNotificationNotice display; So the side dishes passFlutter-NativeMessage communication processing; Among themNotificationThe display click is requiredNativeTo cooperate with the treatment;

3.1 the receiving

The pass-through Push class uses onReceiveMessage() for callback listening for message receiving; After that, side dish creates a MethodChannel to pass messages to Android Native;

XgFlutterPlugin().addEventHandler( onReceiveMessage: (Map<String, dynamic> msg) async { print("HomePage -> onReceiveMessage -> $msg"); _showDialog(' pass-through message receive ', msg.toString()); await methodChannel .invokeMethod('tpns_extras', MSG ['customMessage']).then((val) {print("HomePage -> $val"); if (val ! = null) {_showDialog(' pass-through message click ', val); }}); });Copy the code

3.2 show

When the Flutter terminal receives a transparently transmitted Push message, it sends the MethodChannel to Android Native, and the Native terminal parses the corresponding parameters for Notification display.

@Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine); new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), "com.ace.plugin.flutter_app/tpns_notification").setMethodCallHandler(new MethodChannel.MethodCallHandler() { @Override public void onMethodCall(MethodCall call, MethodChannel.Result result) { if (call ! = null && call.method.equals("tpns_extras")) { setNotification(MainActivity.this, call.arguments.toString()); mResult = result; } else { result.notImplemented(); }}}); }Copy the code

3.3 click

After presenting the Notification on the Native side, the side dish tries two methods. The first is to communicate the message to the Flutter side via a new BasicMessage echannel. The second is a result callback via the MethodChannel sent by the Flutter. Although the second method is used for side dishes, they are more inclined to the first one, and each event is more specific;

After receiving the message sent or returned by Native, the Flutter side is free to process the business logic.

private void setNotification(Context context, String extras) { NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel("ace_push", "ace_push_name", NotificationManager.IMPORTANCE_HIGH); if (notificationManager ! = null) { notificationManager.createNotificationChannel(channel); } } int notificationId = new java.util.Random().nextInt(1000); //Intent intent = new Intent(MainActivity.this, TPNSNotificationReceiver.class); //PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 101, intent, 102); Intent intent = new Intent(context, MainActivity.class); intent.putExtra("push_extras", extras); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(context, notificationId, intent, PendingIntent.FLAG_CANCEL_CURRENT); JSONObject json = JSONObject.parseObject(extras); String extrasStr = json.getString("extras"); json = JSONObject.parseObject(extrasStr); String title = json.getString("title"); String desc = json.getString("desc"); Notification notification = new NotificationCompat.Builder(context, "ace_push").setContentTitle(title) .setContentText(desc) .setContentIntent(pendingIntent) .setWhen(System.currentTimeMillis()) .setSmallIcon(R.mipmap.ic_launcher) .setAutoCancel(true) .build(); notificationManager.notify(notificationId, notification); }Copy the code

3.4 Precautions

The page that is passed in the PendingIntent is still the MainActivity, which can launch a special transit page according to the specific business logic. FLAG_ACTIVITY_NEW_TASK so notice that the data is received through onNewIntent;

@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); if (intent ! = null && intent.getExtras() ! = null && intent.getExtras().containsKey("push_extras")) { String extras = intent.getStringExtra("push_extras"); if (mResult ! = null) { mResult.success(extras); }}}Copy the code

Flutter TPNS case source code


Many advanced methods in Flutter TPNS have not been tried yet, only the most basic notification class and transparent transmission class Push receiving display click, etc. If there is a mistake, please guide!

Source: Young Monk Atze