feat: Allow showing regular notifications
This commit is contained in:
parent
30ef477999
commit
6da35cd0ba
@ -10,6 +10,7 @@ import 'package:file_picker/file_picker.dart';
|
|||||||
|
|
||||||
/// The id of the notification channel.
|
/// The id of the notification channel.
|
||||||
const channelId = "me.polynom.moxplatform.testing3";
|
const channelId = "me.polynom.moxplatform.testing3";
|
||||||
|
const otherChannelId = "me.polynom.moxplatform.testing4";
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(const MyApp());
|
runApp(const MyApp());
|
||||||
@ -46,6 +47,11 @@ class MyAppState extends State<MyApp> {
|
|||||||
channelId,
|
channelId,
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
await MoxplatformPlugin.notifications.createNotificationChannel(
|
||||||
|
"Test notification channel for warnings",
|
||||||
|
otherChannelId,
|
||||||
|
false,
|
||||||
|
);
|
||||||
await MoxplatformPlugin.notifications.setI18n(
|
await MoxplatformPlugin.notifications.setI18n(
|
||||||
NotificationI18nData(
|
NotificationI18nData(
|
||||||
reply: "答える",
|
reply: "答える",
|
||||||
@ -190,6 +196,34 @@ class MyHomePage extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
child: const Text('Show messaging notification'),
|
child: const Text('Show messaging notification'),
|
||||||
),
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
MoxplatformPlugin.notifications.showNotification(
|
||||||
|
RegularNotification(
|
||||||
|
id: 4384,
|
||||||
|
title: 'Warning',
|
||||||
|
body: 'Something brokey',
|
||||||
|
channelId: otherChannelId,
|
||||||
|
icon: NotificationIcon.warning,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Text('Show warning notification'),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
MoxplatformPlugin.notifications.showNotification(
|
||||||
|
RegularNotification(
|
||||||
|
id: 4384,
|
||||||
|
title: 'Error',
|
||||||
|
body: "Lol, you're on your own",
|
||||||
|
channelId: otherChannelId,
|
||||||
|
icon: NotificationIcon.error,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Text('Show error notification'),
|
||||||
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
final result = await FilePicker.platform.pickFiles(
|
final result = await FilePicker.platform.pickFiles(
|
||||||
|
@ -57,6 +57,18 @@ public class Api {
|
|||||||
return errorList;
|
return errorList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum NotificationIcon {
|
||||||
|
WARNING(0),
|
||||||
|
ERROR(1),
|
||||||
|
NONE(2);
|
||||||
|
|
||||||
|
final int index;
|
||||||
|
|
||||||
|
private NotificationIcon(final int index) {
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum NotificationEventType {
|
public enum NotificationEventType {
|
||||||
MARK_AS_READ(0),
|
MARK_AS_READ(0),
|
||||||
REPLY(1),
|
REPLY(1),
|
||||||
@ -453,6 +465,156 @@ public class Api {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Generated class from Pigeon that represents data sent in messages. */
|
||||||
|
public static final class RegularNotification {
|
||||||
|
/** The title of the notification. */
|
||||||
|
private @NonNull String title;
|
||||||
|
|
||||||
|
public @NonNull String getTitle() {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(@NonNull String setterArg) {
|
||||||
|
if (setterArg == null) {
|
||||||
|
throw new IllegalStateException("Nonnull field \"title\" is null.");
|
||||||
|
}
|
||||||
|
this.title = setterArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The body of the notification. */
|
||||||
|
private @NonNull String body;
|
||||||
|
|
||||||
|
public @NonNull String getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBody(@NonNull String setterArg) {
|
||||||
|
if (setterArg == null) {
|
||||||
|
throw new IllegalStateException("Nonnull field \"body\" is null.");
|
||||||
|
}
|
||||||
|
this.body = setterArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The id of the channel to show the notification on. */
|
||||||
|
private @NonNull String channelId;
|
||||||
|
|
||||||
|
public @NonNull String getChannelId() {
|
||||||
|
return channelId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChannelId(@NonNull String setterArg) {
|
||||||
|
if (setterArg == null) {
|
||||||
|
throw new IllegalStateException("Nonnull field \"channelId\" is null.");
|
||||||
|
}
|
||||||
|
this.channelId = setterArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The id of the notification. */
|
||||||
|
private @NonNull Long id;
|
||||||
|
|
||||||
|
public @NonNull Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(@NonNull Long setterArg) {
|
||||||
|
if (setterArg == null) {
|
||||||
|
throw new IllegalStateException("Nonnull field \"id\" is null.");
|
||||||
|
}
|
||||||
|
this.id = setterArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The icon to use. */
|
||||||
|
private @NonNull NotificationIcon icon;
|
||||||
|
|
||||||
|
public @NonNull NotificationIcon getIcon() {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIcon(@NonNull NotificationIcon setterArg) {
|
||||||
|
if (setterArg == null) {
|
||||||
|
throw new IllegalStateException("Nonnull field \"icon\" is null.");
|
||||||
|
}
|
||||||
|
this.icon = setterArg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Constructor is non-public to enforce null safety; use Builder. */
|
||||||
|
RegularNotification() {}
|
||||||
|
|
||||||
|
public static final class Builder {
|
||||||
|
|
||||||
|
private @Nullable String title;
|
||||||
|
|
||||||
|
public @NonNull Builder setTitle(@NonNull String setterArg) {
|
||||||
|
this.title = setterArg;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private @Nullable String body;
|
||||||
|
|
||||||
|
public @NonNull Builder setBody(@NonNull String setterArg) {
|
||||||
|
this.body = setterArg;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private @Nullable String channelId;
|
||||||
|
|
||||||
|
public @NonNull Builder setChannelId(@NonNull String setterArg) {
|
||||||
|
this.channelId = setterArg;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private @Nullable Long id;
|
||||||
|
|
||||||
|
public @NonNull Builder setId(@NonNull Long setterArg) {
|
||||||
|
this.id = setterArg;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private @Nullable NotificationIcon icon;
|
||||||
|
|
||||||
|
public @NonNull Builder setIcon(@NonNull NotificationIcon setterArg) {
|
||||||
|
this.icon = setterArg;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NonNull RegularNotification build() {
|
||||||
|
RegularNotification pigeonReturn = new RegularNotification();
|
||||||
|
pigeonReturn.setTitle(title);
|
||||||
|
pigeonReturn.setBody(body);
|
||||||
|
pigeonReturn.setChannelId(channelId);
|
||||||
|
pigeonReturn.setId(id);
|
||||||
|
pigeonReturn.setIcon(icon);
|
||||||
|
return pigeonReturn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
ArrayList<Object> toList() {
|
||||||
|
ArrayList<Object> toListResult = new ArrayList<Object>(5);
|
||||||
|
toListResult.add(title);
|
||||||
|
toListResult.add(body);
|
||||||
|
toListResult.add(channelId);
|
||||||
|
toListResult.add(id);
|
||||||
|
toListResult.add(icon == null ? null : icon.index);
|
||||||
|
return toListResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
static @NonNull RegularNotification fromList(@NonNull ArrayList<Object> list) {
|
||||||
|
RegularNotification pigeonResult = new RegularNotification();
|
||||||
|
Object title = list.get(0);
|
||||||
|
pigeonResult.setTitle((String) title);
|
||||||
|
Object body = list.get(1);
|
||||||
|
pigeonResult.setBody((String) body);
|
||||||
|
Object channelId = list.get(2);
|
||||||
|
pigeonResult.setChannelId((String) channelId);
|
||||||
|
Object id = list.get(3);
|
||||||
|
pigeonResult.setId((id == null) ? null : ((id instanceof Integer) ? (Integer) id : (Long) id));
|
||||||
|
Object icon = list.get(4);
|
||||||
|
pigeonResult.setIcon(icon == null ? null : NotificationIcon.values()[(int) icon]);
|
||||||
|
return pigeonResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Generated class from Pigeon that represents data sent in messages. */
|
/** Generated class from Pigeon that represents data sent in messages. */
|
||||||
public static final class NotificationEvent {
|
public static final class NotificationEvent {
|
||||||
/** The JID the notification was for. */
|
/** The JID the notification was for. */
|
||||||
@ -672,6 +834,8 @@ public class Api {
|
|||||||
return NotificationMessage.fromList((ArrayList<Object>) readValue(buffer));
|
return NotificationMessage.fromList((ArrayList<Object>) readValue(buffer));
|
||||||
case (byte) 132:
|
case (byte) 132:
|
||||||
return NotificationMessageContent.fromList((ArrayList<Object>) readValue(buffer));
|
return NotificationMessageContent.fromList((ArrayList<Object>) readValue(buffer));
|
||||||
|
case (byte) 133:
|
||||||
|
return RegularNotification.fromList((ArrayList<Object>) readValue(buffer));
|
||||||
default:
|
default:
|
||||||
return super.readValueOfType(type, buffer);
|
return super.readValueOfType(type, buffer);
|
||||||
}
|
}
|
||||||
@ -694,6 +858,9 @@ public class Api {
|
|||||||
} else if (value instanceof NotificationMessageContent) {
|
} else if (value instanceof NotificationMessageContent) {
|
||||||
stream.write(132);
|
stream.write(132);
|
||||||
writeValue(stream, ((NotificationMessageContent) value).toList());
|
writeValue(stream, ((NotificationMessageContent) value).toList());
|
||||||
|
} else if (value instanceof RegularNotification) {
|
||||||
|
stream.write(133);
|
||||||
|
writeValue(stream, ((RegularNotification) value).toList());
|
||||||
} else {
|
} else {
|
||||||
super.writeValue(stream, value);
|
super.writeValue(stream, value);
|
||||||
}
|
}
|
||||||
@ -707,6 +874,8 @@ public class Api {
|
|||||||
|
|
||||||
void showMessagingNotification(@NonNull MessagingNotification notification);
|
void showMessagingNotification(@NonNull MessagingNotification notification);
|
||||||
|
|
||||||
|
void showNotification(@NonNull RegularNotification notification);
|
||||||
|
|
||||||
void setNotificationSelfAvatar(@NonNull String path);
|
void setNotificationSelfAvatar(@NonNull String path);
|
||||||
|
|
||||||
void setNotificationI18n(@NonNull NotificationI18nData data);
|
void setNotificationI18n(@NonNull NotificationI18nData data);
|
||||||
@ -765,6 +934,30 @@ public class Api {
|
|||||||
api.showMessagingNotification(notificationArg);
|
api.showMessagingNotification(notificationArg);
|
||||||
wrapped.add(0, null);
|
wrapped.add(0, null);
|
||||||
}
|
}
|
||||||
|
catch (Throwable exception) {
|
||||||
|
ArrayList<Object> wrappedError = wrapError(exception);
|
||||||
|
wrapped = wrappedError;
|
||||||
|
}
|
||||||
|
reply.reply(wrapped);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
channel.setMessageHandler(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
BasicMessageChannel<Object> channel =
|
||||||
|
new BasicMessageChannel<>(
|
||||||
|
binaryMessenger, "dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.showNotification", getCodec());
|
||||||
|
if (api != null) {
|
||||||
|
channel.setMessageHandler(
|
||||||
|
(message, reply) -> {
|
||||||
|
ArrayList<Object> wrapped = new ArrayList<Object>();
|
||||||
|
ArrayList<Object> args = (ArrayList<Object>) message;
|
||||||
|
RegularNotification notificationArg = (RegularNotification) args.get(0);
|
||||||
|
try {
|
||||||
|
api.showNotification(notificationArg);
|
||||||
|
wrapped.add(0, null);
|
||||||
|
}
|
||||||
catch (Throwable exception) {
|
catch (Throwable exception) {
|
||||||
ArrayList<Object> wrappedError = wrapError(exception);
|
ArrayList<Object> wrappedError = wrapError(exception);
|
||||||
wrapped = wrappedError;
|
wrapped = wrappedError;
|
||||||
|
@ -4,6 +4,7 @@ import static androidx.core.content.ContextCompat.getSystemService;
|
|||||||
import static me.polynom.moxplatform_android.ConstantsKt.SHARED_PREFERENCES_KEY;
|
import static me.polynom.moxplatform_android.ConstantsKt.SHARED_PREFERENCES_KEY;
|
||||||
import static me.polynom.moxplatform_android.RecordSentMessageKt.recordSentMessage;
|
import static me.polynom.moxplatform_android.RecordSentMessageKt.recordSentMessage;
|
||||||
import static me.polynom.moxplatform_android.CryptoKt.*;
|
import static me.polynom.moxplatform_android.CryptoKt.*;
|
||||||
|
|
||||||
import me.polynom.moxplatform_android.Api.*;
|
import me.polynom.moxplatform_android.Api.*;
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
@ -38,300 +39,270 @@ import io.flutter.plugin.common.JSONMethodCodec;
|
|||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
import kotlin.jvm.functions.Function1;
|
import kotlin.jvm.functions.Function1;
|
||||||
|
|
||||||
public class MoxplatformAndroidPlugin extends BroadcastReceiver implements FlutterPlugin, MethodCallHandler, EventChannel.StreamHandler, ServiceAware, MoxplatformApi {
|
public class MoxplatformAndroidPlugin extends BroadcastReceiver implements FlutterPlugin, MethodCallHandler, EventChannel.StreamHandler, ServiceAware, MoxplatformApi {
|
||||||
public static final String entrypointKey = "entrypoint_handle";
|
public static final String entrypointKey = "entrypoint_handle";
|
||||||
public static final String extraDataKey = "extra_data";
|
public static final String extraDataKey = "extra_data";
|
||||||
private static final String autoStartAtBootKey = "auto_start_at_boot";
|
private static final String autoStartAtBootKey = "auto_start_at_boot";
|
||||||
private static final String TAG = "moxplatform_android";
|
private static final String TAG = "moxplatform_android";
|
||||||
public static final String methodChannelKey = "me.polynom.moxplatform_android";
|
public static final String methodChannelKey = "me.polynom.moxplatform_android";
|
||||||
public static final String dataReceivedMethodName = "dataReceived";
|
public static final String dataReceivedMethodName = "dataReceived";
|
||||||
|
|
||||||
private static final List<MoxplatformAndroidPlugin> _instances = new ArrayList<>();
|
private static final List<MoxplatformAndroidPlugin> _instances = new ArrayList<>();
|
||||||
private BackgroundService service;
|
private BackgroundService service;
|
||||||
private MethodChannel channel;
|
private MethodChannel channel;
|
||||||
private static EventChannel notificationChannel;
|
private static EventChannel notificationChannel;
|
||||||
public static EventSink notificationSink;
|
public static EventSink notificationSink;
|
||||||
|
|
||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
public MoxplatformAndroidPlugin() {
|
public MoxplatformAndroidPlugin() {
|
||||||
_instances.add(this);
|
_instances.add(this);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
|
|
||||||
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), methodChannelKey);
|
|
||||||
channel.setMethodCallHandler(this);
|
|
||||||
context = flutterPluginBinding.getApplicationContext();
|
|
||||||
|
|
||||||
notificationChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "me.polynom/notification_stream");
|
|
||||||
notificationChannel.setStreamHandler(
|
|
||||||
this
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this.context);
|
|
||||||
localBroadcastManager.registerReceiver(this, new IntentFilter(methodChannelKey));
|
|
||||||
|
|
||||||
MoxplatformApi.setup(flutterPluginBinding.getBinaryMessenger(), this);
|
|
||||||
|
|
||||||
Log.d(TAG, "Attached to engine");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void registerWith(Registrar registrar) {
|
|
||||||
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(registrar.context());
|
|
||||||
final MoxplatformAndroidPlugin plugin = new MoxplatformAndroidPlugin();
|
|
||||||
localBroadcastManager.registerReceiver(plugin, new IntentFilter(methodChannelKey));
|
|
||||||
|
|
||||||
final MethodChannel channel = new MethodChannel(registrar.messenger(), "me.polynom/background_service_android", JSONMethodCodec.INSTANCE);
|
|
||||||
channel.setMethodCallHandler(plugin);
|
|
||||||
plugin.channel = channel;
|
|
||||||
|
|
||||||
Log.d(TAG, "Registered against registrar");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCancel(Object arguments) {
|
|
||||||
Log.d(TAG, "Removed listener");
|
|
||||||
notificationSink = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onListen(Object arguments, EventChannel.EventSink eventSink) {
|
|
||||||
Log.d(TAG, "Attached listener");
|
|
||||||
notificationSink = eventSink;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Store the entrypoint handle and extra data for the background service.
|
|
||||||
private void configure(long entrypointHandle, String extraData) {
|
|
||||||
SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE);
|
|
||||||
prefs.edit()
|
|
||||||
.putLong(entrypointKey, entrypointHandle)
|
|
||||||
.putString(extraDataKey, extraData)
|
|
||||||
.apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long getHandle(Context c) {
|
|
||||||
return c.getSharedPreferences(SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE).getLong(entrypointKey, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getExtraData(Context c) {
|
|
||||||
return c.getSharedPreferences(SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE).getString(extraDataKey, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setStartAtBoot(Context c, boolean value) {
|
|
||||||
c.getSharedPreferences(SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE)
|
|
||||||
.edit()
|
|
||||||
.putBoolean(autoStartAtBootKey, value)
|
|
||||||
.apply();
|
|
||||||
}
|
|
||||||
public static boolean getStartAtBoot(Context c) {
|
|
||||||
return c.getSharedPreferences(SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE).getBoolean(autoStartAtBootKey, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isRunning() {
|
|
||||||
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
|
||||||
for (ActivityManager.RunningServiceInfo info : manager.getRunningServices(Integer.MAX_VALUE)) {
|
|
||||||
if (BackgroundService.class.getName().equals(info.service.getClassName())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
@Override
|
||||||
}
|
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
|
||||||
|
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), methodChannelKey);
|
||||||
|
channel.setMethodCallHandler(this);
|
||||||
|
context = flutterPluginBinding.getApplicationContext();
|
||||||
|
|
||||||
@Override
|
notificationChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "me.polynom/notification_stream");
|
||||||
public void onMethodCall(@NonNull MethodCall call, @NonNull io.flutter.plugin.common.MethodChannel.Result result) {
|
notificationChannel.setStreamHandler(this);
|
||||||
switch (call.method) {
|
|
||||||
case "configure":
|
|
||||||
ArrayList args = (ArrayList) call.arguments;
|
|
||||||
long handle = (long) args.get(0);
|
|
||||||
String extraData = (String) args.get(1);
|
|
||||||
|
|
||||||
configure(handle, extraData);
|
|
||||||
result.success(true);
|
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this.context);
|
||||||
break;
|
localBroadcastManager.registerReceiver(this, new IntentFilter(methodChannelKey));
|
||||||
case "isRunning":
|
|
||||||
result.success(isRunning());
|
MoxplatformApi.setup(flutterPluginBinding.getBinaryMessenger(), this);
|
||||||
break;
|
|
||||||
case "start":
|
Log.d(TAG, "Attached to engine");
|
||||||
MoxplatformAndroidPlugin.setStartAtBoot(context, true);
|
}
|
||||||
BackgroundService.enqueue(context);
|
|
||||||
Intent intent = new Intent(context, BackgroundService.class);
|
static void registerWith(Registrar registrar) {
|
||||||
ContextCompat.startForegroundService(context, intent);
|
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(registrar.context());
|
||||||
Log.d(TAG, "Service started");
|
final MoxplatformAndroidPlugin plugin = new MoxplatformAndroidPlugin();
|
||||||
result.success(true);
|
localBroadcastManager.registerReceiver(plugin, new IntentFilter(methodChannelKey));
|
||||||
break;
|
|
||||||
case "sendData":
|
final MethodChannel channel = new MethodChannel(registrar.messenger(), "me.polynom/background_service_android", JSONMethodCodec.INSTANCE);
|
||||||
for (MoxplatformAndroidPlugin plugin : _instances) {
|
channel.setMethodCallHandler(plugin);
|
||||||
if (plugin.service != null) {
|
plugin.channel = channel;
|
||||||
plugin.service.receiveData((String) call.arguments);
|
|
||||||
break;
|
Log.d(TAG, "Registered against registrar");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancel(Object arguments) {
|
||||||
|
Log.d(TAG, "Removed listener");
|
||||||
|
notificationSink = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onListen(Object arguments, EventChannel.EventSink eventSink) {
|
||||||
|
Log.d(TAG, "Attached listener");
|
||||||
|
notificationSink = eventSink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Store the entrypoint handle and extra data for the background service.
|
||||||
|
private void configure(long entrypointHandle, String extraData) {
|
||||||
|
SharedPreferences prefs = context.getSharedPreferences(SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE);
|
||||||
|
prefs.edit().putLong(entrypointKey, entrypointHandle).putString(extraDataKey, extraData).apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getHandle(Context c) {
|
||||||
|
return c.getSharedPreferences(SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE).getLong(entrypointKey, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getExtraData(Context c) {
|
||||||
|
return c.getSharedPreferences(SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE).getString(extraDataKey, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setStartAtBoot(Context c, boolean value) {
|
||||||
|
c.getSharedPreferences(SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE).edit().putBoolean(autoStartAtBootKey, value).apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean getStartAtBoot(Context c) {
|
||||||
|
return c.getSharedPreferences(SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE).getBoolean(autoStartAtBootKey, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isRunning() {
|
||||||
|
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||||
|
for (ActivityManager.RunningServiceInfo info : manager.getRunningServices(Integer.MAX_VALUE)) {
|
||||||
|
if (BackgroundService.class.getName().equals(info.service.getClassName())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result.success(true);
|
|
||||||
break;
|
|
||||||
case "encryptFile":
|
|
||||||
Thread encryptionThread = new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
ArrayList args = (ArrayList) call.arguments;
|
|
||||||
String src = (String) args.get(0);
|
|
||||||
String dest = (String) args.get(1);
|
|
||||||
byte[] key = (byte[]) args.get(2);
|
|
||||||
byte[] iv = (byte[]) args.get(3);
|
|
||||||
int algorithm = (int) args.get(4);
|
|
||||||
String hashSpec = (String) args.get(5);
|
|
||||||
|
|
||||||
result.success(
|
return false;
|
||||||
encryptAndHash(
|
|
||||||
src,
|
|
||||||
dest,
|
|
||||||
key,
|
|
||||||
iv,
|
|
||||||
getCipherSpecFromInteger(algorithm),
|
|
||||||
hashSpec
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
encryptionThread.start();
|
|
||||||
break;
|
|
||||||
case "decryptFile":
|
|
||||||
Thread decryptionThread = new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
ArrayList args = (ArrayList) call.arguments;
|
|
||||||
String src = (String) args.get(0);
|
|
||||||
String dest = (String) args.get(1);
|
|
||||||
byte[] key = (byte[]) args.get(2);
|
|
||||||
byte[] iv = (byte[]) args.get(3);
|
|
||||||
int algorithm = (int) args.get(4);
|
|
||||||
String hashSpec = (String) args.get(5);
|
|
||||||
|
|
||||||
result.success(
|
|
||||||
decryptAndHash(
|
|
||||||
src,
|
|
||||||
dest,
|
|
||||||
key,
|
|
||||||
iv,
|
|
||||||
getCipherSpecFromInteger(algorithm),
|
|
||||||
hashSpec
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
decryptionThread.start();
|
|
||||||
break;
|
|
||||||
case "hashFile":
|
|
||||||
Thread hashingThread = new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
ArrayList args = (ArrayList) call.arguments;
|
|
||||||
String src = (String) args.get(0);
|
|
||||||
String hashSpec = (String) args.get(1);
|
|
||||||
|
|
||||||
result.success(hashFile(src, hashSpec));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
hashingThread.start();
|
|
||||||
break;
|
|
||||||
case "recordSentMessage":
|
|
||||||
ArrayList rargs = (ArrayList) call.arguments;
|
|
||||||
recordSentMessage(
|
|
||||||
context,
|
|
||||||
(String) rargs.get(0),
|
|
||||||
(String) rargs.get(1),
|
|
||||||
(String) rargs.get(2),
|
|
||||||
(int) rargs.get(3)
|
|
||||||
);
|
|
||||||
result.success(true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
result.notImplemented();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onMethodCall(@NonNull MethodCall call, @NonNull io.flutter.plugin.common.MethodChannel.Result result) {
|
||||||
if (intent.getAction() == null) return;
|
switch (call.method) {
|
||||||
|
case "configure":
|
||||||
|
ArrayList args = (ArrayList) call.arguments;
|
||||||
|
long handle = (long) args.get(0);
|
||||||
|
String extraData = (String) args.get(1);
|
||||||
|
|
||||||
if (intent.getAction().equalsIgnoreCase(methodChannelKey)) {
|
configure(handle, extraData);
|
||||||
String data = intent.getStringExtra("data");
|
result.success(true);
|
||||||
|
break;
|
||||||
|
case "isRunning":
|
||||||
|
result.success(isRunning());
|
||||||
|
break;
|
||||||
|
case "start":
|
||||||
|
MoxplatformAndroidPlugin.setStartAtBoot(context, true);
|
||||||
|
BackgroundService.enqueue(context);
|
||||||
|
Intent intent = new Intent(context, BackgroundService.class);
|
||||||
|
ContextCompat.startForegroundService(context, intent);
|
||||||
|
Log.d(TAG, "Service started");
|
||||||
|
result.success(true);
|
||||||
|
break;
|
||||||
|
case "sendData":
|
||||||
|
for (MoxplatformAndroidPlugin plugin : _instances) {
|
||||||
|
if (plugin.service != null) {
|
||||||
|
plugin.service.receiveData((String) call.arguments);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.success(true);
|
||||||
|
break;
|
||||||
|
case "encryptFile":
|
||||||
|
Thread encryptionThread = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ArrayList args = (ArrayList) call.arguments;
|
||||||
|
String src = (String) args.get(0);
|
||||||
|
String dest = (String) args.get(1);
|
||||||
|
byte[] key = (byte[]) args.get(2);
|
||||||
|
byte[] iv = (byte[]) args.get(3);
|
||||||
|
int algorithm = (int) args.get(4);
|
||||||
|
String hashSpec = (String) args.get(5);
|
||||||
|
|
||||||
if (channel != null) {
|
result.success(encryptAndHash(src, dest, key, iv, getCipherSpecFromInteger(algorithm), hashSpec));
|
||||||
channel.invokeMethod(dataReceivedMethodName, data);
|
}
|
||||||
}
|
});
|
||||||
|
encryptionThread.start();
|
||||||
|
break;
|
||||||
|
case "decryptFile":
|
||||||
|
Thread decryptionThread = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ArrayList args = (ArrayList) call.arguments;
|
||||||
|
String src = (String) args.get(0);
|
||||||
|
String dest = (String) args.get(1);
|
||||||
|
byte[] key = (byte[]) args.get(2);
|
||||||
|
byte[] iv = (byte[]) args.get(3);
|
||||||
|
int algorithm = (int) args.get(4);
|
||||||
|
String hashSpec = (String) args.get(5);
|
||||||
|
|
||||||
|
result.success(decryptAndHash(src, dest, key, iv, getCipherSpecFromInteger(algorithm), hashSpec));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
decryptionThread.start();
|
||||||
|
break;
|
||||||
|
case "hashFile":
|
||||||
|
Thread hashingThread = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ArrayList args = (ArrayList) call.arguments;
|
||||||
|
String src = (String) args.get(0);
|
||||||
|
String hashSpec = (String) args.get(1);
|
||||||
|
|
||||||
|
result.success(hashFile(src, hashSpec));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
hashingThread.start();
|
||||||
|
break;
|
||||||
|
case "recordSentMessage":
|
||||||
|
ArrayList rargs = (ArrayList) call.arguments;
|
||||||
|
recordSentMessage(context, (String) rargs.get(0), (String) rargs.get(1), (String) rargs.get(2), (int) rargs.get(3));
|
||||||
|
result.success(true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result.notImplemented();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
channel.setMethodCallHandler(null);
|
if (intent.getAction() == null) return;
|
||||||
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this.context);
|
|
||||||
localBroadcastManager.unregisterReceiver(this);
|
|
||||||
|
|
||||||
Log.d(TAG, "Detached from engine");
|
if (intent.getAction().equalsIgnoreCase(methodChannelKey)) {
|
||||||
}
|
String data = intent.getStringExtra("data");
|
||||||
|
|
||||||
@Override
|
if (channel != null) {
|
||||||
public void onAttachedToService(@NonNull ServicePluginBinding binding) {
|
channel.invokeMethod(dataReceivedMethodName, data);
|
||||||
Log.d(TAG, "Attached to service");
|
}
|
||||||
this.service = (BackgroundService) binding.getService();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDetachedFromService() {
|
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
|
||||||
Log.d(TAG, "Detached from service");
|
channel.setMethodCallHandler(null);
|
||||||
this.service = null;
|
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this.context);
|
||||||
}
|
localBroadcastManager.unregisterReceiver(this);
|
||||||
|
|
||||||
@Override
|
Log.d(TAG, "Detached from engine");
|
||||||
public void createNotificationChannel(@NonNull String title, @NonNull String id, @NonNull Boolean urgent) {
|
}
|
||||||
final NotificationChannel channel = new NotificationChannel(
|
|
||||||
id,
|
|
||||||
title,
|
|
||||||
urgent ? NotificationManager.IMPORTANCE_HIGH : NotificationManager.IMPORTANCE_DEFAULT
|
|
||||||
);
|
|
||||||
channel.enableVibration(true);
|
|
||||||
channel.enableLights(true);
|
|
||||||
final NotificationManager manager = getSystemService(context, NotificationManager.class);
|
|
||||||
manager.createNotificationChannel(channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showMessagingNotification(@NonNull MessagingNotification notification) {
|
public void onAttachedToService(@NonNull ServicePluginBinding binding) {
|
||||||
NotificationsKt.showMessagingNotification(context, notification);
|
Log.d(TAG, "Attached to service");
|
||||||
}
|
this.service = (BackgroundService) binding.getService();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetachedFromService() {
|
||||||
|
Log.d(TAG, "Detached from service");
|
||||||
|
this.service = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createNotificationChannel(@NonNull String title, @NonNull String id, @NonNull Boolean urgent) {
|
||||||
|
final NotificationChannel channel = new NotificationChannel(id, title, urgent ? NotificationManager.IMPORTANCE_HIGH : NotificationManager.IMPORTANCE_DEFAULT);
|
||||||
|
channel.enableVibration(true);
|
||||||
|
channel.enableLights(true);
|
||||||
|
final NotificationManager manager = getSystemService(context, NotificationManager.class);
|
||||||
|
manager.createNotificationChannel(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showMessagingNotification(@NonNull MessagingNotification notification) {
|
||||||
|
NotificationsKt.showMessagingNotification(context, notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showNotification(@NonNull RegularNotification notification) {
|
||||||
|
NotificationsKt.showNotification(context, notification);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNotificationSelfAvatar(@NonNull String path) {
|
public void setNotificationSelfAvatar(@NonNull String path) {
|
||||||
NotificationDataManager.INSTANCE.setAvatarPath(path);
|
NotificationDataManager.INSTANCE.setAvatarPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setNotificationI18n(@NonNull NotificationI18nData data) {
|
public void setNotificationI18n(@NonNull NotificationI18nData data) {
|
||||||
// Configure i18n
|
// Configure i18n
|
||||||
NotificationDataManager.INSTANCE.setYou(context, data.getYou());
|
NotificationDataManager.INSTANCE.setYou(context, data.getYou());
|
||||||
NotificationDataManager.INSTANCE.setReply(context, data.getReply());
|
NotificationDataManager.INSTANCE.setReply(context, data.getReply());
|
||||||
NotificationDataManager.INSTANCE.setMarkAsRead(context, data.getMarkAsRead());
|
NotificationDataManager.INSTANCE.setMarkAsRead(context, data.getMarkAsRead());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public String getPersistentDataPath() {
|
public String getPersistentDataPath() {
|
||||||
return context.getFilesDir().getPath();
|
return context.getFilesDir().getPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public String getCacheDataPath() {
|
public String getCacheDataPath() {
|
||||||
return context.getCacheDir().getPath();
|
return context.getCacheDir().getPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void eventStub(@NonNull NotificationEvent event) {
|
public void eventStub(@NonNull NotificationEvent event) {
|
||||||
// Stub to trick pigeon into
|
// Stub to trick pigeon into
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,4 +211,20 @@ fun showMessagingNotification(context: Context, notification: Api.MessagingNotif
|
|||||||
notification.id.toInt(),
|
notification.id.toInt(),
|
||||||
finalNotification,
|
finalNotification,
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showNotification(context: Context, notification: Api.RegularNotification) {
|
||||||
|
val builtNotification = NotificationCompat.Builder(context, notification.channelId).apply {
|
||||||
|
setContentTitle(notification.title)
|
||||||
|
setContentText(notification.body)
|
||||||
|
|
||||||
|
when (notification.icon) {
|
||||||
|
Api.NotificationIcon.ERROR -> setSmallIcon(R.drawable.error)
|
||||||
|
Api.NotificationIcon.WARNING -> setSmallIcon(R.drawable.warning)
|
||||||
|
Api.NotificationIcon.NONE -> {}
|
||||||
|
}
|
||||||
|
}.build()
|
||||||
|
|
||||||
|
// Post the notification
|
||||||
|
NotificationManagerCompat.from(context).notify(notification.id.toInt(), builtNotification)
|
||||||
}
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
|
||||||
|
</vector>
|
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/>
|
||||||
|
</vector>
|
@ -24,6 +24,11 @@ class AndroidNotificationsImplementation extends NotificationsImplementation {
|
|||||||
return _api.showMessagingNotification(notification);
|
return _api.showMessagingNotification(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> showNotification(RegularNotification notification) async {
|
||||||
|
return _api.showNotification(notification);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> setNotificationSelfAvatar(String path) async {
|
Future<void> setNotificationSelfAvatar(String path) async {
|
||||||
return _api.setNotificationSelfAvatar(path);
|
return _api.setNotificationSelfAvatar(path);
|
||||||
|
@ -8,6 +8,12 @@ import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
|
|||||||
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
|
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
enum NotificationIcon {
|
||||||
|
warning,
|
||||||
|
error,
|
||||||
|
none,
|
||||||
|
}
|
||||||
|
|
||||||
enum NotificationEventType {
|
enum NotificationEventType {
|
||||||
markAsRead,
|
markAsRead,
|
||||||
reply,
|
reply,
|
||||||
@ -139,6 +145,52 @@ class MessagingNotification {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RegularNotification {
|
||||||
|
RegularNotification({
|
||||||
|
required this.title,
|
||||||
|
required this.body,
|
||||||
|
required this.channelId,
|
||||||
|
required this.id,
|
||||||
|
required this.icon,
|
||||||
|
});
|
||||||
|
|
||||||
|
/// The title of the notification.
|
||||||
|
String title;
|
||||||
|
|
||||||
|
/// The body of the notification.
|
||||||
|
String body;
|
||||||
|
|
||||||
|
/// The id of the channel to show the notification on.
|
||||||
|
String channelId;
|
||||||
|
|
||||||
|
/// The id of the notification.
|
||||||
|
int id;
|
||||||
|
|
||||||
|
/// The icon to use.
|
||||||
|
NotificationIcon icon;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
title,
|
||||||
|
body,
|
||||||
|
channelId,
|
||||||
|
id,
|
||||||
|
icon.index,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static RegularNotification decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return RegularNotification(
|
||||||
|
title: result[0]! as String,
|
||||||
|
body: result[1]! as String,
|
||||||
|
channelId: result[2]! as String,
|
||||||
|
id: result[3]! as int,
|
||||||
|
icon: NotificationIcon.values[result[4]! as int],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class NotificationEvent {
|
class NotificationEvent {
|
||||||
NotificationEvent({
|
NotificationEvent({
|
||||||
required this.jid,
|
required this.jid,
|
||||||
@ -228,6 +280,9 @@ class _MoxplatformApiCodec extends StandardMessageCodec {
|
|||||||
} else if (value is NotificationMessageContent) {
|
} else if (value is NotificationMessageContent) {
|
||||||
buffer.putUint8(132);
|
buffer.putUint8(132);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is RegularNotification) {
|
||||||
|
buffer.putUint8(133);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
} else {
|
} else {
|
||||||
super.writeValue(buffer, value);
|
super.writeValue(buffer, value);
|
||||||
}
|
}
|
||||||
@ -246,6 +301,8 @@ class _MoxplatformApiCodec extends StandardMessageCodec {
|
|||||||
return NotificationMessage.decode(readValue(buffer)!);
|
return NotificationMessage.decode(readValue(buffer)!);
|
||||||
case 132:
|
case 132:
|
||||||
return NotificationMessageContent.decode(readValue(buffer)!);
|
return NotificationMessageContent.decode(readValue(buffer)!);
|
||||||
|
case 133:
|
||||||
|
return RegularNotification.decode(readValue(buffer)!);
|
||||||
default:
|
default:
|
||||||
return super.readValueOfType(type, buffer);
|
return super.readValueOfType(type, buffer);
|
||||||
}
|
}
|
||||||
@ -306,6 +363,28 @@ class MoxplatformApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> showNotification(RegularNotification arg_notification) async {
|
||||||
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.showNotification', codec,
|
||||||
|
binaryMessenger: _binaryMessenger);
|
||||||
|
final List<Object?>? replyList =
|
||||||
|
await channel.send(<Object?>[arg_notification]) as List<Object?>?;
|
||||||
|
if (replyList == null) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: 'channel-error',
|
||||||
|
message: 'Unable to establish connection on channel.',
|
||||||
|
);
|
||||||
|
} else if (replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: replyList[0]! as String,
|
||||||
|
message: replyList[1] as String?,
|
||||||
|
details: replyList[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> setNotificationSelfAvatar(String arg_path) async {
|
Future<void> setNotificationSelfAvatar(String arg_path) async {
|
||||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||||
'dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.setNotificationSelfAvatar', codec,
|
'dev.flutter.pigeon.moxplatform_platform_interface.MoxplatformApi.setNotificationSelfAvatar', codec,
|
||||||
|
@ -9,6 +9,9 @@ abstract class NotificationsImplementation {
|
|||||||
/// Shows a notification [notification] in the messaging style with everyting it needs.
|
/// Shows a notification [notification] in the messaging style with everyting it needs.
|
||||||
Future<void> showMessagingNotification(MessagingNotification notification);
|
Future<void> showMessagingNotification(MessagingNotification notification);
|
||||||
|
|
||||||
|
/// Shows a regular notification [notification].
|
||||||
|
Future<void> showNotification(RegularNotification notification);
|
||||||
|
|
||||||
/// Sets the path to the self-avatar for in-notification replies.
|
/// Sets the path to the self-avatar for in-notification replies.
|
||||||
Future<void> setNotificationSelfAvatar(String path);
|
Future<void> setNotificationSelfAvatar(String path);
|
||||||
|
|
||||||
|
@ -9,6 +9,10 @@ class StubNotificationsImplementation extends NotificationsImplementation {
|
|||||||
@override
|
@override
|
||||||
Future<void> showMessagingNotification(MessagingNotification notification) async {}
|
Future<void> showMessagingNotification(MessagingNotification notification) async {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> showNotification(RegularNotification notification) async {}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> setNotificationSelfAvatar(String path) async {}
|
Future<void> setNotificationSelfAvatar(String path) async {}
|
||||||
|
|
||||||
|
@ -72,6 +72,31 @@ class MessagingNotification {
|
|||||||
final List<NotificationMessage?> messages;
|
final List<NotificationMessage?> messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum NotificationIcon {
|
||||||
|
warning,
|
||||||
|
error,
|
||||||
|
none,
|
||||||
|
}
|
||||||
|
|
||||||
|
class RegularNotification {
|
||||||
|
const RegularNotification(this.title, this.body, this.channelId, this.id, this.icon);
|
||||||
|
|
||||||
|
/// The title of the notification.
|
||||||
|
final String title;
|
||||||
|
|
||||||
|
/// The body of the notification.
|
||||||
|
final String body;
|
||||||
|
|
||||||
|
/// The id of the channel to show the notification on.
|
||||||
|
final String channelId;
|
||||||
|
|
||||||
|
/// The id of the notification.
|
||||||
|
final int id;
|
||||||
|
|
||||||
|
/// The icon to use.
|
||||||
|
final NotificationIcon icon;
|
||||||
|
}
|
||||||
|
|
||||||
enum NotificationEventType {
|
enum NotificationEventType {
|
||||||
markAsRead,
|
markAsRead,
|
||||||
reply,
|
reply,
|
||||||
@ -114,6 +139,7 @@ class NotificationI18nData {
|
|||||||
abstract class MoxplatformApi {
|
abstract class MoxplatformApi {
|
||||||
void createNotificationChannel(String title, String id, bool urgent);
|
void createNotificationChannel(String title, String id, bool urgent);
|
||||||
void showMessagingNotification(MessagingNotification notification);
|
void showMessagingNotification(MessagingNotification notification);
|
||||||
|
void showNotification(RegularNotification notification);
|
||||||
void setNotificationSelfAvatar(String path);
|
void setNotificationSelfAvatar(String path);
|
||||||
void setNotificationI18n(NotificationI18nData data);
|
void setNotificationI18n(NotificationI18nData data);
|
||||||
String getPersistentDataPath();
|
String getPersistentDataPath();
|
||||||
|
Reference in New Issue
Block a user