Flutter移动分析与推送插件umeng_analytics_with_push的使用

Flutter移动分析与推送插件umeng_analytics_with_push的使用

友盟统计 (U-App) 与友盟分析 (U-Push) Flutter 插件。

容易集成的友盟分析和Push,集成分析只需两步,集成 Push 再加两步。

使用

要使用此插件,在 pubspec.yaml 文件中添加 umeng_analytics_with_push 作为依赖项。例如:

dependencies:
    umeng_analytics_with_push: ^0.2.1

该插件已遵循合规指南。

该插件只集成了分析和Push必须的依赖项,其他可选项依赖由使用者根据实际需求添加。比如 Crash, Push 厂商通道等,请参考 Example 添加。Push 厂商通道会根据依赖和配置自动初始化,请参考厂商Push配置。

记录事件

// 无参数记录事件
UmengAnalyticsWithPush.onEvent("app_startup");
// 或
// 参数
UmengAnalyticsWithPush.onEvent("app_startup", {
  "time": DateTime.now().toString() // 注意:这里使用 toString() 方法而不是 toISOString()
});
// 或
// 参数 + counter
UmengAnalyticsWithPush.onEvent("app_startup", {
  "time": DateTime.now().toString() // 注意:这里使用 toString() 方法而不是 toISOString()
}, 1);

获取 DeviceToken,集成 Push 时调用

final deviceToken = await UmengAnalyticsWithPush.deviceToken;

统计路由

import 'package:umeng_analytics_with_push/umeng_analytics_with_push.dart';

class App extends StatelessWidget {

  // ... 其他代码 

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorObservers: [UmengAnalyticsObserver(log: !kReleaseMode)],
      // ...
  }
}

其他 API

// 获取 OAID
final String oaid = await UmengAnalyticsWithPush.oaid;
// 获取 UTDID
final String utdid = await UmengAnalyticsWithPush.utdid;
// 用户登录
await UmengAnalyticsWithPush.onProfileSignIn("ID", "Provider");
// 用户登出
await UmengAnalyticsWithPush.onProfileSignOut();
// 获取测试设备信息
final String testInfo = await UmengAnalyticsWithPush.testDeviceInfo;
// 以下 API 在集成 Push 时可调用
// Alias
await UmengAnalyticsWithPush.putAlias("from", "I'm from flutter"); 
await UmengAnalyticsWithPush.addAlias("from", "I'm from flutter"); 
await UmengAnalyticsWithPush.removeAlias("from", "I'm from flutter"); 
// Tags
await UmengAnalyticsWithPush.addTags(["flutter_tag1", "flutter_tag2"]);
final List<String> tags = await UmengAnalyticsWithPush.getTags();
await UmengAnalyticsWithPush.removeTags(["flutter_tag1", "flutter_tag2"]);

配置

初始化

可在用户同意隐私协议后再调用该方法,建议每次都调用

await UmengAnalyticsWithPush.initialize();

Android

初始化
import com.auwx.umeng_analytics_with_push.UmengAnalyticsWithPush
import io.flutter.app.FlutterApplication

class App: FlutterApplication() {

    override fun onCreate() {
        super.onCreate()
        UmengAnalyticsWithPush.preinitial(
            this,
            // AppKey, secret, channel 也可配置在 AndroidManifest 中
            // Required here or AndroidManifest.application
            //   <meta-data android:name="UMENG_APPKEY" android:value="aaaaaaaaaaaaaaaaaa" />
            //   <meta-data android:name="UMENG_SECRET" android:value="aaaaaaaaaaaaaaaaaa" />
            //   <meta-data android:name="UMENG_CHANNEL" android:value="${CHANNEL}" />
            appKey = getString(R.string.umeng_app_key),
            secret = getString(R.string.umeng_secret),
            channel = BuildConfig.FLAVOR,
            enableLog = BuildConfig.DEBUG,
            // ... 其他参数    
        )
    }
}

进阶

配置厂商 Push 通道

厂商配置需要使用者手动添加,需要同时添加厂商通道的依赖并在 AndroidManifest 中配置相应的 id 才会生效。配置成功后插件会自动调用厂商 Push 的初始化。

