forked from MaikuB/flutter_local_notifications
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[flutter_local_notifications ] Notification actions for iOS, macOS, A…
…ndroid (MaikuB#880) * WIP - engine starts and executes dispatcher * Ensure Dart side can receive notification callback in a simple handler with a ID parameter * iOS implementation * Update tests * Configure action icons * Support text actions on iOS & Android * Support additional properties to fine-tune the notification action display * Docs & cleanups * typo * submit notification payload in action callback as well * Commit objc and swift formatting * Google Java Format * Clang Format * Fix notification payload not updating on android * Add notification id to background handler Google Java Format * Fix clashing request codes * Replace result param usage with completion handler * Improve example project * xcode version update * Clang Format * Adds custom color support for Android action labels * Adds basic macos support * Swift Format * Clang Format * Unit test on Android * CI update to run android unit tests * use symlinks * Google Java Format * add action handler support for macOS * Swift Format * update example app to demonstrate usage of IsolateNameServer so action can trigger navigation * Clang Format * Clang Format * restore link * Formatting * WIP * Restore iOS' FlutterEngineManager * formatting * apply compat annotaiton suggestion * Some docs about notification categories on mac/ios * restore symlink * Ensure to map options properly, add test * add url_launcher example * Fix Dart tests * attempt to fix android unit tests * Attempt to speed up integration test task * only build debug app on android * Add new `cancelNotification` flag, add various tests & refactor a bit * Google Java Format * ensure text input works on macos * Swift Format Co-authored-by: Pieter van Loon <git@pietervanloon.com> Co-authored-by: github-actions <> Co-authored-by: runner <runner@Mac-1637669235868.local> Co-authored-by: runner <runner@Mac-1640723570985.local> Co-authored-by: runner <runner@Mac-1640810998232.local> Co-authored-by: runner <runner@Mac-1640847178272.local> Co-authored-by: runner <runner@Mac-1640857501835.local> Co-authored-by: Michael Bui <25263378+MaikuB@users.noreply.github.com> Co-authored-by: runner <runner@Mac-1640921172953.local> Co-authored-by: runner <runner@Mac-1640934619690.local> Co-authored-by: runner <runner@Mac-1641162978390.local>
- Loading branch information
1 parent
794c121
commit 8e1ad8e
Showing
66 changed files
with
2,755 additions
and
285 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
144 changes: 144 additions & 0 deletions
144
...ndroid/src/main/java/com/dexterous/flutterlocalnotifications/ActionBroadcastReceiver.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
package com.dexterous.flutterlocalnotifications; | ||
|
||
import android.content.BroadcastReceiver; | ||
import android.content.Context; | ||
import android.content.Intent; | ||
import android.os.Bundle; | ||
import androidx.annotation.Keep; | ||
import androidx.annotation.Nullable; | ||
import androidx.annotation.VisibleForTesting; | ||
import androidx.core.app.NotificationManagerCompat; | ||
import androidx.core.app.RemoteInput; | ||
import com.dexterous.flutterlocalnotifications.isolate.IsolatePreferences; | ||
import io.flutter.FlutterInjector; | ||
import io.flutter.embedding.engine.FlutterEngine; | ||
import io.flutter.embedding.engine.dart.DartExecutor; | ||
import io.flutter.embedding.engine.loader.FlutterLoader; | ||
import io.flutter.plugin.common.EventChannel; | ||
import io.flutter.plugin.common.EventChannel.EventSink; | ||
import io.flutter.plugin.common.EventChannel.StreamHandler; | ||
import io.flutter.view.FlutterCallbackInformation; | ||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class ActionBroadcastReceiver extends BroadcastReceiver { | ||
@VisibleForTesting | ||
ActionBroadcastReceiver(IsolatePreferences preferences) { | ||
this.preferences = preferences; | ||
} | ||
|
||
@Keep | ||
public ActionBroadcastReceiver() {} | ||
|
||
IsolatePreferences preferences; | ||
|
||
public static final String ACTION_TAPPED = | ||
"com.dexterous.flutterlocalnotifications.ActionBroadcastReceiver.ACTION_TAPPED"; | ||
public static final String ACTION_ID = "actionId"; | ||
public static final String NOTIFICATION_ID = "notificationId"; | ||
private static final String INPUT = "input"; | ||
|
||
public static final String INPUT_RESULT = "FlutterLocalNotificationsPluginInputResult"; | ||
|
||
@Nullable private static ActionEventSink actionEventSink; | ||
|
||
@Nullable private static FlutterEngine engine; | ||
|
||
@Override | ||
public void onReceive(Context context, Intent intent) { | ||
if (!ACTION_TAPPED.equalsIgnoreCase(intent.getAction())) { | ||
return; | ||
} | ||
|
||
preferences = preferences == null ? new IsolatePreferences(context) : preferences; | ||
|
||
final Map<String, Object> action = new HashMap<>(); | ||
final int notificationId = intent.getIntExtra(NOTIFICATION_ID, -1); | ||
action.put(NOTIFICATION_ID, notificationId); | ||
action.put( | ||
ACTION_ID, intent.hasExtra(ACTION_ID) ? intent.getStringExtra(ACTION_ID) : "unknown"); | ||
action.put( | ||
FlutterLocalNotificationsPlugin.PAYLOAD, | ||
intent.hasExtra(FlutterLocalNotificationsPlugin.PAYLOAD) | ||
? intent.getStringExtra(FlutterLocalNotificationsPlugin.PAYLOAD) | ||
: ""); | ||
|
||
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent); | ||
if (remoteInput != null) { | ||
action.put(INPUT, remoteInput.getString(INPUT_RESULT)); | ||
} else { | ||
action.put(INPUT, ""); | ||
} | ||
|
||
if (intent.getBooleanExtra(FlutterLocalNotificationsPlugin.CANCEL_NOTIFICATION, false)) { | ||
NotificationManagerCompat.from(context).cancel(notificationId); | ||
} | ||
|
||
if (actionEventSink == null) { | ||
actionEventSink = new ActionEventSink(); | ||
} | ||
actionEventSink.addItem(action); | ||
|
||
startEngine(context); | ||
} | ||
|
||
private static class ActionEventSink implements StreamHandler { | ||
|
||
final List<Map<String, Object>> cache = new ArrayList<>(); | ||
|
||
@Nullable private EventSink eventSink; | ||
|
||
public void addItem(Map<String, Object> item) { | ||
if (eventSink != null) { | ||
eventSink.success(item); | ||
} else { | ||
cache.add(item); | ||
} | ||
} | ||
|
||
@Override | ||
public void onListen(Object arguments, EventSink events) { | ||
for (Map<String, Object> item : cache) { | ||
events.success(item); | ||
} | ||
|
||
cache.clear(); | ||
eventSink = events; | ||
} | ||
|
||
@Override | ||
public void onCancel(Object arguments) { | ||
eventSink = null; | ||
} | ||
} | ||
|
||
private void startEngine(Context context) { | ||
FlutterCallbackInformation dispatcherHandle = preferences.lookupDispatcherHandle(); | ||
|
||
if (dispatcherHandle != null && engine == null) { | ||
FlutterInjector injector = FlutterInjector.instance(); | ||
FlutterLoader loader = injector.flutterLoader(); | ||
|
||
loader.startInitialization(context); | ||
loader.ensureInitializationComplete(context, null); | ||
|
||
engine = new FlutterEngine(context); | ||
|
||
String dartBundlePath = loader.findAppBundlePath(); | ||
|
||
EventChannel channel = | ||
new EventChannel( | ||
engine.getDartExecutor().getBinaryMessenger(), | ||
"dexterous.com/flutter/local_notifications/actions"); | ||
|
||
channel.setStreamHandler(actionEventSink); | ||
|
||
engine | ||
.getDartExecutor() | ||
.executeDartCallback( | ||
new DartExecutor.DartCallback(context.getAssets(), dartBundlePath, dispatcherHandle)); | ||
} | ||
} | ||
} |
Oops, something went wrong.