Действия Flutter Live не отображаются на экране блокировки или на динамическом острове (ActivityKit + плагин live_activiIOS

Программируем под IOS
Ответить
Anonymous
 Действия Flutter Live не отображаются на экране блокировки или на динамическом острове (ActivityKit + плагин live_activi

Сообщение Anonymous »

Я пытаюсь отобразить Live Activity + Dynamic Island в своем приложении Flutter с помощью плагина live_activities.
Простое Live Activity отображается правильно, но когда я переключился на более подробный макет Live Activity, на экране блокировки ничего не появляется, или Dynamic Island не вызывает ошибок от Flutter.
Рабочий код:
MineAppWidgetLiveActivity.swift
import ActivityKit
import WidgetKit
import SwiftUI

// 1. ATTRIBUTES
struct LiveActivitiesAppAttributes: ActivityAttributes, Identifiable {
public struct ContentState: Codable, Hashable {
var score: String
}

var matchName: String
}

extension LiveActivitiesAppAttributes {
func prefixedKey(_ key: String) -> String {
"\(id)_\(key)"
}
}

let sharedDefault = UserDefaults(suiteName: "group.com.example.appLiveActivitytest")!

struct MineAppWidgetLiveActivity: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: LiveActivitiesAppAttributes.self) { context in
VStack {
Text("⚽ \(context.attributes.matchName)")
.font(.headline)
Text(context.state.score)
.font(.title)
}
.padding()
} dynamicIsland: { context in
DynamicIsland {
DynamicIslandExpandedRegion(.center) {
Text("Score: \(context.state.score)")
}
} compactLeading: {
Text("⚽")
} compactTrailing: {
Text(context.state.score)
} minimal: {
Text("⚽")
}
}
}
}


MineAppWidgetBundle.swift
import WidgetKit
import SwiftUI

@main
struct MineAppWidgetBundle: WidgetBundle {
var body: some Widget {
MineAppWidget()
MineAppWidgetLiveActivity()
}
}

**main.dart**

class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State createState() => _MyAppState();
}

class _MyAppState extends State {
final _liveActivitiesPlugin = LiveActivities();
String? _latestActivityId;

@override
void initState() {
_liveActivitiesPlugin.init(
appGroupId: 'group.com.example.appLiveActivitytest',
requestAndroidNotificationPermission: true,
);
super.initState();
}

Future start() async {
_latestActivityId = await _liveActivitiesPlugin.createActivity(
DateTime.now().millisecondsSinceEpoch.toString(),
{"score": "0 - 0"},
);
setState(() {});
}

Future update() async {
if (_latestActivityId == null) return;
final asd = await _liveActivitiesPlugin.updateActivity(_latestActivityId!, {
"score": "5 - 3",
});
log(asd.toString());
}

Future stop() async {
if (_latestActivityId == null) return;
_liveActivitiesPlugin.endAllActivities();
_latestActivityId = null;
setState(() {});
}

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text("Live Activities Test")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(onPressed: start, child: const Text("Start")),
ElevatedButton(onPressed: update, child: const Text("Update")),
ElevatedButton(onPressed: stop, child: const Text("Stop")),
Text("Activity: ${_latestActivityId ?? 'None'}"),
],
),
),
),
);
}
}


код ниже не работает
main.dart

class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State createState() => _MyAppState();
}

