Flutter 第三方SDK集成友盟统计(亲测有效)

   题记
—— 执剑天涯,从你的点滴积累开始,所及之处,必精益求精,即是折腾每一天。

Flutter 第三方SDK集成友盟统计(亲测有效)

最近开发过程中,需要引入友盟进行统计服务。友盟统计还需要区分不同渠道的打开应用的情况,所以需要处理多渠道打包的问题。

Flutter中文网

Flutter

一、引入友盟统计
在工程的pubspec.yaml中引入插件

  // 在工程 pubspec.yaml 中加入 
  dependencies:
     umeng_common_sdk: ^1.2.3
    
导入及调用初始化友盟

import 'package:umeng_common_sdk/umeng_common_sdk.dart';

调用友盟统计

@override
  void initState() {
    super.initState();
    initPlatformState();
    UmengCommonSdk.initCommon('5e3f96f3cb23d2a070000048', '5e3f96f3cb23d2a070000048', 'Umeng');
    UmengCommonSdk.setPageCollectionModeManual();
  }

这里需要填写channel渠道名后续我们需要根据打包的渠道来设置。

二、flutter代码中获取渠道
Flutter命令工具增加了自定义参数的功能 --dart-define,可以用这个命令参数在打包或运行 App 时设置参数。

如:

flutter run --dart-define=CHANNEL=YYB
    
在lib/main.dart中定义变量配置,可以方便调用

/// 定义环境变量配置
class EnvironmentConfig {
  static const CHANNEL = String.fromEnvironment('CHANNEL');
}

在需要的地方调用获取渠道名

  String currentChannel = "";

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    // 获取CHANNEL 参数值
    String channel = EnvironmentConfig.CHANNEL;
    print("channel:${channel}");
    currentChannel = channel;
    setState(() {});
  }

显示渠道名

            Container(
              height: 136,
              width: 300,
              color: Colors.lightGreen,
              alignment: Alignment.center,
              child: Text(
                '当前渠道:${currentChannel}',
                style: TextStyle(fontSize: 12, color: Colors.white),
              ),
            ),

最终获得渠道显示效果图如下

三、android中gradle配置
我们需要在android/app/build.gradle中添加一下配置


/// 获取渠道参数使用,这里设置一下默认值
def dartEnvironmentVariables = [
        CHANNEL: 'guanfang-app',
]

if (project.hasProperty('dart-defines')) {
    dartEnvironmentVariables = dartEnvironmentVariables + project.property('dart-defines')
            .split(',')
            .collectEntries { entry ->
                def pair = new String(entry.decodeBase64(), 'UTF-8').split('=')
                [(pair.first()): pair.last()]
            }
}
 
在输出的apk中,添加对应渠道名,在android一下${dartEnvironmentVariables.CHANNEL}进行区分不同渠道的apk名称。

ext {
    publishName = 'AppDemoLab'
}

android {
    android.applicationVariants.all {variant ->
        variant.outputs.all {
            def buildTime = new Date().format('yyyyMMddHHmm')
            outputFileName = "${project.publishName}_${variant.versionName}_${variant.versionCode}_${buildTime}_${variant.buildType.name}_${dartEnvironmentVariables.CHANNEL}.apk"
        }
    }
}

打包与测试命令

# 调试例子1:设置渠道为应用宝。
flutter run --dart-define=CHANNEL=YYB

#打包例子1:打包应用宝渠道包
flutter build apk --dart-define=CHANNEL=YYB

可以是多个–dart-define,如:

#打包例子2:打包应用宝渠道包,DEBUG参数是Y
flutter build apk --dart-define=CHANNEL=YYB --dart-define=DEBUG=Y

四、apk.sh多渠道打包脚本
在脚本中定义了渠道channels=(YYB HUAWEI MI OPPO VIVO)

在工程目录下创建shell目录,将apk.sh放到shell目录下。
在工程目录下创建prod目录,prod目录下创建apk目录,用于存放打包的渠道apk文件

apk.sh多渠道打包脚本如下

#!/bin/sh

#---------------------请修改渠道数组----------------#
channels=(YYB HUAWEI MI OPPO VIVO)

#当前工程绝对路径
project_path=$(pwd)

#安卓包product文件夹路径
prod_path=${project_path}/prod/apk/
#Flutter打包生成的最初地址
release_path=${project_path}/build/app/outputs/apk/release/