app build.gradle
dependencies {
    // 以下配置请根据需求选择性添加
    // Umeng Push 厂商 SDK  https://developer.umeng.com/docs/67966/detail/98589
    // 小米 Push 通道
    implementation 'com.umeng.umsdk:xiaomi-push:4.9.1'
    implementation 'com.umeng.umsdk:xiaomi-umengaccs:1.2.8'
    // 华为 Push 通道
    implementation 'com.huawei.hms:push:6.1.0.300'
    implementation 'com.umeng.umsdk:huawei-umengaccs:1.3.6'
    // Vivo Push 通道
    implementation 'com.umeng.umsdk:vivo-push:3.0.0.4'
    implementation 'com.umeng.umsdk:vivo-umengaccs:1.1.6'
    // Meizu Push 通道
    implementation 'com.umeng.umsdk:meizu-push:4.1.4'
    implementation 'com.umeng.umsdk:meizu-umengaccs:1.1.5'
    // Oppo Push 通道
    implementation 'com.umeng.umsdk:oppo-push:3.0.0'
    implementation 'com.umeng.umsdk:oppo-umengaccs:1.0.8-fix'
}
AndroidManifest.xml
<manifest>
    <application android:name=".App">
        <!-- ** Umeng Start ** -->
        <!-- Required Here or UmengAnalyticsWithPush.preinitial() -->
        <meta-data
            android:name="UMENG_APPKEY"
            android:value="@string/umeng_app_key" />
        <!-- Channel ID 用来标识 App 的推广渠道,作为推送消息时给用户分组的一个维度。 -->
        <!-- Option your flavor name,
         in your build.gradle manifestPlaceholders = [UMENG_CHANNEL: ""]
         请参考 example app build.gradle
        -->
        <meta-data
            android:name="UMENG_CHANNEL"
            android:value="${UMENG_CHANNEL}" />
        <!-- Under tag is umeng_analysis_with_push plugin define -->
        <!-- Option if don't need push -->
        <meta-data
            android:name="UMENG_SECRET"
            android:value="@string/umeng_secret" />
        <!-- 以下为厂商推送配置,具体请参考 Umeng 官方文档 https://developer.umeng.com/docs/67966/detail/98589 -->
        <!-- 以下配置请根据需求选择性添加 -->
        <!-- huawei push 参数声明 -->
        <!-- huawei start Option -->
        <meta-data
            android:name="com.huawei.hms.client.appid"
            android:value="appid=000000000" />
        <!-- huawei end -->
        <!-- Vivo push 参数声明 -->
        <!-- Vivo start-->
        <meta-data
            android:name="com.vivo.push.app_id"
            android:value="000000000" />
        <meta-data
            android:name="com.vivo.push.api_key"
            android:value="aaaaaaaaaaaaaaaaaaaaaaaa" />
        <!-- Vivo end-->
        <!-- Oppo push 参数声明 -->
        <!-- Oppo start-->
        <!-- Under tag is umeng_analysis_with_push plugin define -->
        <meta-data
            android:name="com.oppo.push.app_key"
            android:value="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" />
        <meta-data
            android:name="com.oppo.push.app_secret"
            android:value="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" />
        <!-- Oppo end-->
        <!-- Meizu push 参数声明 https://developer.umeng.com/docs/67966/detail/98589#h1--push-4 -->
        <!-- Meizu start-->
        <!-- Under tag is umeng_analysis_with_push plugin define -->
        <meta-data
            android:name="com.meizu.push.app_id"
            android:value="aaaaaaaaaaaaaaaaaaa" />
        <meta-data
            android:name="com.meizu.push.app_key"
            android:value="aaaaaaaaaaaaaaaaaaaa" />
        <!-- Meizu end-->
        <!-- XiaoMi start-->
        <!-- Under tag is umeng_analysis_with_push plugin define -->
        <!-- Android 会将纯数字的 meta-data 识别为 Number 类型
        所有数字形式的 meta-data 请在加前缀 "\ " 或定义到 strings.xml 中在此处引用以识别为 String -->
        <meta-data
            android:name="com.xiaomi.push.app_id"
            android:value="\ 000000000000000000000" />
        <meta-data
            android:name="com.xiaomi.push.app_key"
            android:value="\ 0000000000000" />
        <!-- XiaoMi end-->
        <!-- ** Umeng End ** -->
    </application>
</manifest>

魅族接入

  1. 受魅族接入限制,魅族需要在包名目录下实现一个自定义 Receiver,继承自 MeizuPushReceiver,例如:
public class MeizuTestReceiver extends MeizuPushReceiver {
}
  1. 然后在 AndroidManifest.xml 中配置该 Receiver,例如:
