Действия Flutter Live не отображаются на экране блокировки или на динамическом островеIOS

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

Сообщение 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 ... mic-island
Ответить

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

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

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

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

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