clean_tips="执行flutter clean(默认:n) [ y/n ]"
echo $clean_tips
read  -t 5 is_clean
if [  ! -n "${is_clean}" ];then
    is_clean="n"
fi
while([[ $is_clean != "y" ]] && [[ $is_clean != "n" ]])
do
  echo "错误!只能输入[ y/n ] !!!"
  echo $clean_tips
  read is_clean
done

tips="请输入选择渠道(默认:0) [ ALL: 0 "
c_length=${#channels[@]};
for(( i=0; i<$c_length; i++)) do
  if (($i < $c_length-1 )); then
    tips="${tips}${channels[i]}: $((i+1)) "
  else
    tips="${tips}${channels[i]}: $((i+1)) ]"
  fi
done;

echo $tips
read  -t 5 number
if [  ! -n "${number}" ];then
    number=0
fi
while(( $number < "0" || $number > $c_length ))
do
  echo "错误!只能输入0到${c_length} !!!"
  echo $tips
  read number
done

#如果有product/apk文件夹则删除,然后再创建一个空文件夹
if [ -d ${prod_path} ]; then
  rm -rf ${prod_path}
fi
#创建目录
mkdir -p ${prod_path}

if [ ${is_clean} = "y" ];then
  echo "=============== 开始清理 ==============="
    flutter clean
fi

if (($number == 0 )); then
  echo "=============== 开始构建:全部渠道包 ==============="
  for(( i=0;i<${c_length};i++)) do
    echo "正在构建:${channels[$i]} 渠道包"
    flutter build apk --no-shrink --dart-define=CHANNEL=${channels[$i]}
    cp -R ${release_path}*.apk ${prod_path}
  done;
else
  echo "=============== 正在构建:${channels[$((number-1))]} 渠道包 ==============="
  flutter build apk --no-shrink --dart-define=CHANNEL=${channels[$((number-1))]}
  cp -R ${release_path}*.apk ${prod_path}
fi

#判断apk目录下是否有文件
if [ "$(ls -A $prod_path)" ]; then
  echo "=============== APK包已导出:$prod_path ==============="
  open $prod_path
else
  echo '=============== APK包导出失败 ==============='
  exit 1
fi
exit 0
 
查看脚本可以看出

控制是否执行flutter clean
输入是全部渠道打包
打包后的apk拷贝到prod/apk文件夹下。

通过cd切换到shell目录下,执行apk.sh脚本进行多渠道打包

./shell/papk.sh

在prod/apk目录下,可以看到打包的apk


参考:https://github.com/sugood/flutter_shell

五、更改友盟渠道
在文中,使用友盟时候,需要传递渠道名,我们通过EnvironmentConfig.CHANNEL拿到渠道名后作为参数传给友盟。
友盟即可根据渠道进行统计。

六、附录(完整的gradle配置)
android/build.gradle配置如下
buildscript {
    ext.kotlin_version = '1.7.10'
    repositories {
        maven { url "https://maven.aliyun.com/repository/google" }
        maven { url "https://maven.aliyun.com/repository/central" }
        maven { url "https://maven.aliyun.com/repository/jcenter" }
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:7.2.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

allprojects {
    repositories {
        maven { url "https://maven.aliyun.com/repository/google" }
        maven { url "https://maven.aliyun.com/repository/central" }
        maven { url "https://maven.aliyun.com/repository/jcenter" }
    }
}

rootProject.buildDir = '../build'
subprojects {
    project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
    project.evaluationDependsOn(':app')
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

 
android/app/build.gradle配置如下
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader('UTF-8') { reader ->
        localProperties.load(reader)
    }
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
    throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
    flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    flutterVersionName = '1.0'
}

def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

/// 获取渠道参数使用,这里设置一下默认值
def dartEnvironmentVariables = [
        CHANNEL: 'GuanFang',
]

if (project.hasProperty('dart-defines')) {
    dartEnvironmentVariables = dartEnvironmentVariables + project.property('dart-defines')
            .split(',')
            .collectEntries { entry ->
                def pair = new String(entry.decodeBase64(), 'UTF-8').split('=')
                [(pair.first()): pair.last()]
            }
}

ext {
    publishName = 'AppDemoLab'
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
    compileSdkVersion 34
    ndkVersion flutter.ndkVersion

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.example.flutter_app_demolab"
        // You can update the following values to match your application needs.
        // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
        minSdkVersion 21
        targetSdkVersion flutter.targetSdkVersion
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName

        ndk {
            abiFilters "armeabi-v7a", "arm64-v8a"
        }
    }

    buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig signingConfigs.debug
        }
    }

    android.applicationVariants.all {variant ->
        variant.outputs.all {
            def buildTime = new Date().format('yyyyMMddHHmm')
            outputFileName = "${project.publishName}_${variant.versionName}_${variant.versionCode}_${buildTime}_${variant.buildType.name}_${dartEnvironmentVariables.CHANNEL}.apk"
        }
    }
}