<!-- 魅族 push 应用定义消息 receiver 声明 -->
<receiver android:name="${applicationId}.MeizuTestReceiver">
    <intent-filter>
        <!-- 接收 push 消息 -->
        <action android:name="com.meizu.flyme.push.intent.MESSAGE" />
        <!-- 接收 register 消息 -->
        <action android:name="com.meizu.flyme.push.intent.REGISTER.FEEDBACK" />
        <!-- 接收 unregister 消息 -->
        <action android:name="com.meizu.flyme.push.intent.UNREGISTER.FEEDBACK" />
        <!-- 兼容低版本 Flyme 3 推送服务配置 -->
        <action android:name="com.meizu.c2dm.intent.REGISTRATION" />
        <action android:name="com.meizu.c2dm.intent.RECEIVE" />

        <category android:name="${applicationId}" />
    </intent-filter>
</receiver>
  1. 请在 drawable 目录下添加一个图标,命名为 stat_sys_third_app_notify.png,建议尺寸 64px * 64px,图标四周留有透明。若不添加此图标,可能在部分魅族手机上无法弹出通知。

Crash 收集

自己在主工程添加依赖项即可

app build.gradle
dependencies {
    implementation 'com.umeng.umsdk:crash:0.0.5'
}

iOS

暂未支持

完整示例 Demo

以下是完整的示例代码:

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:umeng_analytics_with_push/umeng_analytics_with_push.dart';

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

