Skip to content

Commit 15ca07e

Browse files
committed
conversation shortcut implemented
1 parent 11383ff commit 15ca07e

File tree

5 files changed

+186
-56
lines changed

5 files changed

+186
-56
lines changed

android/.settings/org.eclipse.buildship.core.prefs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
arguments=
22
auto.sync=false
33
build.scans.enabled=false
4-
connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(6.8))
5-
connection.project.dir=../example/android
4+
connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(7.1.1))
5+
connection.project.dir=
66
eclipse.preferences.version=1
77
gradle.user.home=
88
java.home=C\:/Program Files/AdoptOpenJDK/jdk-15.0.2.7-hotspot

android/src/main/java/com/divyanshushekhar/flutter_shortcuts/MethodCallImplementation.java

Lines changed: 112 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import androidx.annotation.NonNull;
1717
import androidx.annotation.RequiresApi;
18+
import androidx.core.app.Person;
1819
import androidx.core.content.pm.ShortcutInfoCompat;
1920
import androidx.core.content.pm.ShortcutManagerCompat;
2021
import androidx.core.graphics.drawable.IconCompat;
@@ -146,7 +147,7 @@ private Map<String, Integer> getIconProperties() {
146147

147148
@RequiresApi(api = Build.VERSION_CODES.N_MR1)
148149
private void setShortcutItems(MethodCall call) {
149-
List<Map<String, String>> args = call.arguments();
150+
List<Map<String, Object>> args = call.arguments();
150151
List<ShortcutInfoCompat> shortcuts;
151152
try {
152153
shortcuts = shortcutInfoCompatList(args);
@@ -159,7 +160,7 @@ private void setShortcutItems(MethodCall call) {
159160

160161
@RequiresApi(api = Build.VERSION_CODES.N_MR1)
161162
private void pushShortcutItem(MethodCall call) {
162-
final List<Map<String, String>> args = call.arguments();
163+
final List<Map<String, Object>> args = call.arguments();
163164
List<ShortcutInfoCompat> shortcuts;
164165
try {
165166
shortcuts = shortcutInfoCompatList(args);
@@ -172,7 +173,7 @@ private void pushShortcutItem(MethodCall call) {
172173

173174
@RequiresApi(api = Build.VERSION_CODES.N_MR1)
174175
private void pushShortcutItems(MethodCall call) {
175-
final List<Map<String, String>> args = call.arguments();
176+
final List<Map<String, Object>> args = call.arguments();
176177
List<ShortcutInfoCompat> shortcuts;
177178
try {
178179
shortcuts = shortcutInfoCompatList(args);
@@ -185,7 +186,7 @@ private void pushShortcutItems(MethodCall call) {
185186

186187
@RequiresApi(api = Build.VERSION_CODES.N_MR1)
187188
private void updateShortcutItems(MethodCall call) {
188-
List<Map<String, String>> args = call.arguments();
189+
List<Map<String, Object>> args = call.arguments();
189190
boolean updated = false;
190191
try {
191192
List<ShortcutInfoCompat> updateShortcuts = shortcutInfoCompatList(args);
@@ -202,14 +203,18 @@ private void updateShortcutItems(MethodCall call) {
202203

203204
@RequiresApi(api = Build.VERSION_CODES.N_MR1)
204205
private void updateShortcutItem(MethodCall call) {
205-
final List<Map<String, String>> args = call.arguments();
206-
Map<String, String> info = args.get(0);
207-
final String id = info.get("id");
208-
final String icon = info.get("icon");
209-
final String action = info.get("action");
210-
final String shortLabel = info.get("shortLabel");
211-
final String longLabel = info.get("LongLabel");
212-
final int iconType = Integer.parseInt(Objects.requireNonNull(info.get("shortcutIconType")));
206+
final List<Map<String, Object>> args = call.arguments();
207+
Map<String, Object> info = args.get(0);
208+
final String id = (String) info.get("id");
209+
final String icon = (String) info.get("icon");
210+
final String action = (String) info.get("action");
211+
final String shortLabel = (String) info.get("shortLabel");
212+
final String longLabel = (String) info.get("LongLabel");
213+
final int iconType = Integer.parseInt(Objects.requireNonNull( (String) info.get("shortcutIconType")));
214+
215+
final boolean isImportant = (boolean) info.get("isImportant");
216+
final boolean isBot = (boolean) info.get("isBot");
217+
final boolean isConversationShortcut = (boolean) info.get("conversationShortcut");
213218

214219
List<ShortcutInfoCompat> dynamicShortcuts = ShortcutManagerCompat.getDynamicShortcuts(context);
215220
final List<ShortcutInfoCompat> shortcutList = new ArrayList<>();
@@ -218,6 +223,24 @@ private void updateShortcutItem(MethodCall call) {
218223
if(si.getId().equals(id)) {
219224
ShortcutInfoCompat.Builder shortcutInfo = buildShortcutUsingCompat(
220225
id,icon,action,shortLabel,longLabel,iconType);
226+
227+
// Set Person if isConversationShortcut is true
228+
if(isConversationShortcut) {
229+
Person.Builder personBuilder = new Person.Builder()
230+
.setKey(id)
231+
.setName(shortLabel)
232+
.setImportant(isImportant)
233+
.setBot(isBot);
234+
235+
// Setting Icon for person builder
236+
setIconCompat(iconType, icon, personBuilder);
237+
238+
shortcutInfo
239+
.setLongLived(true)
240+
.setPerson(personBuilder.build());
241+
242+
}
243+
221244
shortcutList.add(shortcutInfo.build());
222245
flag = 0;
223246
continue;
@@ -255,7 +278,9 @@ private void changeShortcutItemIcon(MethodCall call) {
255278
String shortLabel = (String) si.getShortLabel();
256279
String longLabel = (String) si.getLongLabel();
257280

258-
ShortcutInfoCompat.Builder shortcutInfo = buildShortcutUsingCompat(id,null,null,shortLabel,longLabel,0);
281+
ShortcutInfoCompat.Builder shortcutInfo = buildShortcutUsingCompat(
282+
id,null,null,shortLabel,longLabel,0);
283+
259284
shortcutInfo.setIcon(iconCompat).setIntent(si.getIntent());
260285
shortcutList.add(shortcutInfo.build());
261286
flag = 0;
@@ -278,40 +303,61 @@ private void changeShortcutItemIcon(MethodCall call) {
278303
}
279304
}
280305

281-
282306
/* ******************** Utility Functions ********************* */
283307

284308
@RequiresApi(api = Build.VERSION_CODES.N_MR1)
285-
private List<ShortcutInfoCompat> shortcutInfoCompatList(List<Map<String, String>> shortcuts) {
309+
private List<ShortcutInfoCompat> shortcutInfoCompatList(
310+
List<Map<String, Object>> shortcuts) {
286311
final List<ShortcutInfoCompat> shortcutList = new ArrayList<>();
287312

288-
for (Map<String, String> shortcut : shortcuts) {
289-
final String id = shortcut.get("id");
290-
final String icon = shortcut.get("icon");
291-
final String action = shortcut.get("action");
292-
final String shortLabel = shortcut.get("shortLabel");
293-
final String longLabel = shortcut.get("LongLabel");
313+
for (Map<String, Object> shortcut : shortcuts) {
314+
final String id = (String) shortcut.get("id");
315+
final String icon = (String) shortcut.get("icon");
316+
final String action = (String) shortcut.get("action");
317+
318+
// Short Label for the shortcut
319+
// Name for Person
320+
final String shortLabel = (String) shortcut.get("shortLabel");
321+
322+
// Long Label for the shortcut
323+
final String longLabel = (String) shortcut.get("LongLabel");
324+
325+
final boolean isImportant = (boolean) shortcut.get("isImportant");
326+
final boolean isBot = (boolean) shortcut.get("isBot");
327+
final boolean isConversationShortcut = (boolean) shortcut.get("conversationShortcut");
328+
294329
final int iconType = Integer.parseInt(Objects.requireNonNull(
295-
shortcut.get("shortcutIconType")));
330+
(String) shortcut.get("shortcutIconType")));
331+
296332
ShortcutInfoCompat.Builder shortcutInfoCompat = buildShortcutUsingCompat(
297-
id,
298-
icon,
299-
action,
300-
shortLabel,
301-
longLabel,
302-
iconType);
333+
id, icon, action, shortLabel, longLabel, iconType);
334+
335+
// Set Person if isConversationShortcut is true
336+
if(isConversationShortcut) {
337+
Person.Builder personBuilder = new Person.Builder()
338+
.setKey(id)
339+
.setName(shortLabel)
340+
.setImportant(isImportant)
341+
.setBot(isBot);
342+
343+
// Setting Icon for person builder
344+
setIconCompat(iconType, icon, personBuilder);
345+
346+
shortcutInfoCompat
347+
.setLongLived(true)
348+
.setPerson(personBuilder.build());
349+
350+
}
351+
303352
shortcutList.add(shortcutInfoCompat.build());
304353
}
305354
return shortcutList;
306355
}
307356

308357
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
309-
private ShortcutInfoCompat.Builder buildShortcutUsingCompat(String id,
310-
String icon,
311-
String action,
312-
String shortLabel,
313-
String longLabel,
314-
int iconType) {
358+
private ShortcutInfoCompat.Builder buildShortcutUsingCompat(
359+
String id, String icon, String action, String shortLabel,
360+
String longLabel, int iconType) {
315361

316362
assert id != null;
317363
ShortcutInfoCompat.Builder shortcutInfoCompat = new ShortcutInfoCompat.Builder(context, id);
@@ -337,6 +383,7 @@ private ShortcutInfoCompat.Builder buildShortcutUsingCompat(String id,
337383
return shortcutInfoCompat;
338384
}
339385

386+
/* *********************** ShortcutInfoCompat ******************* */
340387
private void setIconCompat(int iconType,String icon,ShortcutInfoCompat.Builder shortcutBuilderCompat) {
341388
// 0 - ShortcutIconType.androidAsset
342389
// 1 - ShortcutIconType.flutterAsset
@@ -367,6 +414,37 @@ private void setIconFromFlutterCompat(ShortcutInfoCompat.Builder shortcutBuilder
367414
}
368415
}
369416

417+
/* *********************** Person ******************* */
418+
private void setIconCompat(int iconType,String icon,Person.Builder personBuilderCompat) {
419+
// 0 - ShortcutIconType.androidAsset
420+
// 1 - ShortcutIconType.flutterAsset
421+
switch (iconType) {
422+
case 0:
423+
setIconFromNativeCompat(personBuilderCompat, icon);
424+
break;
425+
case 1:
426+
setIconFromFlutterCompat(personBuilderCompat, icon);
427+
break;
428+
default:
429+
break;
430+
}
431+
}
432+
433+
private void setIconFromNativeCompat(Person.Builder personBuilder, String icon) {
434+
final int resourceId = loadResourceId(context, icon);
435+
if (resourceId > 0) {
436+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
437+
personBuilder.setIcon(IconCompat.createFromIcon(context,Icon.createWithResource(context, resourceId)));
438+
}
439+
}
440+
}
441+
442+
private void setIconFromFlutterCompat(Person.Builder personBuilder, String icon) {
443+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
444+
personBuilder.setIcon(IconCompat.createFromIcon(context,getIconFromFlutterAsset(context,icon)));
445+
}
446+
}
447+
370448
@RequiresApi(api = Build.VERSION_CODES.O)
371449
private Icon getIconFromFlutterAsset(Context context, String path) {
372450
AssetManager assetManager = context.getAssets();

example/lib/main.dart

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,44 @@ class _MyAppState extends State<MyApp> {
221221
),
222222
],
223223
),
224-
224+
Text("Conversation Shortcuts"),
225+
Row(
226+
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
227+
children: [
228+
ElevatedButton(
229+
child: Text("Set conversation Shortcut"),
230+
onPressed: () async {
231+
await flutterShortcuts.pushShortcutItems(
232+
shortcutList: <FlutterShortcutItem>[
233+
const FlutterShortcutItem(
234+
id: "1",
235+
action: 'open_chat_1',
236+
shortLabel: 'Divyanshu Shekhar',
237+
icon: 'assets/icons/home.png',
238+
conversationShortcut: true,
239+
isImportant: true,
240+
),
241+
const FlutterShortcutItem(
242+
id: "2",
243+
action: 'oepn_chat_2',
244+
shortLabel: 'Subham Praharaj',
245+
icon: 'assets/icons/bookmark.png',
246+
conversationShortcut: true,
247+
),
248+
const FlutterShortcutItem(
249+
id: "3",
250+
action: 'oepn_chat_3',
251+
shortLabel: 'Auto Reply Bot',
252+
icon: 'assets/icons/url.png',
253+
conversationShortcut: true,
254+
isBot: true,
255+
),
256+
],
257+
);
258+
},
259+
),
260+
],
261+
),
225262
],
226263
),
227264
),

lib/src/helper/model/flutter_shortcut_item.dart

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ class FlutterShortcutItem {
2929
this.shortcutIconAsset = ShortcutIconAsset.flutterAsset,
3030
this.longLabel,
3131
this.icon,
32+
this.conversationShortcut = false,
33+
this.isImportant = false,
34+
this.isBot = false,
3235
});
3336

3437
/// ID of the shortcut that differentiates it from other shortcuts.
@@ -48,4 +51,27 @@ class FlutterShortcutItem {
4851

4952
/// `ShortcutIconType.androidAsset` or `ShortcutIconType.flutterAsset`
5053
final ShortcutIconAsset shortcutIconAsset;
54+
55+
/// `true` if the shortcut is a person.
56+
final bool conversationShortcut;
57+
58+
/// true if the person shortcut is a person
59+
final bool isImportant;
60+
61+
/// true if the person shortcut is a machine/bot
62+
final bool isBot;
63+
64+
Map<String, dynamic> serialize() {
65+
return <String, dynamic>{
66+
'id': id,
67+
'action': action,
68+
'shortLabel': shortLabel,
69+
'longLabel': longLabel,
70+
'icon': icon,
71+
'shortcutIconType': shortcutIconAsset.index.toString(),
72+
'conversationShortcut': conversationShortcut,
73+
'isImportant': isImportant,
74+
'isBot': isBot,
75+
};
76+
}
5177
}

lib/src/method_call/flutter_shortcuts_method_call_handler.dart

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ class FlutterShortcutsMethodCallHandler extends FlutterShortcutsPlatform {
5353

5454
@override
5555
Future<void> setShortcutItems(List<FlutterShortcutItem> items) async {
56-
final List<Map<String, String?>> itemsList =
57-
items.map(_serializeItem).toList();
56+
final List<Map<String, dynamic>> itemsList =
57+
items.map((item) => item.serialize()).toList();
5858
await channel.invokeMethod<void>('setShortcutItems', itemsList);
5959
}
6060

@@ -65,43 +65,32 @@ class FlutterShortcutsMethodCallHandler extends FlutterShortcutsPlatform {
6565

6666
@override
6767
Future<void> pushShortcutItem(FlutterShortcutItem shortcut) async {
68-
final Map<String, String?> item = _serializeItem(shortcut);
68+
final Map<String, dynamic> item = shortcut.serialize();
6969
await channel.invokeMethod<void>('pushShortcutItem', [item]);
7070
}
7171

7272
@override
7373
Future<void> pushShortcutItems(List<FlutterShortcutItem> items) async {
74-
final List<Map<String, String?>> itemsList =
75-
items.map(_serializeItem).toList();
74+
final List<Map<String, dynamic>> itemsList =
75+
items.map((item) => item.serialize()).toList();
7676
await channel.invokeMethod<void>('pushShortcutItems', itemsList);
7777
}
7878

7979
@override
8080
Future<void> updateShortcutItems(List<FlutterShortcutItem> items) async {
81-
final List<Map<String, String?>> itemsList =
82-
items.map(_serializeItem).toList();
81+
final List<Map<String, dynamic>> itemsList =
82+
items.map((item) => item.serialize()).toList();
8383
await channel.invokeMethod<void>('updateShortcutItems', itemsList);
8484
}
8585

8686
@override
8787
Future<void> updateShortcutItem(FlutterShortcutItem shortcut) async {
88-
final Map<String, String?> item = _serializeItem(shortcut);
88+
final Map<String, dynamic> item = shortcut.serialize();
8989
await channel.invokeMethod<void>('updateShortcutItem', [item]);
9090
}
9191

9292
@override
9393
Future<void> changeShortcutItemIcon(String id, String icon) async {
9494
await channel.invokeMethod<void>('changeShortcutItemIcon', [id, icon]);
9595
}
96-
97-
Map<String, String?> _serializeItem(FlutterShortcutItem item) {
98-
return <String, String?>{
99-
'id': item.id,
100-
'action': item.action,
101-
'shortLabel': item.shortLabel,
102-
'longLabel': item.longLabel,
103-
'icon': item.icon,
104-
'shortcutIconType': item.shortcutIconAsset.index.toString(),
105-
};
106-
}
10796
}

0 commit comments

Comments
 (0)