feat(mobile-next): 导入官方 openim-flutter-demo 固定基线 3.8.3-patch.3 并完成双构建

- 上游: github.com/OpenIMSDK/openim-flutter-demo tag 3.8.3-patch.3
  commit b3dfdb1e8aaeaaf6f0793e10cadd20d5c184a31f
- 并行目录 mobile-next/ 原样导入(含 LICENSE),不覆盖现网 mobile/
- 锁定 Flutter 3.24.5 / Dart 3.5.4 / JDK 17 / Gradle 7.6.3 / AGP 7.3.1
- 实测 Android debug 与 release 构建均成功(见 docs/mobile-next-baseline-import.md)
- 本提交可单独回退:git revert 1db1229(重写前)

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
编码工程师
2026-08-19 15:24:33 +08:00
co-authored by multica-agent
parent fa8584a73f
commit 8046ec7483
767 changed files with 57658 additions and 0 deletions
@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 7e9793dee1b85a243edd0e06cb1658e98b077561
channel: stable
project_type: plugin
@@ -0,0 +1,3 @@
## 0.0.1
* TODO: Describe initial release.
@@ -0,0 +1 @@
TODO: Add your license here.
@@ -0,0 +1,5 @@
# flutter_openim_live_alert
#### 仅支持Android端,当app处于后台收到音视频通话邀请,这时候会在桌面弹窗一个接听对话框。
@@ -0,0 +1,4 @@
include: package:flutter_lints/flutter.yaml
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
@@ -0,0 +1,2 @@
#Thu Jan 02 10:14:31 HKT 2025
gradle.version=8.9
@@ -0,0 +1,41 @@
group 'io.openim.live.alert.flutter_openim_live_alert'
version '1.0'
buildscript {
repositories {
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
}
}
rootProject.allprojects {
repositories {
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
google()
mavenCentral()
}
}
apply plugin: 'com.android.library'
android {
compileSdkVersion 31
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
minSdkVersion 16
}
}
@@ -0,0 +1 @@
rootProject.name = 'flutter_openim_live_alert'
@@ -0,0 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.openim.live.alert.flutter_openim_live_alert">
<uses-permission android:name="android.permission.REORDER_TASKS" />
</manifest>
@@ -0,0 +1,95 @@
package io.openim.live.alert.flutter_openim_live_alert;
import android.app.Activity;
import android.content.Context;
import androidx.annotation.NonNull;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.openim.live.alert.flutter_openim_live_alert.services.CallService;
import io.openim.live.alert.flutter_openim_live_alert.utils.Utils;
/**
* FlutterOpenimLiveAlertPlugin
*/
public class FlutterOpenimLiveAlertPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
public static MethodChannel channel;
private Context context;
private Activity activity;
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
context = flutterPluginBinding.getApplicationContext();
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "flutter_openim_live_alert");
channel.setMethodCallHandler(this);
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
switch (call.method) {
case "showLiveAlert":
String title = call.argument("title");
String rejectText = call.argument("rejectText");
String acceptText = call.argument("acceptText");
CallService.startService(activity, title, rejectText, acceptText);
break;
case "closeLiveAlert":
CallService.stopService(activity);
break;
case "closeLiveAlertAndMoveTaskToFront": {
CallService.stopService(activity);
String packageName = call.argument("packageName");
String activityName = call.argument("activityName");
if (null == packageName) {
packageName = activity.getPackageName();
}
if (null == activityName) {
activityName = packageName + ".MainActivity";
}
Utils.moveTaskToFront(activity, activity.getPackageName(), activityName);
break;
}
default:
result.notImplemented();
break;
}
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
channel.setMethodCallHandler(null);
activity = null;
context = null;
}
@Override
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
activity = binding.getActivity();
}
@Override
public void onDetachedFromActivityForConfigChanges() {
activity = null;
}
@Override
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
activity = binding.getActivity();
}
@Override
public void onDetachedFromActivity() {
activity = null;
}
}
@@ -0,0 +1,128 @@
package io.openim.live.alert.flutter_openim_live_alert.services;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.os.Build;
import android.os.IBinder;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.Nullable;
import io.openim.live.alert.flutter_openim_live_alert.FlutterOpenimLiveAlertPlugin;
import io.openim.live.alert.flutter_openim_live_alert.R;
public class CallService extends Service {
private WindowManager mWindowManager;
private View mFloatingView;
private TextView mTitleView;
private Button mRejectButton;
private TextView mAcceptButton;
private final Point szWindow = new Point();
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
// init WindowManager
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
getWindowManagerDefaultDisplay();
// Init LayoutInflater
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
// Inflate the floating view layout we created
mFloatingView = inflater.inflate(R.layout.call, null);
mTitleView = mFloatingView.findViewById(R.id.tv_title);
mRejectButton = mFloatingView.findViewById(R.id.btn_reject);
mAcceptButton = mFloatingView.findViewById(R.id.btn_accept);
mRejectButton.setOnClickListener(view -> {
FlutterOpenimLiveAlertPlugin.channel.invokeMethod("reject", null);
});
mAcceptButton.setOnClickListener(view -> {
FlutterOpenimLiveAlertPlugin.channel.invokeMethod("accept", null);
});
// Add the view to the window.
WindowManager.LayoutParams params;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
} else {
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
}
// Specify the view position
params.gravity = Gravity.TOP | Gravity.CENTER;
// Initially view will be added to top-left corner, you change x-y coordinates according to your need
params.x = 0;
params.y = 20;
// Add the view to the window
mWindowManager.addView(mFloatingView, params);
}
private void getWindowManagerDefaultDisplay() {
mWindowManager.getDefaultDisplay().getSize(szWindow);
}
@Override
public void onDestroy() {
super.onDestroy();
if (mFloatingView != null) {
mWindowManager.removeView(mFloatingView);
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String title = intent.getStringExtra("title");
String rejectText = intent.getStringExtra("rejectText");
String acceptText = intent.getStringExtra("acceptText");
if (null != title) {
mTitleView.setText(title);
}
if (null != rejectText) {
mRejectButton.setText(rejectText);
}
if (null != acceptText) {
mAcceptButton.setText(acceptText);
}
return START_STICKY;
}
public static void startService(Context activity, String title, String rejectText, String acceptText) {
Intent intent = new Intent(activity, CallService.class);
intent.putExtra("title", title);
intent.putExtra("rejectText", rejectText);
intent.putExtra("acceptText", acceptText);
activity.startService(intent);
}
public static void stopService(Context activity) {
Intent intent = new Intent(activity, CallService.class);
activity.stopService(intent);
}
}
@@ -0,0 +1,79 @@
package io.openim.live.alert.flutter_openim_live_alert.utils;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import java.util.List;
public class Utils {
public static boolean isInstalled(Context context, String packageName) {
try {
final PackageManager packageManager = context.getPackageManager();
// 获取所有已安装程序的包信息
List<PackageInfo> infoList = packageManager.getInstalledPackages(0);
for (int i = 0; i < infoList.size(); i++) {
if (infoList.get(i).packageName.equalsIgnoreCase(packageName))
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public static boolean isRunningForeground(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (null != activityManager) {
List<ActivityManager.RunningAppProcessInfo> appProcessInfos = activityManager.getRunningAppProcesses();
// 枚举进程
for (ActivityManager.RunningAppProcessInfo appProcessInfo : appProcessInfos) {
if (appProcessInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
if (appProcessInfo.processName.equals(context.getApplicationInfo().processName)) {
return true;
}
}
}
}
return false;
}
public static void moveTaskToFront(Context context, String packageName, String activityName) {
//如果APP是在后台运行
if (!isRunningForeground(context)) {
//获取ActivityManager
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (null != activityManager) {
//获得当前运行的task
List<ActivityManager.RunningTaskInfo> taskList = activityManager.getRunningTasks(Integer.MAX_VALUE);
for (ActivityManager.RunningTaskInfo rti : taskList) {
//找到当前应用的task,并启动task的栈顶activity,达到程序切换到前台
if (rti.topActivity.getPackageName().equals(packageName)) {
activityManager.moveTaskToFront(rti.id, 0);
// return;
}
}
}
//若没有找到运行的task,用户结束了task或被系统释放,则重新启动
if (null != activityName) {
startActivity(context, activityName);
}
}
}
public static void startActivity(Context context, String activityName) {
try {
Class<?> clazz = Class.forName(activityName);
Intent intent = new Intent(context, clazz);
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intent);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/accept_button_nor" android:state_pressed="true" />
<item android:drawable="@drawable/accept_button_sel" />
</selector>
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#802be2a2" />
<stroke
android:width="1dp"
android:color="#802be2a2" />
<corners android:radius="6dp" />
</shape>
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#2be2a2" />
<stroke
android:width="1dp"
android:color="#2be2a2" />
<corners android:radius="6dp" />
</shape>
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 背景颜色 -->
<solid android:color="#b0000000" />
<!-- 边框线 -->
<stroke
android:width="1dp"
android:color="#b0000000" />
<!-- 圆角 -->
<corners android:radius="5dp" />
</shape>
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/reject_button_nor" android:state_pressed="true" />
<item android:drawable="@drawable/reject_button_sel" />
</selector>
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#40FB4A42" />
<stroke
android:width="1dp"
android:color="#40FB4A42" />
<corners android:radius="6dp" />
</shape>
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FB4A42" />
<stroke
android:width="1dp"
android:color="#FB4A42" />
<corners android:radius="6dp" />
</shape>
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/call_background"
android:orientation="vertical"
android:padding="15dp">
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:text="来电提示..."
android:textColor="#ffffff"
android:textSize="16sp" />
<Button
android:id="@+id/btn_reject"
android:layout_width="80dp"
android:layout_height="40dp"
android:layout_below="@+id/tv_title"
android:layout_marginTop="15dp"
android:layout_marginEnd="10dp"
android:layout_toStartOf="@+id/btn_accept"
android:background="@drawable/reject_button"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:text="拒绝"
android:textColor="#ffffff"
android:textSize="12sp" />
<Button
android:id="@+id/btn_accept"
android:layout_width="80dp"
android:layout_height="40dp"
android:layout_alignTop="@+id/btn_reject"
android:layout_alignParentEnd="true"
android:background="@drawable/accept_button"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:text="接听"
android:textColor="#ffffff"
android:textSize="12sp" />
</RelativeLayout>
</FrameLayout>
@@ -0,0 +1,63 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/services.dart';
class FlutterOpenimLiveAlert {
static const MethodChannel _channel = MethodChannel('flutter_openim_live_alert');
static Future? showLiveAlert({String? title, String? rejectText, String? acceptText}) async {
if (Platform.isAndroid) {
return _channel.invokeMethod('showLiveAlert', {
'title': title,
'rejectText': rejectText,
'acceptText': acceptText,
});
}
return null;
}
static Future? closeLiveAlert() async {
if (Platform.isAndroid) {
return _channel.invokeMethod('closeLiveAlert');
}
return null;
}
static Future? closeLiveAlertAndMoveTaskToFront({
String? activityName,
String? packageName,
}) async {
if (Platform.isAndroid) {
return _channel.invokeMethod('closeLiveAlertAndMoveTaskToFront', {
'activityName': activityName,
'packageName': packageName,
});
}
return null;
}
static buttonEvent({
Function()? onReject,
Function()? onAccept,
String? activityName,
}) {
if (Platform.isAndroid) {
_channel.setMethodCallHandler((call) async {
switch (call.method) {
case 'reject':
onReject?.call();
closeLiveAlert();
break;
case 'accept':
onAccept?.call();
closeLiveAlertAndMoveTaskToFront(
activityName: activityName,
);
break;
}
return null;
});
}
}
}
@@ -0,0 +1,205 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.18.0"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1"
url: "https://pub.dev"
source: hosted
version: "3.0.2"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
url: "https://pub.dev"
source: hosted
version: "10.0.5"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
url: "https://pub.dev"
source: hosted
version: "3.0.0"
matcher:
dependency: transitive
description:
name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
url: "https://pub.dev"
source: hosted
version: "0.12.16+1"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev"
source: hosted
version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
url: "https://pub.dev"
source: hosted
version: "1.15.0"
path:
dependency: transitive
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.dev"
source: hosted
version: "1.9.0"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.2"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
url: "https://pub.dev"
source: hosted
version: "0.7.2"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
url: "https://pub.dev"
source: hosted
version: "14.2.5"
sdks:
dart: ">=3.3.0 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54"
@@ -0,0 +1,64 @@
name: flutter_openim_live_alert
description: A new Flutter project.
version: 0.0.1
homepage:
publish_to: none
environment:
sdk: ">=2.16.1 <4.0.0"
flutter: ">=1.17.0"
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^3.0.1
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# This section identifies this Flutter project as a plugin project.
# The 'pluginClass' and Android 'package' identifiers should not ordinarily
# be modified. They are used by the tooling to maintain consistency when
# adding or updating assets for this project.
plugin:
platforms:
android:
package: io.openim.live.alert.flutter_openim_live_alert
pluginClass: FlutterOpenimLiveAlertPlugin
# To add assets to your plugin package, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
#
# For details regarding assets in packages, see
# https://flutter.dev/assets-and-images/#from-packages
#
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# To add custom fonts to your plugin package, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts in packages, see
# https://flutter.dev/custom-fonts/#from-packages