class _MyAppState extends State {
final _liveActivitiesPlugin = LiveActivities();

String? _latestActivityId;

Timer? _timer;

double _currentProgress = 0.0;

@override
void initState() {
_liveActivitiesPlugin.init(
appGroupId: 'group.com.example.appLiveActivitytest',
requestAndroidNotificationPermission: true,
);

super.initState();
}

Future start() async {
try {
_currentProgress = 0.0;

final activityData = {
"status": "Preparing your order...",
"driverName": "Assigning...",
"estimatedTime": "1:00 PM",
"progress": 0.0,
};

_latestActivityId = await _liveActivitiesPlugin.createActivity(
"Burger King",
activityData,
);

setState(() {});

_timer?.cancel();
_timer = Timer.periodic(const Duration(seconds: 3), (timer) async {
if (_latestActivityId == null) {
timer.cancel();
return;
}

_currentProgress += 0.1;
if (_currentProgress >= 1.0) _currentProgress = 1.0;

final status = _currentProgress >= 1.0
? "Enjoy your meal!"
: _currentProgress >= 0.8
? "Arriving soon"
: _currentProgress >= 0.5
? "Driver picked up order"
: "Preparing your order...";

final updateData = {
"status": status,
"driverName": "Mike",
"estimatedTime": "12:55 PM",
"progress": _currentProgress,
};

await _liveActivitiesPlugin.updateActivity(
_latestActivityId!,
updateData,
);
log("Progress: $_currentProgress");

if (_currentProgress >= 1.0) {
stop();
timer.cancel();
}
});
} catch (e) {
log(e.toString());
}
}

Future stop() async {
_timer?.cancel();
if (_latestActivityId == null) return;

await _liveActivitiesPlugin.endAllActivities();

_latestActivityId = null;
_currentProgress = 0.0;
setState(() {});
}

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text("Delivery Tracker")),

body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,

children: [
if (_latestActivityId != null)
const Text(
"Order Active!",

style: TextStyle(
color: Colors.green,

fontWeight: FontWeight.bold,
),
),

const SizedBox(height: 20),

ElevatedButton.icon(
icon: const Icon(Icons.restaurant),

label: const Text("Place Order (Start)"),

onPressed: start,
),

const SizedBox(height: 10),

ElevatedButton.icon(
icon: const Icon(Icons.stop),

label: const Text("Delivered (Stop)"),

onPressed: stop,
),
],
),
),
),
);
}
}


MineAppWidgetBundle.swift
import WidgetKit
import SwiftUI

@main
struct MineAppWidgetBundle: WidgetBundle {
var body: some Widget {
MineAppWidget()
MineAppWidgetLiveActivity()
}
}

MineAppWidgetLiveActivity.swift
import ActivityKit
import WidgetKit
import SwiftUI

struct DeliveryAttributes: ActivityAttributes {
public struct ContentState: Codable, Hashable {
var status: String
var driverName: String
var estimatedTime: String
var progress: Double
}

var restaurantName: String
}

struct MineAppWidgetLiveActivity: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: DeliveryAttributes.self) { context in

VStack(alignment: .leading) {
HStack {
Image(systemName: "fork.knife.circle.fill")
.foregroundColor(.orange)
.font(.title)

VStack(alignment: .leading) {
Text(context.attributes.restaurantName)
.font(.headline)
.foregroundColor(.white)

Text(context.state.status)
.font(.subheadline)
.foregroundColor(.gray)
}

Spacer()

Text(context.state.estimatedTime)
.font(.title3)
.bold()
.foregroundColor(.white)
}
.padding(.bottom, 8)

ProgressView(value: context.state.progress, total: 1.0)
.tint(.orange)
.padding(.vertical, 4)

Text("Driver: \(context.state.driverName)")
.font(.caption)
.foregroundColor(.secondary)
}
.padding()
.activityBackgroundTint(Color.black.opacity(0.85))
.activitySystemActionForegroundColor(.white)

} dynamicIsland: { context in

DynamicIsland {
DynamicIslandExpandedRegion(.leading) {
Label(context.state.driverName, systemImage: "car.fill")
.foregroundColor(.orange)
}
DynamicIslandExpandedRegion(.trailing) {
Text(context.state.estimatedTime)
.font(.headline)
}
DynamicIslandExpandedRegion(.center) {
Text(context.attributes.restaurantName)
.font(.headline)
}
DynamicIslandExpandedRegion(.bottom) {
VStack {
ProgressView(value: context.state.progress, total: 1.0)
.tint(.orange)
Text(context.state.status)
.font(.caption)
.foregroundColor(.secondary)
}
}
} compactLeading: {
Image(systemName: "fork.knife")
} compactTrailing: {
Text(context.state.estimatedTime)
.font(.caption)
.bold()
} minimal: {
Image(systemName: "fork.knife")
}
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/798 ... activityki
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»