class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _initialized;
  dynamic _errorOnInit;

  String _oaid;
  String _utdid;
  String _devToken;
  String _tags;

  bool get _hasDeviceToken => _devToken != null && _devToken != "Getting";

  [@override](/user/override)
  void initState() {
    super.initState();
    _initialized = false;
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorObservers: [UmengAnalyticsObserver(log: !kReleaseMode)],
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: ListView(
          padding: EdgeInsets.symmetric(vertical: 12, horizontal: 16),
          children: [
            ElevatedButton(
              onPressed: _initialized
                  ? null
                  : () {
                      UmengAnalyticsWithPush.initialize().then((_) {
                        setState(() {
                          _initialized = true;
                        });
                      }).catchError((e, s) {
                        setState(() {
                          _errorOnInit = e;
                        });
                      });
                    },
              child: Text("Init"),
            ),
            ElevatedButton(
              onPressed: () {
                UmengAnalyticsWithPush.oaid.then((oaid) {
                  setState(() {
                    _oaid = oaid ?? "null";
                  });
                }).catchError((e, s) {
                  setState(() {
                    _oaid = e.toString();
                  });
                });
              },
              child: Text("Got OAID"),
            ),
            ElevatedButton(
              onPressed: () {
                UmengAnalyticsWithPush.utdid.then((utdid) {
                  setState(() {
                    _utdid = utdid ?? "null";
                  });
                }).catchError((e, s) {
                  setState(() {
                    _utdid = e.toString();
                  });
                });
              },
              child: Text("Got UtdId"),
            ),
            ElevatedButton(
              onPressed: !_initialized
                  ? null
                  : () {
                      setState(() {
                        _devToken = "Getting";
                      });
                      UmengAnalyticsWithPush.deviceToken.then((dt) {
                        print("deviceToken: $dt");
                        setState(() {
                          _devToken = dt ?? "null";
                        });
                      }).catchError((e, s) {
                        print("deviceToken: $e" + (s != null ? "\n$s" : ""));
                        setState(() {
                          _devToken = e.toString();
                        });
                      });
                    },
              child: Text("Got DeviceToken"),
            ),
            ElevatedButton(
              onPressed: !_hasDeviceToken
                  ? null
                  : () async {
                      await UmengAnalyticsWithPush.addAlias("token", "flutter");
                      print("addAlias ok");
                    },
              child: Text("AddAlias type=\"token\", alias=\"flutter\""),
            ),
            ElevatedButton(
              onPressed: !_hasDeviceToken
                  ? null
                  : () async {
                      await UmengAnalyticsWithPush.putAlias("token", "flutter");
                      print("putAlias ok");
                    },
              child: Text("PutAlias type=\"token\", alias=\"flutter\""),
            ),
            ElevatedButton(
              onPressed: !_hasDeviceToken
                  ? null
                  : () async {
                      await UmengAnalyticsWithPush.removeAlias(
                          "token", "flutter");
                      print("removeAlias ok");
                    },
              child: Text("RemoveAlias type=\"token\", alias=\"flutter\""),
            ),
            ElevatedButton(
              onPressed: !_hasDeviceToken
                  ? null
                  : () {
                      UmengAnalyticsWithPush.getTags().then((tags) {
                        print("getTags: $tags");
                        setState(() {
                          _tags = tags?.join(", ") ?? "null";
                        });
                      }).catchError((e, s) {
                        print("getTags: $e" + (s != null ? "\n$s" : ""));
                        setState(() {
                          _tags = e.toString();
                        });
                      });
                    },
              child: Text("getTags \"flutter_tag1\", \"flutter_tag2\""),
            ),
            ElevatedButton(
              onPressed: !_hasDeviceToken
                  ? null
                  : () {
                      UmengAnalyticsWithPush.addTags(
                          ["flutter_tag1", "flutter_tag2"]);
                    },
              child: Text("AddTags \"flutter_tag1\", \"flutter_tag2\""),
            ),
            ElevatedButton(
              onPressed: !_hasDeviceToken
                  ? null
                  : () {
                      UmengAnalyticsWithPush.removeTags(
                          ["flutter_tag1", "flutter_tag2"]);
                    },
              child: Text("RemoveTags \"flutter_tag1\", \"flutter_tag2\""),
            ),
            SizedBox(height: 16),
            Text(_initialized ? "Initialized!" : "Please click Init"),
            if (_oaid != null) SizedBox(height: 12),
            if (_oaid != null) SelectableText("OAID: $_oaid"),
            if (_utdid != null) SizedBox(height: 12),
            if (_utdid != null) SelectableText("UTDID: $_utdid"),
            SizedBox(height: 12),
            SelectableText(_devToken == null
                ? "Please click Got DeviceToken"
                : "DeviceToken: $_devToken"),
            SizedBox(height: 12),
            if (_tags != null) SelectableText("Tags: $_tags"),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter移动分析与推送插件umeng_analytics_with_push的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter移动分析与推送插件umeng_analytics_with_push的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


umeng_analytics_with_push 是一个 Flutter 插件,用于集成友盟的移动分析和推送通知功能。它可以帮助开发者轻松地在 Flutter 应用中集成友盟的统计分析(如用户行为分析、事件追踪等)和推送通知服务。

以下是如何在 Flutter 项目中使用 umeng_analytics_with_push 插件的步骤:

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  umeng_analytics_with_push: ^1.0.0  # 请使用最新版本

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

2. 初始化插件

main.dart 文件中初始化友盟插件。通常,你需要在应用启动时进行初始化。

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 初始化友盟插件
  await UmengAnalyticsWithPush.init(
    androidAppKey: 'YOUR_ANDROID_APP_KEY',
    iosAppKey: 'YOUR_IOS_APP_KEY',
    channel: 'YOUR_CHANNEL',  // 渠道名称,如 "Google Play"
  );

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Demo Home Page'),
      ),
      body: Center(
        child: Text('Hello, Umeng Analytics with Push!'),
      ),
    );
  }
}

3. 配置 Android 和 iOS 项目

Android

android/app/build.gradle 文件中,确保以下配置:

android {
    ...
    defaultConfig {
        ...
        manifestPlaceholders = [
            UMENG_APPKEY: "YOUR_ANDROID_APP_KEY",
            UMENG_CHANNEL: "YOUR_CHANNEL"
        ]
    }
}

iOS

ios/Runner/Info.plist 文件中,添加以下配置:

<key>UMENG_APPKEY</key>
<string>YOUR_IOS_APP_KEY</string>
<key>UMENG_CHANNEL</key>
<string>YOUR_CHANNEL</string>

4. 使用事件统计

你可以在应用中使用 UmengAnalyticsWithPush 来记录用户事件:

UmengAnalyticsWithPush.event('button_click', label: 'Login Button');

5. 推送通知

友盟推送功能需要额外的配置和集成。你需要在友盟后台配置推送证书,并在应用中进行相应的处理。

获取设备 Token

String? deviceToken = await UmengAnalyticsWithPush.getDeviceToken();
print('Device Token: $deviceToken');

处理推送消息

你可以在 main.dart 中设置推送消息的回调:

UmengAnalyticsWithPush.setMessageHandler((Map<String, dynamic> message) {
  print('Received message: $message');
  // 处理推送消息
});
回到顶部