Skip to content

Commit

Permalink
feat(android): interface to inlcude layoutId and layoutName
Browse files Browse the repository at this point in the history
  • Loading branch information
noxasch committed Apr 26, 2024
1 parent 4f67904 commit e5b3f79
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,15 @@ class AppWidgetMethodCallHandler(private val context: Context, )

fun handleConfigureIntent(intent: Intent): Boolean {
val widgetId = intent.extras!!.getInt("widgetId")
channel!!.invokeMethod(AppWidgetPlugin.ON_CONFIGURE_WIDGET_CALLBACK, mapOf("widgetId" to widgetId))
val layoutId = intent.extras!!.getInt("layoutId")
val layoutName = intent.extras!!.getString("layoutName")
channel!!.invokeMethod(AppWidgetPlugin.ON_CONFIGURE_WIDGET_CALLBACK,
mapOf(
"widgetId" to widgetId,
"layoutId" to layoutId,
"layoutName" to layoutName
)
)
return true
}

Expand Down Expand Up @@ -67,7 +75,7 @@ class AppWidgetMethodCallHandler(private val context: Context, )
}
}

private fun getWidgetIds(@NonNull call: MethodCall, @NonNull result: MethodChannel.Result) {
private fun getWidgetIds(call: MethodCall, result: MethodChannel.Result) {
val androidPackageName = call.argument<String>("androidPackageName")
?: context.packageName
val widgetProviderName = call.argument<String>("androidProviderName") ?: return result.error(
Expand All @@ -88,7 +96,7 @@ class AppWidgetMethodCallHandler(private val context: Context, )
}
}

private fun cancelConfigureWidget(@NonNull result: MethodChannel.Result) {
private fun cancelConfigureWidget(result: MethodChannel.Result) {
return try {
activity!!.setResult(Activity.RESULT_CANCELED)
result.success(true)
Expand All @@ -100,18 +108,16 @@ class AppWidgetMethodCallHandler(private val context: Context, )


/// This should be called when configuring individual widgets
private fun configureWidget(@NonNull call: MethodCall, @NonNull result: MethodChannel.Result) {
private fun configureWidget(call: MethodCall, result: MethodChannel.Result) {
return try {
if (activity == null) return result.error("-2", "Not attached to any activity!", null)

val androidPackageName = call.argument<String>("androidPackageName")
?: context.packageName
val widgetId = call.argument<Int>("widgetId")
?: return result.error("-1", "widgetId is required!", null)
val widgetLayout = call.argument<String>("widgetLayout")
?: return result.error("-1", "widgetLayout is required!", null)

val widgetLayoutId: Int = context.resources.getIdentifier(widgetLayout, "layout", context.packageName)
val layoutId = call.argument<Int>("layoutId")
?: return result.error("-1", "layoutId is required!", null)
val payload = call.argument<String>("payload")
val url = call.argument<String>("url")
val activityClass = Class.forName("${context.packageName}.MainActivity")
Expand All @@ -120,7 +126,7 @@ class AppWidgetMethodCallHandler(private val context: Context, )
val textViewsMap = call.argument<Map<String, String>>("textViews")

if (textViewsMap != null) {
val views : RemoteViews = RemoteViews(context.packageName, widgetLayoutId).apply {
val views : RemoteViews = RemoteViews(context.packageName, layoutId).apply {
for ((key, value) in textViewsMap) {
val textViewId: Int =
context.resources.getIdentifier(key, "id", context.packageName)
Expand All @@ -143,7 +149,7 @@ class AppWidgetMethodCallHandler(private val context: Context, )
}
}

private fun widgetExist(@NonNull call: MethodCall, @NonNull result: MethodChannel.Result) {
private fun widgetExist(call: MethodCall, result: MethodChannel.Result) {
val widgetId = call.argument<Int>("widgetId") ?: return result.success(false)
return try {
val widgetManager = AppWidgetManager.getInstance(context)
Expand All @@ -156,17 +162,15 @@ class AppWidgetMethodCallHandler(private val context: Context, )
}

// This should only be called after the widget has been configure for the first time
private fun updateWidget(@NonNull call: MethodCall, @NonNull result: MethodChannel.Result) {
private fun updateWidget(call: MethodCall, result: MethodChannel.Result) {
return try {
val androidPackageName = call.argument<String>("androidPackageName")
?: context.packageName
val widgetId = call.argument<Int>("widgetId")
?: return result.error("-1", "widgetId is required!", null)
val widgetLayout = call.argument<String>("widgetLayout")
?: return result.error("-1", "widgetLayout is required!", null)
val layoutId = call.argument<Int>("layoutId")
?: return result.error("-1", "layoutId is required!", null)

val widgetLayoutId: Int =
context.resources.getIdentifier(widgetLayout, "layout", context.packageName)
val payload = call.argument<String>("payload")
val url = call.argument<String>("url")
val activityClass = Class.forName("${context.packageName}.MainActivity")
Expand All @@ -175,7 +179,7 @@ class AppWidgetMethodCallHandler(private val context: Context, )
val textViewsMap = call.argument<Map<String, String>>("textViews")

if (textViewsMap != null) {
val views = RemoteViews(context.packageName, widgetLayoutId)
val views = RemoteViews(context.packageName, layoutId)

for ((key, value) in textViewsMap) {
val textViewId: Int =
Expand Down Expand Up @@ -230,7 +234,7 @@ class AppWidgetMethodCallHandler(private val context: Context, )
}

/// force reload the widget and this will trigger onUpdate in broadcast receiver
private fun reloadWidgets(@NonNull call: MethodCall, @NonNull result: MethodChannel.Result) {
private fun reloadWidgets(call: MethodCall, result: MethodChannel.Result) {
val androidPackageName = call.argument<String>("androidPackageName")
?: context.packageName
val widgetProviderName = call.argument<String>("androidProviderName")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,26 @@ class AppWidgetPlugin: FlutterPlugin, ActivityAware,
val widgetId: Int = extras?.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID) ?: return
if (widgetId == 0) return

val widgetManager = AppWidgetManager.getInstance(context)
val appWidgetInfo = widgetManager.getAppWidgetInfo(widgetId)
val layoutId = appWidgetInfo.initialLayout
val layoutName = context.resources.getResourceName(layoutId)

val configIntent = Intent(context, context.javaClass)
configIntent.action = CONFIGURE_WIDGET_ACTION_CALLBACK
configIntent.putExtra("widgetId", widgetId)
configIntent.putExtra("layoutId", layoutId)
configIntent.putExtra("layoutName", layoutName)
context.startActivity(configIntent)
}
}

override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
methodCallHandler = AppWidgetMethodCallHandler(flutterPluginBinding.applicationContext)
methodCallHandler!!.open(flutterPluginBinding.binaryMessenger)
}

override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
methodCallHandler!!.close()
}

Expand Down
4 changes: 2 additions & 2 deletions app_widget_android/example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ packages:
dependency: transitive
description:
name: app_widget_platform_interface
sha256: "07c7500e83f86703fdad1aa3480e492a7226b322cbad3e71910f2630df96391e"
sha256: a288112ec826c25e7638ddc30c33a5e7279cfc2eadba89ccb33bc8d3ddbb589c
url: "https://pub.dev"
source: hosted
version: "0.3.1"
version: "0.4.0"
async:
dependency: transitive
description:
Expand Down
21 changes: 13 additions & 8 deletions app_widget_android/lib/src/app_widget_android_plugin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,25 @@ const MethodChannel _methodChannel = MethodChannel(AppWidgetPlatform.channel);

class AppWidgetAndroidPlugin extends AppWidgetAndroid {
AppWidgetAndroidPlugin({
void Function(int widgetId)? onConfigureWidget,
void Function(int widgetId, int layoutId, String layoutName)?
onConfigureWidget,
void Function(String? payload)? onClickWidget,
}) : _onConfigureWidget = onConfigureWidget,
_onClickWidget = onClickWidget {
_methodChannel.setMethodCallHandler(handleMethod);
}

final void Function(int widgetId)? _onConfigureWidget;
final void Function(int widgetId, int layoutId, String layoutName)?
_onConfigureWidget;
final void Function(String? payload)? _onClickWidget;

Future<dynamic> handleMethod(MethodCall call) async {
switch (call.method) {
case onConfigureWidgetCallback:
final widgetId = call.arguments['widgetId'] as int;
return _onConfigureWidget?.call(widgetId);
final layoutId = call.arguments['layoutId'] as int;
final layoutName = call.arguments['layoutName'] as String;
return _onConfigureWidget?.call(widgetId, layoutId, layoutName);
case onClickWidgetCallback:
return _onClickWidget?.call(call.arguments['payload'] as String);
default:
Expand All @@ -42,18 +46,18 @@ class AppWidgetAndroidPlugin extends AppWidgetAndroid {
Future<bool?> configureWidget({
String? androidPackageName,
int? widgetId,
String? widgetLayout,
int? layoutId,
Map<String, String>? textViews = const {},
String? payload,
String? url,
}) {
assert(widgetId != null, 'widgetId is required for android!');
assert(widgetLayout != null, 'widgetLayout is required for android!');
assert(layoutId != null, 'layoutId is required for android!');

return _methodChannel.invokeMethod<bool>('configureWidget', {
'androidPackageName': androidPackageName,
'widgetLayout': widgetLayout,
'widgetId': widgetId,
'layoutId': layoutId,
'textViews': textViews,
'payload': payload,
'url': url,
Expand Down Expand Up @@ -106,20 +110,21 @@ class AppWidgetAndroidPlugin extends AppWidgetAndroid {
Future<bool?> updateWidget({
String? androidPackageName,
int? widgetId,
int? layoutId,
String? widgetLayout,
Map<String, String>? textViews = const {},
String? payload,
String? url,
}) {
assert(widgetId != null, 'widgetId is required for android!');
assert(widgetLayout != null, 'widgetLayout is required for android!');
assert(layoutId != null, 'layoutId is required for android!');

return _methodChannel.invokeMethod<bool>('updateWidget', {
if (androidPackageName != null) ...{
'androidPackageName': androidPackageName,
},
'widgetLayout': widgetLayout,
'widgetId': widgetId,
'layoutId': layoutId,
'textViews': textViews,
'payload': payload,
'url': url,
Expand Down
4 changes: 2 additions & 2 deletions app_widget_android/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: app_widget_android
description: Android implementation for app_widget plugin
version: 0.3.3
version: 0.4.0
homepage: https://noxasch.tech/
repository: https://github.com/noxasch/flutter_app_widget/tree/master/app_widget_android
issue_tracker: https://github.com/noxasch/flutter_app_widget/issues
Expand All @@ -13,7 +13,7 @@ dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.1.7
app_widget_platform_interface: ^0.3.1
app_widget_platform_interface: ^0.4.0
# app_widget_platform_interface: # local dev
# path: ../app_widget_platform_interface

Expand Down
2 changes: 2 additions & 0 deletions app_widget_android/test/app_widget_android_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class MockAppWidgetAndroidPlatform
Future<bool?> configureWidget({
String? androidPackageName,
int? widgetId,
int? layoutId,
String? widgetLayout,
String? widgetContainerName,
Map<String, String>? textViews,
Expand All @@ -97,6 +98,7 @@ class MockAppWidgetAndroidPlatform
Future<bool?> updateWidget({
String? androidPackageName,
int? widgetId,
int? layoutId,
String? widgetLayout,
Map<String, String>? textViews,
String? payload,
Expand Down

0 comments on commit e5b3f79

Please sign in to comment.