Basic stuff
This commit is contained in:
parent
17642f9fab
commit
1771c0e1b6
@ -47,7 +47,7 @@ android {
|
||||
applicationId "com.example.example"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
|
||||
minSdkVersion flutter.minSdkVersion
|
||||
minSdkVersion 26
|
||||
targetSdkVersion flutter.targetSdkVersion
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
|
@ -34,5 +34,5 @@
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
</manifest>
|
||||
|
@ -1,17 +1,49 @@
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:moxplatform/moxplatform.dart';
|
||||
import 'package:moxplatform_platform_interface/moxplatform_platform_interface.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
|
||||
/// The id of the notification channel.
|
||||
const channelId = "me.polynom.moxplatform.testing3";
|
||||
|
||||
void main() {
|
||||
runApp(const MyApp());
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
class Sender {
|
||||
const Sender(this.name, this.jid);
|
||||
|
||||
final String name;
|
||||
|
||||
final String jid;
|
||||
}
|
||||
|
||||
class MyApp extends StatefulWidget {
|
||||
const MyApp({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
MyAppState createState() => MyAppState();
|
||||
}
|
||||
|
||||
class MyAppState extends State<MyApp> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
initStateAsync();
|
||||
}
|
||||
|
||||
Future<void> initStateAsync() async {
|
||||
await Permission.notification.request();
|
||||
|
||||
await MoxplatformPlugin.notifications.createNotificationChannel("Test notification channel", channelId, false);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
@ -19,13 +51,23 @@ class MyApp extends StatelessWidget {
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.blue,
|
||||
),
|
||||
home: const MyHomePage(),
|
||||
home: MyHomePage(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyHomePage extends StatelessWidget {
|
||||
const MyHomePage({super.key});
|
||||
MyHomePage({super.key});
|
||||
|
||||
/// List of "Message senders".
|
||||
final List<Sender> senders = const [
|
||||
Sender('Mash Kyrielight', 'mash@example.org'),
|
||||
Sender('Rio Tsukatsuki', 'rio@millenium'),
|
||||
Sender('Raiden Shogun', 'raiden@tevhat'),
|
||||
];
|
||||
|
||||
/// List of sent messages.
|
||||
List<NotificationMessage> messages = List<NotificationMessage>.empty(growable: true);
|
||||
|
||||
Future<void> _cryptoTest() async {
|
||||
final result = await FilePicker.platform.pickFiles();
|
||||
@ -98,6 +140,41 @@ class MyHomePage extends StatelessWidget {
|
||||
},
|
||||
child: const Text('Test recordSentMessage (notes fallback)'),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
final result = await FilePicker.platform.pickFiles(
|
||||
type: FileType.image,
|
||||
);
|
||||
print('Picked file: ${result?.files.single.path}');
|
||||
|
||||
// Create a new message.
|
||||
final senderIndex = Random().nextInt(senders.length);
|
||||
final time = DateTime.now().millisecondsSinceEpoch;
|
||||
messages.add(
|
||||
NotificationMessage(
|
||||
jid: senders[senderIndex].jid,
|
||||
sender: senders[senderIndex].name,
|
||||
content: NotificationMessageContent(
|
||||
body: result != null ? null : 'Message #${messages.length}',
|
||||
mime: 'image/jpeg',
|
||||
path: result?.files.single.path,
|
||||
),
|
||||
timestamp: time,
|
||||
)
|
||||
);
|
||||
|
||||
await Future<void>.delayed(const Duration(seconds: 4));
|
||||
await MoxplatformPlugin.notifications.showMessagingNotification(
|
||||
MessagingNotification(
|
||||
id: 2343,
|
||||
title: 'Test conversation',
|
||||
messages: messages,
|
||||
channelId: channelId,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: const Text('Show messaging notification'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -38,6 +38,8 @@ dependencies:
|
||||
version: 0.1.17+1
|
||||
|
||||
file_picker: 5.2.0+1
|
||||
|
||||
permission_handler: 10.4.3
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
|
@ -5,4 +5,5 @@ class MoxplatformPlugin {
|
||||
static MediaScannerImplementation get media => MoxplatformInterface.media;
|
||||
static CryptographyImplementation get crypto => MoxplatformInterface.crypto;
|
||||
static ContactsImplementation get contacts => MoxplatformInterface.contacts;
|
||||
static NotificationsImplementation get notifications => MoxplatformInterface.notifications;
|
||||
}
|
||||
|
@ -35,7 +35,8 @@ android {
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
// What Moxxy currently uses
|
||||
minSdkVersion 26
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,22 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="me.polynom.moxplatform_android">
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
|
||||
|
||||
<application>
|
||||
<provider
|
||||
android:name="me.polynom.moxplatform_android.MoxplatformFileProvider"
|
||||
android:authorities="me.polynom.moxplatform_android.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
|
||||
<service
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
@ -27,5 +38,6 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".NotificationReceiver" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
@ -6,6 +6,14 @@ const val TAG = "Moxplatform"
|
||||
// The size of the buffer to hashing, encryption, and decryption in bytes.
|
||||
const val BUFFER_SIZE = 8096
|
||||
|
||||
// The data key for text entered in the notification's reply field
|
||||
const val REPLY_TEXT_KEY = "key_reply_text"
|
||||
|
||||
// The action for pressing the "Mark as read" button on a notification
|
||||
const val MARK_AS_READ_ACTION = "mark_as_read"
|
||||
// The key for the notification id to mark as read
|
||||
const val MARK_AS_READ_ID_KEY = "notification_id"
|
||||
|
||||
// TODO: Maybe try again to rewrite the entire plugin in Kotlin
|
||||
//const val METHOD_CHANNEL_KEY = "me.polynom.moxplatform_android"
|
||||
//const val BACKGROUND_METHOD_CHANNEL_KEY = METHOD_CHANNEL_KEY + "_bg"
|
||||
|
@ -0,0 +1,6 @@
|
||||
package me.polynom.moxplatform_android
|
||||
|
||||
import androidx.core.content.FileProvider
|
||||
|
||||
class MoxplatformFileProvider : FileProvider(R.xml.file_paths) {
|
||||
}
|
@ -1,31 +1,39 @@
|
||||
package me.polynom.moxplatform_android;
|
||||
|
||||
import static androidx.core.content.ContextCompat.getSystemService;
|
||||
import static me.polynom.moxplatform_android.ConstantsKt.MARK_AS_READ_ACTION;
|
||||
import static me.polynom.moxplatform_android.ConstantsKt.MARK_AS_READ_ID_KEY;
|
||||
import static me.polynom.moxplatform_android.ConstantsKt.REPLY_TEXT_KEY;
|
||||
import static me.polynom.moxplatform_android.RecordSentMessageKt.recordSentMessage;
|
||||
import static me.polynom.moxplatform_android.CryptoKt.*;
|
||||
import me.polynom.moxplatform_android.Notifications.*;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.RemoteInput;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
import androidx.core.app.Person;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.CipherOutputStream;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin;
|
||||
import io.flutter.embedding.engine.plugins.service.ServiceAware;
|
||||
import io.flutter.embedding.engine.plugins.service.ServicePluginBinding;
|
||||
@ -35,8 +43,10 @@ import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
||||
import io.flutter.plugin.common.MethodChannel.Result;
|
||||
import io.flutter.plugin.common.PluginRegistry.Registrar;
|
||||
import io.flutter.plugin.common.JSONMethodCodec;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
|
||||
public class MoxplatformAndroidPlugin extends BroadcastReceiver implements FlutterPlugin, MethodCallHandler, ServiceAware {
|
||||
public class MoxplatformAndroidPlugin extends BroadcastReceiver implements FlutterPlugin, MethodCallHandler, ServiceAware, NotificationsImplementationApi {
|
||||
public static final String entrypointKey = "entrypoint_handle";
|
||||
public static final String extraDataKey = "extra_data";
|
||||
private static final String autoStartAtBootKey = "auto_start_at_boot";
|
||||
@ -50,6 +60,8 @@ public class MoxplatformAndroidPlugin extends BroadcastReceiver implements Flutt
|
||||
private MethodChannel channel;
|
||||
private Context context;
|
||||
|
||||
private FileProvider provider = new FileProvider();
|
||||
|
||||
public MoxplatformAndroidPlugin() {
|
||||
_instances.add(this);
|
||||
}
|
||||
@ -63,6 +75,8 @@ public class MoxplatformAndroidPlugin extends BroadcastReceiver implements Flutt
|
||||
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this.context);
|
||||
localBroadcastManager.registerReceiver(this, new IntentFilter(methodChannelKey));
|
||||
|
||||
NotificationsImplementationApi.setup(flutterPluginBinding.getBinaryMessenger(), this);
|
||||
|
||||
Log.d(TAG, "Attached to engine");
|
||||
}
|
||||
|
||||
@ -117,7 +131,7 @@ public class MoxplatformAndroidPlugin extends BroadcastReceiver implements Flutt
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
|
||||
public void onMethodCall(@NonNull MethodCall call, @NonNull io.flutter.plugin.common.MethodChannel.Result result) {
|
||||
switch (call.method) {
|
||||
case "configure":
|
||||
ArrayList args = (ArrayList) call.arguments;
|
||||
@ -262,4 +276,78 @@ public class MoxplatformAndroidPlugin extends BroadcastReceiver implements Flutt
|
||||
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) {
|
||||
// Create a reply button
|
||||
// TODO: i18n
|
||||
RemoteInput remoteInput = new RemoteInput.Builder(REPLY_TEXT_KEY).setLabel("Reply").build();
|
||||
final Intent replyIntent = new Intent(context, NotificationReceiver.class);
|
||||
final PendingIntent replyPendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(), 0, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
// TODO: i18n
|
||||
// TODO: Correct icon
|
||||
final NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.ic_service_icon, "Reply", replyPendingIntent)
|
||||
.addRemoteInput(remoteInput)
|
||||
.build();
|
||||
|
||||
// Create the "mark as read" button
|
||||
final Intent markAsReadIntent = new Intent(context, NotificationReceiver.class);
|
||||
markAsReadIntent.setAction(MARK_AS_READ_ACTION);
|
||||
markAsReadIntent.putExtra(MARK_AS_READ_ID_KEY, notification.getId());
|
||||
// TODO: Replace with something more useful
|
||||
markAsReadIntent.putExtra("title", notification.getTitle());
|
||||
final PendingIntent markAsReadPendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(), 0, readIntent,PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
|
||||
final NotificationCompat.MessagingStyle style = new NotificationCompat.MessagingStyle("Me")
|
||||
.setConversationTitle(notification.getTitle());
|
||||
for (final NotificationMessage message : notification.getMessages()) {
|
||||
// Build the sender of the message
|
||||
final Person.Builder personBuilder = new Person.Builder()
|
||||
.setName(message.getSender())
|
||||
.setKey(message.getJid());
|
||||
if (message.getAvatarPath() != null) {
|
||||
final IconCompat icon = IconCompat.createWithAdaptiveBitmap(
|
||||
BitmapFactory.decodeFile(message.getAvatarPath())
|
||||
);
|
||||
personBuilder.setIcon(icon);
|
||||
}
|
||||
|
||||
// Build the message
|
||||
final String content = message.getContent().getBody() == null ? "" : message.getContent().getBody();
|
||||
final NotificationCompat.MessagingStyle.Message msg = new NotificationCompat.MessagingStyle.Message(
|
||||
content,
|
||||
message.getTimestamp(),
|
||||
personBuilder.build()
|
||||
);
|
||||
// Turn the image path to a content Uri, if a media file was specified
|
||||
if (message.getContent().getMime() != null && message.getContent().getPath() != null) {
|
||||
final Uri fileUri = androidx.core.content.FileProvider.getUriForFile(context, "me.polynom.moxplatform_android.fileprovider", new File(message.getContent().getPath()));
|
||||
msg.setData(message.getContent().getMime(), fileUri);
|
||||
}
|
||||
|
||||
style.addMessage(msg);
|
||||
}
|
||||
|
||||
// Build the notification and send it
|
||||
final NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, notification.getChannelId())
|
||||
.setStyle(style)
|
||||
// TODO: This is wrong
|
||||
.setSmallIcon(R.drawable.ic_service_icon)
|
||||
.addAction(action)
|
||||
.addAction(R.drawable.ic_service_icon, "Mark as read", markAsReadPendingIntent);
|
||||
NotificationManagerCompat.from(context).notify(notification.getId().intValue(), notificationBuilder.build());
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
package me.polynom.moxplatform_android
|
||||
|
||||
import android.app.NotificationManager
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.core.app.RemoteInput
|
||||
|
||||
class NotificationReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
// If it is a mark as read, dismiss the entire notification and
|
||||
// send a notification to the app.
|
||||
// TODO: Notify app
|
||||
if (intent.action == MARK_AS_READ_ACTION) {
|
||||
Log.d("NotificationReceiver", "Marking ${intent.getStringExtra("title")} as read")
|
||||
NotificationManagerCompat.from(context).cancel(intent.getLongExtra(MARK_AS_READ_ID_KEY, -1).toInt())
|
||||
return
|
||||
}
|
||||
|
||||
val remoteInput = RemoteInput.getResultsFromIntent(intent) ?: return
|
||||
|
||||
val title = remoteInput.getCharSequence(REPLY_TEXT_KEY).toString()
|
||||
Log.d("NotificationReceiver", title)
|
||||
// TODO: Notify app
|
||||
}
|
||||
}
|
@ -0,0 +1,520 @@
|
||||
// Autogenerated from Pigeon (v10.1.4), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
|
||||
package me.polynom.moxplatform_android;
|
||||
|
||||
import android.util.Log;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import io.flutter.plugin.common.BasicMessageChannel;
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
import io.flutter.plugin.common.MessageCodec;
|
||||
import io.flutter.plugin.common.StandardMessageCodec;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/** Generated class from Pigeon. */
|
||||
@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"})
|
||||
public class Notifications {
|
||||
|
||||
/** Error class for passing custom error details to Flutter via a thrown PlatformException. */
|
||||
public static class FlutterError extends RuntimeException {
|
||||
|
||||
/** The error code. */
|
||||
public final String code;
|
||||
|
||||
/** The error details. Must be a datatype supported by the api codec. */
|
||||
public final Object details;
|
||||
|
||||
public FlutterError(@NonNull String code, @Nullable String message, @Nullable Object details)
|
||||
{
|
||||
super(message);
|
||||
this.code = code;
|
||||
this.details = details;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected static ArrayList<Object> wrapError(@NonNull Throwable exception) {
|
||||
ArrayList<Object> errorList = new ArrayList<Object>(3);
|
||||
if (exception instanceof FlutterError) {
|
||||
FlutterError error = (FlutterError) exception;
|
||||
errorList.add(error.code);
|
||||
errorList.add(error.getMessage());
|
||||
errorList.add(error.details);
|
||||
} else {
|
||||
errorList.add(exception.toString());
|
||||
errorList.add(exception.getClass().getSimpleName());
|
||||
errorList.add(
|
||||
"Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception));
|
||||
}
|
||||
return errorList;
|
||||
}
|
||||
|
||||
/** Generated class from Pigeon that represents data sent in messages. */
|
||||
public static final class NotificationMessageContent {
|
||||
/** The textual body of the message. */
|
||||
private @Nullable String body;
|
||||
|
||||
public @Nullable String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void setBody(@Nullable String setterArg) {
|
||||
this.body = setterArg;
|
||||
}
|
||||
|
||||
/** The path and mime type of the media to show. */
|
||||
private @Nullable String mime;
|
||||
|
||||
public @Nullable String getMime() {
|
||||
return mime;
|
||||
}
|
||||
|
||||
public void setMime(@Nullable String setterArg) {
|
||||
this.mime = setterArg;
|
||||
}
|
||||
|
||||
private @Nullable String path;
|
||||
|
||||
public @Nullable String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(@Nullable String setterArg) {
|
||||
this.path = setterArg;
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
|
||||
private @Nullable String body;
|
||||
|
||||
public @NonNull Builder setBody(@Nullable String setterArg) {
|
||||
this.body = setterArg;
|
||||
return this;
|
||||
}
|
||||
|
||||
private @Nullable String mime;
|
||||
|
||||
public @NonNull Builder setMime(@Nullable String setterArg) {
|
||||
this.mime = setterArg;
|
||||
return this;
|
||||
}
|
||||
|
||||
private @Nullable String path;
|
||||
|
||||
public @NonNull Builder setPath(@Nullable String setterArg) {
|
||||
this.path = setterArg;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull NotificationMessageContent build() {
|
||||
NotificationMessageContent pigeonReturn = new NotificationMessageContent();
|
||||
pigeonReturn.setBody(body);
|
||||
pigeonReturn.setMime(mime);
|
||||
pigeonReturn.setPath(path);
|
||||
return pigeonReturn;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
ArrayList<Object> toList() {
|
||||
ArrayList<Object> toListResult = new ArrayList<Object>(3);
|
||||
toListResult.add(body);
|
||||
toListResult.add(mime);
|
||||
toListResult.add(path);
|
||||
return toListResult;
|
||||
}
|
||||
|
||||
static @NonNull NotificationMessageContent fromList(@NonNull ArrayList<Object> list) {
|
||||
NotificationMessageContent pigeonResult = new NotificationMessageContent();
|
||||
Object body = list.get(0);
|
||||
pigeonResult.setBody((String) body);
|
||||
Object mime = list.get(1);
|
||||
pigeonResult.setMime((String) mime);
|
||||
Object path = list.get(2);
|
||||
pigeonResult.setPath((String) path);
|
||||
return pigeonResult;
|
||||
}
|
||||
}
|
||||
|
||||
/** Generated class from Pigeon that represents data sent in messages. */
|
||||
public static final class NotificationMessage {
|
||||
/** The sender of the message. */
|
||||
private @NonNull String sender;
|
||||
|
||||
public @NonNull String getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public void setSender(@NonNull String setterArg) {
|
||||
if (setterArg == null) {
|
||||
throw new IllegalStateException("Nonnull field \"sender\" is null.");
|
||||
}
|
||||
this.sender = setterArg;
|
||||
}
|
||||
|
||||
/** The jid of the sender. */
|
||||
private @NonNull String jid;
|
||||
|
||||
public @NonNull String getJid() {
|
||||
return jid;
|
||||
}
|
||||
|
||||
public void setJid(@NonNull String setterArg) {
|
||||
if (setterArg == null) {
|
||||
throw new IllegalStateException("Nonnull field \"jid\" is null.");
|
||||
}
|
||||
this.jid = setterArg;
|
||||
}
|
||||
|
||||
/** The body of the message. */
|
||||
private @NonNull NotificationMessageContent content;
|
||||
|
||||
public @NonNull NotificationMessageContent getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(@NonNull NotificationMessageContent setterArg) {
|
||||
if (setterArg == null) {
|
||||
throw new IllegalStateException("Nonnull field \"content\" is null.");
|
||||
}
|
||||
this.content = setterArg;
|
||||
}
|
||||
|
||||
/** Milliseconds since epoch. */
|
||||
private @NonNull Long timestamp;
|
||||
|
||||
public @NonNull Long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(@NonNull Long setterArg) {
|
||||
if (setterArg == null) {
|
||||
throw new IllegalStateException("Nonnull field \"timestamp\" is null.");
|
||||
}
|
||||
this.timestamp = setterArg;
|
||||
}
|
||||
|
||||
/** The path to the avatar to use */
|
||||
private @Nullable String avatarPath;
|
||||
|
||||
public @Nullable String getAvatarPath() {
|
||||
return avatarPath;
|
||||
}
|
||||
|
||||
public void setAvatarPath(@Nullable String setterArg) {
|
||||
this.avatarPath = setterArg;
|
||||
}
|
||||
|
||||
/** Constructor is non-public to enforce null safety; use Builder. */
|
||||
NotificationMessage() {}
|
||||
|
||||
public static final class Builder {
|
||||
|
||||
private @Nullable String sender;
|
||||
|
||||
public @NonNull Builder setSender(@NonNull String setterArg) {
|
||||
this.sender = setterArg;
|
||||
return this;
|
||||
}
|
||||
|
||||
private @Nullable String jid;
|
||||
|
||||
public @NonNull Builder setJid(@NonNull String setterArg) {
|
||||
this.jid = setterArg;
|
||||
return this;
|
||||
}
|
||||
|
||||
private @Nullable NotificationMessageContent content;
|
||||
|
||||
public @NonNull Builder setContent(@NonNull NotificationMessageContent setterArg) {
|
||||
this.content = setterArg;
|
||||
return this;
|
||||
}
|
||||
|
||||
private @Nullable Long timestamp;
|
||||
|
||||
public @NonNull Builder setTimestamp(@NonNull Long setterArg) {
|
||||
this.timestamp = setterArg;
|
||||
return this;
|
||||
}
|
||||
|
||||
private @Nullable String avatarPath;
|
||||
|
||||
public @NonNull Builder setAvatarPath(@Nullable String setterArg) {
|
||||
this.avatarPath = setterArg;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull NotificationMessage build() {
|
||||
NotificationMessage pigeonReturn = new NotificationMessage();
|
||||
pigeonReturn.setSender(sender);
|
||||
pigeonReturn.setJid(jid);
|
||||
pigeonReturn.setContent(content);
|
||||
pigeonReturn.setTimestamp(timestamp);
|
||||
pigeonReturn.setAvatarPath(avatarPath);
|
||||
return pigeonReturn;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
ArrayList<Object> toList() {
|
||||
ArrayList<Object> toListResult = new ArrayList<Object>(5);
|
||||
toListResult.add(sender);
|
||||
toListResult.add(jid);
|
||||
toListResult.add((content == null) ? null : content.toList());
|
||||
toListResult.add(timestamp);
|
||||
toListResult.add(avatarPath);
|
||||
return toListResult;
|
||||
}
|
||||
|
||||
static @NonNull NotificationMessage fromList(@NonNull ArrayList<Object> list) {
|
||||
NotificationMessage pigeonResult = new NotificationMessage();
|
||||
Object sender = list.get(0);
|
||||
pigeonResult.setSender((String) sender);
|
||||
Object jid = list.get(1);
|
||||
pigeonResult.setJid((String) jid);
|
||||
Object content = list.get(2);
|
||||
pigeonResult.setContent((content == null) ? null : NotificationMessageContent.fromList((ArrayList<Object>) content));
|
||||
Object timestamp = list.get(3);
|
||||
pigeonResult.setTimestamp((timestamp == null) ? null : ((timestamp instanceof Integer) ? (Integer) timestamp : (Long) timestamp));
|
||||
Object avatarPath = list.get(4);
|
||||
pigeonResult.setAvatarPath((String) avatarPath);
|
||||
return pigeonResult;
|
||||
}
|
||||
}
|
||||
|
||||
/** Generated class from Pigeon that represents data sent in messages. */
|
||||
public static final class MessagingNotification {
|
||||
/** The title of the conversation. */
|
||||
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 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 id of the notification channel the notification should appear 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;
|
||||
}
|
||||
|
||||
/** Messages to show. */
|
||||
private @NonNull List<NotificationMessage> messages;
|
||||
|
||||
public @NonNull List<NotificationMessage> getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public void setMessages(@NonNull List<NotificationMessage> setterArg) {
|
||||
if (setterArg == null) {
|
||||
throw new IllegalStateException("Nonnull field \"messages\" is null.");
|
||||
}
|
||||
this.messages = setterArg;
|
||||
}
|
||||
|
||||
/** Constructor is non-public to enforce null safety; use Builder. */
|
||||
MessagingNotification() {}
|
||||
|
||||
public static final class Builder {
|
||||
|
||||
private @Nullable String title;
|
||||
|
||||
public @NonNull Builder setTitle(@NonNull String setterArg) {
|
||||
this.title = setterArg;
|
||||
return this;
|
||||
}
|
||||
|
||||
private @Nullable Long id;
|
||||
|
||||
public @NonNull Builder setId(@NonNull Long setterArg) {
|
||||
this.id = setterArg;
|
||||
return this;
|
||||
}
|
||||
|
||||
private @Nullable String channelId;
|
||||
|
||||
public @NonNull Builder setChannelId(@NonNull String setterArg) {
|
||||
this.channelId = setterArg;
|
||||
return this;
|
||||
}
|
||||
|
||||
private @Nullable List<NotificationMessage> messages;
|
||||
|
||||
public @NonNull Builder setMessages(@NonNull List<NotificationMessage> setterArg) {
|
||||
this.messages = setterArg;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull MessagingNotification build() {
|
||||
MessagingNotification pigeonReturn = new MessagingNotification();
|
||||
pigeonReturn.setTitle(title);
|
||||
pigeonReturn.setId(id);
|
||||
pigeonReturn.setChannelId(channelId);
|
||||
pigeonReturn.setMessages(messages);
|
||||
return pigeonReturn;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
ArrayList<Object> toList() {
|
||||
ArrayList<Object> toListResult = new ArrayList<Object>(4);
|
||||
toListResult.add(title);
|
||||
toListResult.add(id);
|
||||
toListResult.add(channelId);
|
||||
toListResult.add(messages);
|
||||
return toListResult;
|
||||
}
|
||||
|
||||
static @NonNull MessagingNotification fromList(@NonNull ArrayList<Object> list) {
|
||||
MessagingNotification pigeonResult = new MessagingNotification();
|
||||
Object title = list.get(0);
|
||||
pigeonResult.setTitle((String) title);
|
||||
Object id = list.get(1);
|
||||
pigeonResult.setId((id == null) ? null : ((id instanceof Integer) ? (Integer) id : (Long) id));
|
||||
Object channelId = list.get(2);
|
||||
pigeonResult.setChannelId((String) channelId);
|
||||
Object messages = list.get(3);
|
||||
pigeonResult.setMessages((List<NotificationMessage>) messages);
|
||||
return pigeonResult;
|
||||
}
|
||||
}
|
||||
|
||||
private static class NotificationsImplementationApiCodec extends StandardMessageCodec {
|
||||
public static final NotificationsImplementationApiCodec INSTANCE = new NotificationsImplementationApiCodec();
|
||||
|
||||
private NotificationsImplementationApiCodec() {}
|
||||
|
||||
@Override
|
||||
protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
|
||||
switch (type) {
|
||||
case (byte) 128:
|
||||
return MessagingNotification.fromList((ArrayList<Object>) readValue(buffer));
|
||||
case (byte) 129:
|
||||
return NotificationMessage.fromList((ArrayList<Object>) readValue(buffer));
|
||||
case (byte) 130:
|
||||
return NotificationMessageContent.fromList((ArrayList<Object>) readValue(buffer));
|
||||
default:
|
||||
return super.readValueOfType(type, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
|
||||
if (value instanceof MessagingNotification) {
|
||||
stream.write(128);
|
||||
writeValue(stream, ((MessagingNotification) value).toList());
|
||||
} else if (value instanceof NotificationMessage) {
|
||||
stream.write(129);
|
||||
writeValue(stream, ((NotificationMessage) value).toList());
|
||||
} else if (value instanceof NotificationMessageContent) {
|
||||
stream.write(130);
|
||||
writeValue(stream, ((NotificationMessageContent) value).toList());
|
||||
} else {
|
||||
super.writeValue(stream, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||
public interface NotificationsImplementationApi {
|
||||
|
||||
void createNotificationChannel(@NonNull String title, @NonNull String id, @NonNull Boolean urgent);
|
||||
|
||||
void showMessagingNotification(@NonNull MessagingNotification notification);
|
||||
|
||||
/** The codec used by NotificationsImplementationApi. */
|
||||
static @NonNull MessageCodec<Object> getCodec() {
|
||||
return NotificationsImplementationApiCodec.INSTANCE;
|
||||
}
|
||||
/**Sets up an instance of `NotificationsImplementationApi` to handle messages through the `binaryMessenger`. */
|
||||
static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable NotificationsImplementationApi api) {
|
||||
{
|
||||
BasicMessageChannel<Object> channel =
|
||||
new BasicMessageChannel<>(
|
||||
binaryMessenger, "dev.flutter.pigeon.moxplatform_platform_interface.NotificationsImplementationApi.createNotificationChannel", getCodec());
|
||||
if (api != null) {
|
||||
channel.setMessageHandler(
|
||||
(message, reply) -> {
|
||||
ArrayList<Object> wrapped = new ArrayList<Object>();
|
||||
ArrayList<Object> args = (ArrayList<Object>) message;
|
||||
String titleArg = (String) args.get(0);
|
||||
String idArg = (String) args.get(1);
|
||||
Boolean urgentArg = (Boolean) args.get(2);
|
||||
try {
|
||||
api.createNotificationChannel(titleArg, idArg, urgentArg);
|
||||
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.NotificationsImplementationApi.showMessagingNotification", getCodec());
|
||||
if (api != null) {
|
||||
channel.setMessageHandler(
|
||||
(message, reply) -> {
|
||||
ArrayList<Object> wrapped = new ArrayList<Object>();
|
||||
ArrayList<Object> args = (ArrayList<Object>) message;
|
||||
MessagingNotification notificationArg = (MessagingNotification) args.get(0);
|
||||
try {
|
||||
api.showMessagingNotification(notificationArg);
|
||||
wrapped.add(0, null);
|
||||
}
|
||||
catch (Throwable exception) {
|
||||
ArrayList<Object> wrappedError = wrapError(exception);
|
||||
wrapped = wrappedError;
|
||||
}
|
||||
reply.reply(wrapped);
|
||||
});
|
||||
} else {
|
||||
channel.setMessageHandler(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- For testing -->
|
||||
<cache-path name="file_picker" path="file_picker/"/>
|
||||
</paths>
|
@ -0,0 +1,17 @@
|
||||
import 'package:moxplatform_platform_interface/moxplatform_platform_interface.dart';
|
||||
|
||||
class AndroidNotificationsImplementation extends NotificationsImplementation {
|
||||
final NotificationsImplementationApi _api = NotificationsImplementationApi();
|
||||
|
||||
|
||||
@override
|
||||
Future<void> createNotificationChannel(String title, String id, bool urgent) async {
|
||||
return _api.createNotificationChannel(title, id, urgent);
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Future<void> showMessagingNotification(MessagingNotification notification) async {
|
||||
return _api.showMessagingNotification(notification);
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ import 'package:moxplatform_android/src/contacts_android.dart';
|
||||
import 'package:moxplatform_android/src/crypto_android.dart';
|
||||
import 'package:moxplatform_android/src/isolate_android.dart';
|
||||
import 'package:moxplatform_android/src/media_android.dart';
|
||||
import 'package:moxplatform_android/src/notifications_android.dart';
|
||||
import 'package:moxplatform_platform_interface/moxplatform_platform_interface.dart';
|
||||
|
||||
class MoxplatformAndroidPlugin extends MoxplatformInterface {
|
||||
@ -12,6 +13,7 @@ class MoxplatformAndroidPlugin extends MoxplatformInterface {
|
||||
MoxplatformInterface.crypto = AndroidCryptographyImplementation();
|
||||
MoxplatformInterface.handler = AndroidIsolateHandler();
|
||||
MoxplatformInterface.media = AndroidMediaScannerImplementation();
|
||||
MoxplatformInterface.notifications = AndroidNotificationsImplementation();
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -41,4 +41,5 @@ dependencies:
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
pigeon: 10.1.4
|
||||
very_good_analysis: ^3.0.1
|
||||
|
@ -9,4 +9,7 @@ export 'src/isolate.dart';
|
||||
export 'src/isolate_stub.dart';
|
||||
export 'src/media.dart';
|
||||
export 'src/media_stub.dart';
|
||||
export 'src/notifications.dart';
|
||||
export 'src/notifications.g.dart';
|
||||
export 'src/notifications_stub.dart';
|
||||
export 'src/service.dart';
|
||||
|
@ -6,6 +6,8 @@ import 'package:moxplatform_platform_interface/src/isolate.dart';
|
||||
import 'package:moxplatform_platform_interface/src/isolate_stub.dart';
|
||||
import 'package:moxplatform_platform_interface/src/media.dart';
|
||||
import 'package:moxplatform_platform_interface/src/media_stub.dart';
|
||||
import 'package:moxplatform_platform_interface/src/notifications.dart';
|
||||
import 'package:moxplatform_platform_interface/src/notifications_stub.dart';
|
||||
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
||||
|
||||
abstract class MoxplatformInterface extends PlatformInterface {
|
||||
@ -17,6 +19,7 @@ abstract class MoxplatformInterface extends PlatformInterface {
|
||||
static MediaScannerImplementation media = StubMediaScannerImplementation();
|
||||
static CryptographyImplementation crypto = StubCryptographyImplementation();
|
||||
static ContactsImplementation contacts = StubContactsImplementation();
|
||||
static NotificationsImplementation notifications = StubNotificationsImplementation();
|
||||
|
||||
/// Return the current platform name.
|
||||
Future<String?> getPlatformName();
|
||||
|
@ -0,0 +1,7 @@
|
||||
import 'package:moxplatform_platform_interface/src/notifications.g.dart';
|
||||
|
||||
abstract class NotificationsImplementation {
|
||||
Future<void> createNotificationChannel(String title, String id, bool urgent);
|
||||
|
||||
Future<void> showMessagingNotification(MessagingNotification notification);
|
||||
}
|
@ -0,0 +1,216 @@
|
||||
// Autogenerated from Pigeon (v10.1.4), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
|
||||
|
||||
import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class NotificationMessageContent {
|
||||
NotificationMessageContent({
|
||||
this.body,
|
||||
this.mime,
|
||||
this.path,
|
||||
});
|
||||
|
||||
/// The textual body of the message.
|
||||
String? body;
|
||||
|
||||
/// The path and mime type of the media to show.
|
||||
String? mime;
|
||||
|
||||
String? path;
|
||||
|
||||
Object encode() {
|
||||
return <Object?>[
|
||||
body,
|
||||
mime,
|
||||
path,
|
||||
];
|
||||
}
|
||||
|
||||
static NotificationMessageContent decode(Object result) {
|
||||
result as List<Object?>;
|
||||
return NotificationMessageContent(
|
||||
body: result[0] as String?,
|
||||
mime: result[1] as String?,
|
||||
path: result[2] as String?,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NotificationMessage {
|
||||
NotificationMessage({
|
||||
required this.sender,
|
||||
required this.jid,
|
||||
required this.content,
|
||||
required this.timestamp,
|
||||
this.avatarPath,
|
||||
});
|
||||
|
||||
/// The sender of the message.
|
||||
String sender;
|
||||
|
||||
/// The jid of the sender.
|
||||
String jid;
|
||||
|
||||
/// The body of the message.
|
||||
NotificationMessageContent content;
|
||||
|
||||
/// Milliseconds since epoch.
|
||||
int timestamp;
|
||||
|
||||
/// The path to the avatar to use
|
||||
String? avatarPath;
|
||||
|
||||
Object encode() {
|
||||
return <Object?>[
|
||||
sender,
|
||||
jid,
|
||||
content.encode(),
|
||||
timestamp,
|
||||
avatarPath,
|
||||
];
|
||||
}
|
||||
|
||||
static NotificationMessage decode(Object result) {
|
||||
result as List<Object?>;
|
||||
return NotificationMessage(
|
||||
sender: result[0]! as String,
|
||||
jid: result[1]! as String,
|
||||
content: NotificationMessageContent.decode(result[2]! as List<Object?>),
|
||||
timestamp: result[3]! as int,
|
||||
avatarPath: result[4] as String?,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MessagingNotification {
|
||||
MessagingNotification({
|
||||
required this.title,
|
||||
required this.id,
|
||||
required this.channelId,
|
||||
required this.messages,
|
||||
});
|
||||
|
||||
/// The title of the conversation.
|
||||
String title;
|
||||
|
||||
/// The id of the notification.
|
||||
int id;
|
||||
|
||||
/// The id of the notification channel the notification should appear on.
|
||||
String channelId;
|
||||
|
||||
/// Messages to show.
|
||||
List<NotificationMessage?> messages;
|
||||
|
||||
Object encode() {
|
||||
return <Object?>[
|
||||
title,
|
||||
id,
|
||||
channelId,
|
||||
messages,
|
||||
];
|
||||
}
|
||||
|
||||
static MessagingNotification decode(Object result) {
|
||||
result as List<Object?>;
|
||||
return MessagingNotification(
|
||||
title: result[0]! as String,
|
||||
id: result[1]! as int,
|
||||
channelId: result[2]! as String,
|
||||
messages: (result[3] as List<Object?>?)!.cast<NotificationMessage?>(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _NotificationsImplementationApiCodec extends StandardMessageCodec {
|
||||
const _NotificationsImplementationApiCodec();
|
||||
@override
|
||||
void writeValue(WriteBuffer buffer, Object? value) {
|
||||
if (value is MessagingNotification) {
|
||||
buffer.putUint8(128);
|
||||
writeValue(buffer, value.encode());
|
||||
} else if (value is NotificationMessage) {
|
||||
buffer.putUint8(129);
|
||||
writeValue(buffer, value.encode());
|
||||
} else if (value is NotificationMessageContent) {
|
||||
buffer.putUint8(130);
|
||||
writeValue(buffer, value.encode());
|
||||
} else {
|
||||
super.writeValue(buffer, value);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Object? readValueOfType(int type, ReadBuffer buffer) {
|
||||
switch (type) {
|
||||
case 128:
|
||||
return MessagingNotification.decode(readValue(buffer)!);
|
||||
case 129:
|
||||
return NotificationMessage.decode(readValue(buffer)!);
|
||||
case 130:
|
||||
return NotificationMessageContent.decode(readValue(buffer)!);
|
||||
default:
|
||||
return super.readValueOfType(type, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class NotificationsImplementationApi {
|
||||
/// Constructor for [NotificationsImplementationApi]. The [binaryMessenger] named argument is
|
||||
/// available for dependency injection. If it is left null, the default
|
||||
/// BinaryMessenger will be used which routes to the host platform.
|
||||
NotificationsImplementationApi({BinaryMessenger? binaryMessenger})
|
||||
: _binaryMessenger = binaryMessenger;
|
||||
final BinaryMessenger? _binaryMessenger;
|
||||
|
||||
static const MessageCodec<Object?> codec = _NotificationsImplementationApiCodec();
|
||||
|
||||
Future<void> createNotificationChannel(String arg_title, String arg_id, bool arg_urgent) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.moxplatform_platform_interface.NotificationsImplementationApi.createNotificationChannel', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_title, arg_id, arg_urgent]) 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> showMessagingNotification(MessagingNotification arg_notification) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.moxplatform_platform_interface.NotificationsImplementationApi.showMessagingNotification', 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
import 'package:moxplatform_platform_interface/src/notifications.g.dart';
|
||||
import 'package:moxplatform_platform_interface/src/notifications.dart';
|
||||
|
||||
class StubNotificationsImplementation extends NotificationsImplementation {
|
||||
@override
|
||||
Future<void> createNotificationChannel(String title, String id, bool urgent) async {}
|
||||
|
||||
@override
|
||||
Future<void> showMessagingNotification(MessagingNotification notification) async {}
|
||||
}
|
77
pigeons/notifications.dart
Normal file
77
pigeons/notifications.dart
Normal file
@ -0,0 +1,77 @@
|
||||
import 'package:pigeon/pigeon.dart';
|
||||
|
||||
@ConfigurePigeon(
|
||||
PigeonOptions(
|
||||
dartOut: 'packages/moxplatform_platform_interface/lib/src/notifications.g.dart',
|
||||
//kotlinOut: 'packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/Notifications.g.kt',
|
||||
//kotlinOptions: KotlinOptions(
|
||||
// package: 'me.polynom.moxplatform_android',
|
||||
//),
|
||||
javaOut: 'packages/moxplatform_android/android/src/main/java/me/polynom/moxplatform_android/Notifications.java',
|
||||
javaOptions: JavaOptions(
|
||||
package: 'me.polynom.moxplatform_android',
|
||||
),
|
||||
),
|
||||
)
|
||||
class NotificationMessageContent {
|
||||
const NotificationMessageContent(
|
||||
this.body,
|
||||
this.mime,
|
||||
this.path,
|
||||
);
|
||||
|
||||
/// The textual body of the message.
|
||||
final String? body;
|
||||
|
||||
/// The path and mime type of the media to show.
|
||||
final String? mime;
|
||||
final String? path;
|
||||
}
|
||||
|
||||
class NotificationMessage {
|
||||
const NotificationMessage(
|
||||
this.sender,
|
||||
this.content,
|
||||
this.jid,
|
||||
this.timestamp,
|
||||
this.avatarPath,
|
||||
);
|
||||
|
||||
/// The sender of the message.
|
||||
final String sender;
|
||||
|
||||
/// The jid of the sender.
|
||||
final String jid;
|
||||
|
||||
/// The body of the message.
|
||||
final NotificationMessageContent content;
|
||||
|
||||
/// Milliseconds since epoch.
|
||||
final int timestamp;
|
||||
|
||||
/// The path to the avatar to use
|
||||
final String? avatarPath;
|
||||
}
|
||||
|
||||
class MessagingNotification {
|
||||
const MessagingNotification(this.title, this.id, this.messages, this.channelId);
|
||||
|
||||
/// The title of the conversation.
|
||||
final String title;
|
||||
|
||||
/// The id of the notification.
|
||||
final int id;
|
||||
|
||||
/// The id of the notification channel the notification should appear on.
|
||||
final String channelId;
|
||||
|
||||
/// Messages to show.
|
||||
final List<NotificationMessage?> messages;
|
||||
}
|
||||
|
||||
@HostApi()
|
||||
abstract class NotificationsImplementationApi {
|
||||
void createNotificationChannel(String title, String id, bool urgent);
|
||||
|
||||
void showMessagingNotification(MessagingNotification notification);
|
||||
}
|
@ -4,3 +4,4 @@ environment:
|
||||
sdk: '>=2.18.0 <3.0.0'
|
||||
dev_dependencies:
|
||||
melos: ^3.1.1
|
||||
pigeon: 10.1.4
|
||||
|
Reference in New Issue
Block a user