Flutter 实现安卓多渠道打包

为什么使用多渠道打包

统计与分析 应用打包成不同的版本,投放到不同的市场或平台。统计应用在各个市场的用户下载量、新增用户量等数据,有助于分析应用在不同市场的表现和用户喜好
推广与营销 针对不同的市场或用户群体进行定制化的推广和营销活动
风险管理 需要切换API环境或进行其他配置更改。多渠道打包可以帮助开发者更好地管理不同版本和配置,降低这种风险。
提高效率 多渠道打包方案可以实现快速打包,例如使用gradle变量动态替换或第三方公司的批量打包方案,可以大大提高打包效率,节省开发者的时间。

动态渠道名称变量

xml 复制代码
<!--value的值填写渠道名称,例如yingyongbao。这里设置动态渠道名称变量-->
<meta-data android:value="xiaomi" android:name="UMENG_CHANNEL"/>
<!--<meta-data android:value="${UMENG_CHANNEL_VALUE}" android:name="UMENG_CHANNEL"/>-->

productFlavors 配置渠道

ini 复制代码
/*配置渠道*/
productFlavors {
    yingyongbao  {
        manifestPlaceholders = [UMENG_CHANNEL_VALUE: "yingyongbao"]
    }
    oppo  {
        manifestPlaceholders = [UMENG_CHANNEL_VALUE: "oppo"]
    }
}

flavorDimensions配置

如果不配置执行多渠道打包命令时会有如下异常:

* 复制代码
A problem occurred evaluating root project 'android'.
> A problem occurred configuring project ':app'.
   > com.android.builder.errors.EvalIssueException: All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com/r/tools/flavorDimensions-missing-error-message.html

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Get more help at https://help.gradle.org

读取清单文件下的渠道名称

kotlin 复制代码
class MainActivity: FlutterActivity() {

    private val CHANNEL = "channel.flutter.dev"

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
            .setMethodCallHandler { call: MethodCall, result: MethodChannel.Result ->
                //与Flutter Client invokeMethod调用字符串标识符匹配
                if (call.method == "channelMetaValue") {
                    val channelValue: String = channelMetaValue()
                    //initBlueTooth为后面安卓端需要调取的方法
                    result.success(channelValue)
                } else {
                    result.notImplemented()
                }
            }
    }

    private fun channelMetaValue(): String {
        val pm: PackageManager = packageManager
        var channel: String = "";
        try {
            val info: ApplicationInfo = pm.getApplicationInfo(getPackageName(),
                PackageManager.GET_META_DATA)
            channel = info.metaData.getString("UMENG_CHANNEL").toString()
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }
        return channel;
    }
}

Flutter工程获取渠道名称

less 复制代码
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late var channel = _channelValue();

  String _channelValue() {
    return '${'这里显示渠道名称'}\n';
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              channel,
              style: Theme.of(context).textTheme.headlineMedium,
            ),
            GestureDetector(
              onTap: () async {
                channel = await channelName();
                setState(() {});
              },
              child: const Text(
                '\n获取渠道名称\n',
              ),
            )
          ],
        ),
      ),
    );
  }

  ///app当前市场
  ///android 例如:小米、华为、opppo
  ///ios - AppStore
  Future<String> channelName() async {
    String channel = '';
    if (Platform.isAndroid) {
      const platform = MethodChannel('channel.flutter.dev');
      channel = await platform.invokeMethod('channelMetaValue');
    } else if (Platform.isIOS) {
      channel = 'ios';
    }
    return channel;
  }
}

执行命令进行多渠道打包

多渠道打包案例

切换到分支flutter_multi_channel

相关推荐
Nayuta5 分钟前
字节跳动「移动 OS 部门」招聘安卓工程师,AI+OS 方向
android
00后程序员张31 分钟前
iOS 应用上架常见问题与解决方案,多工具组合的实战经验
android·ios·小程序·https·uni-app·iphone·webview
恋猫de小郭1 小时前
Flutter 小技巧之有趣的 UI 骨架屏框架 skeletonizer
android·前端·flutter
Kapaseker1 小时前
Kotlin 老手怎么写代码?
android·kotlin
张风捷特烈3 小时前
鸿蒙纪·Flutter卷#03 | 从配置证书到打包发布
android·flutter·harmonyos
技术liul14 小时前
使用安卓平板,通过USB数据线(而不是Wi-Fi)来控制电脑(版本1)
android·stm32·电脑
_祝你今天愉快16 小时前
Android FrameWork - 开机启动 & Init 进程 初探
android
2501_9160074716 小时前
iOS App 上架实战 从内测到应用商店发布的全周期流程解析
android·ios·小程序·https·uni-app·iphone·webview
TimeFine17 小时前
Android 邮件发送日志
android
杨过过儿17 小时前
【Task02】:四步构建简单rag(第一章3节)
android·java·数据库