flutter {
    source '../..'
}
    
七、小结
flutter开发实战-实现多渠道打包及友盟统计(亲测有效),根据自身需求调整后亲测有效,可以根据渠道来做一些代码上的区分。

学习记录,每天不停进步。

### 回答1: Flutter是一种跨平台的移动应用开发框架,可以用于开发iOS和Android应用。在Flutter中实现微博分享可以通过集成第三方的微博SDK来实现。 首先,在pubspec.yaml文件中添加微博SDK的依赖: ``` dependencies: fluwx: ^x.x.x #微信开发包 umeng_sdk: ^x.x.x #统计SDK weibo_sdk: ^x.x.x #微博SDK ``` 然后,在Flutter的代码中,添加微博分享的逻辑。首先,用户需要先登录微博,获取到授权信息。可以使用微博SDK提供的登录接口来实现: ```dart import 'package:weibo_sdk/weibo_sdk.dart'; void loginWeibo() async { var response = await WeiboSDK.login(); if (response != null && response.isSuccess()) { // 授权成功 var accessToken = response.accessToken; var uid = response.uid; // 在这里可以进行微博分享的操作 } else { // 授权失败 } } ``` 在获取到授权信息后,就可以通过微博SDK提供的分享接口来实现微博分享: ```dart import 'package:weibo_sdk/weibo_sdk.dart'; void shareToWeibo() { var weiboContent = WeiboContent(); weiboContent.title = '分享标题'; weiboContent.description = '分享内容'; weiboContent.webpageUrl = '分享链接'; weiboContent.imageUrl = '分享图片链接'; WeiboSDK.shareToWeibo(weiboContent).then((response) { if (response != null && response.isSuccess()) { // 分享成功 } else { // 分享失败 } }); } ``` 通过上述的代码实现,就可以在Flutter中进行微博分享了。当用户点击分享按钮时,首先需要登录微博获取授权信息,然后再调用分享接口进行分享操作。使用微博SDK可以方便地实现微博分享功能,同时也提供了分享成功和失败的回调,方便开发者对分享结果进行处理。 ### 回答2: Flutter 是一种开源的移动应用程序开发框架,它能够帮助开发者用一套代码构建高效、美观的跨平台应用。在 Flutter 中,我们可以很方便地实现微博分享功能。 首先,我们需要引入 `flutter_weibo` 插件,这是一个与微博 API 交互的插件。我们可以在 `pubspec.yaml` 文件中添加依赖: ``` dependencies: flutter_weibo: ^1.0.0 ``` 然后,在我们的代码中导入该插件: ```dart import 'package:flutter_weibo/flutter_weibo.dart'; ``` 接下来,我们需要设置微博开放平台的相关信息,包括 App Key 和回调地址。我们可以在微博开放平台申请一个开发者账号,创建一个应用,然后获取这些信息。在我们的代码中,可以这样设置: ```dart Weibo.init('YOUR_APP_KEY', 'YOUR_REDIRECT_URL'); ``` 现在,我们就可以使用该插件来实现微博分享了。比如,我们可以创建一个按钮,点击该按钮时触发分享操作: ```dart FlatButton( onPressed: () { // 分享文本 Weibo.shareText('要分享的文本内容'); // 分享图片(本地图片或网络图片) Weibo.shareImage( image: 'http://example.com/image.jpg', description: '图片描述', ); // 分享网页链接 Weibo.shareWebPage( url: 'http://example.com/page', title: '网页标题', description: '网页描述', thumbnail: 'http://example.com/thumbnail.jpg', ); }, child: Text('点击分享到微博'), ); ``` 通过上述代码,我们可以实现微博分享的功能。用户点击按钮后,可以分享文本、图片或网页链接到微博上。当然,在实际开发中,我们还可以根据需求进行更多的定制和优化,以提供更好的用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值