diff --git a/android/src/main/kotlin/com/bhikadia/receive_intent/ReceiveIntentPlugin.kt b/android/src/main/kotlin/com/bhikadia/receive_intent/ReceiveIntentPlugin.kt index 70fddc9..98d6c42 100644 --- a/android/src/main/kotlin/com/bhikadia/receive_intent/ReceiveIntentPlugin.kt +++ b/android/src/main/kotlin/com/bhikadia/receive_intent/ReceiveIntentPlugin.kt @@ -3,6 +3,7 @@ package com.bhikadia.receive_intent import android.app.Activity import android.content.Context import android.content.Intent +import android.util.Log import androidx.annotation.NonNull import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.embedding.engine.plugins.activity.ActivityAware @@ -13,6 +14,7 @@ import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler import io.flutter.plugin.common.MethodChannel.Result +import org.json.JSONObject /** ReceiveIntentPlugin */ @@ -40,11 +42,14 @@ class ReceiveIntentPlugin : FlutterPlugin, MethodCallHandler, EventChannel.Strea "action" to intent.action, "data" to intent.dataString, "categories" to intent.categories, - "extra" to intent.extras?.let { bundleToMap(it) } + "extra" to intent.extras?.let { bundleToJSON(it).toString() } ) } private fun handleIntent(intent: Intent, fromPackageName: String?) { + Log.e("ReceiveIntentPlugin", "intent: $intent") + Log.e("ReceiveIntentPlugin", "fromPackageName: $fromPackageName") + Log.e("ReceiveIntentPlugin", "intentMap: " + intentToMap(intent, fromPackageName)) if (initialIntent) { initialIntentMap = intentToMap(intent, fromPackageName) initialIntent = false @@ -53,12 +58,15 @@ class ReceiveIntentPlugin : FlutterPlugin, MethodCallHandler, EventChannel.Strea eventSink?.success(latestIntentMap) } - private fun giveResult(result: Result, resultCode: Int?, data: Map?) { + private fun giveResult(result: Result, resultCode: Int?, data: String?) { if (resultCode != null) { - if (data == null) + if (data == null) { activity?.setResult(resultCode) - else - activity?.setResult(resultCode, mapToIntent(data)) + } + else { + val json = JSONObject(data) + activity?.setResult(resultCode, jsonToIntent(json)) + } result.success(null) } result.error("InvalidArg", "resultCode can not be null", null) diff --git a/android/src/main/kotlin/com/bhikadia/receive_intent/Utils.kt b/android/src/main/kotlin/com/bhikadia/receive_intent/Utils.kt index 1cea08e..625fcb0 100644 --- a/android/src/main/kotlin/com/bhikadia/receive_intent/Utils.kt +++ b/android/src/main/kotlin/com/bhikadia/receive_intent/Utils.kt @@ -6,13 +6,18 @@ import android.content.pm.PackageManager import android.os.Build import android.os.Bundle import android.os.Parcelable +import android.util.Log +import org.json.JSONArray +import org.json.JSONException +import org.json.JSONObject import java.security.MessageDigest -fun mapToBundle(map: Map): Bundle { - val bundle = Bundle(); - map.forEach { - val k = it.key - val v = it.value + +fun jsonToBundle(json: JSONObject): Bundle { + val bundle = Bundle() + json.keys().forEach { + val k = it + val v = json.get(k) when (v) { is Byte -> bundle.putByte(k, v) is ByteArray -> bundle.putByteArray(k, v) @@ -30,20 +35,86 @@ fun mapToBundle(map: Map): Bundle { return bundle; } -fun mapToIntent(map: Map): Intent = Intent().apply { - putExtras(mapToBundle(map)) +fun jsonToIntent(json: JSONObject): Intent = Intent().apply { + putExtras(jsonToBundle(json)) } -fun bundleToMap(extras: Bundle): Map { - val map: MutableMap = HashMap() - val ks = extras.keySet() +fun bundleToJSON(bundle: Bundle): JSONObject { + val json = JSONObject() + val ks = bundle.keySet() val iterator: Iterator = ks.iterator() while (iterator.hasNext()) { val key = iterator.next() - map[key] = extras.get(key) + try { + json.put(key, wrap(bundle.get(key))) + } catch (e: JSONException) { + e.printStackTrace() + } } - return map + return json +} + +fun wrap(o: Any?): Any? { + if (o == null) { + return JSONObject.NULL + } + if (o is JSONArray || o is JSONObject) { + return o + } + if (o == JSONObject.NULL) { + return o + } + try { + if (o is Collection<*>) { + Log.e("ReceiveIntentPlugin", "$o is Collection<*>") + return JSONArray(o as Collection<*>?) + } else if (o.javaClass.isArray) { + Log.e("ReceiveIntentPlugin", "$o is isArray") + return toJSONArray(o) + } + if (o is Map<*, *>) { + Log.e("ReceiveIntentPlugin", "$o is Map<*, *>") + return JSONObject(o as Map<*, *>?) + } + if (o is Boolean || + o is Byte || + o is Char || + o is Double || + o is Float || + o is Int || + o is Long || + o is Short || + o is String) { + return o + } + if (o.javaClass.getPackage().name.startsWith("java.")) { + return o.toString() + } + } catch (e: Exception) { + Log.e("ReceiveIntentPlugin", e.message, e) + e.printStackTrace() + } + return null +} + +@Throws(JSONException::class) +fun toJSONArray(array: Any): JSONArray? { + val result = JSONArray() + if (!array.javaClass.isArray) { + throw JSONException("Not a primitive array: " + array.javaClass) + } + + when (array) { + is List<*> -> { + array.forEach { result.put(wrap(it)) } + } + is Array<*> -> { + array.forEach { result.put(wrap(it)) } + } + } + + return result } fun getApplicationSignature(context: Context, packageName: String): List { diff --git a/lib/receive_intent.dart b/lib/receive_intent.dart index 7316ad7..e8d262f 100644 --- a/lib/receive_intent.dart +++ b/lib/receive_intent.dart @@ -1,8 +1,10 @@ import 'dart:async'; +import 'dart:convert'; import 'package:flutter/services.dart'; class ReceivedIntent { + final bool isNull; final String? fromPackageName; final List? fromSignatures; final String action; @@ -10,7 +12,10 @@ class ReceivedIntent { final List? categories; final Map? extra; + bool get isNotNull => !isNull; + const ReceivedIntent({ + this.isNull = true, this.fromPackageName, this.fromSignatures, required this.action, @@ -20,14 +25,32 @@ class ReceivedIntent { }); factory ReceivedIntent.fromMap(Map? map) => ReceivedIntent( + isNull: map == null, fromPackageName: map?["fromPackageName"], - fromSignatures: map?["fromSignatures"], + fromSignatures: map?["fromSignatures"] != null + ? List.unmodifiable( + (map!["fromSignatures"] as List).map((e) => e.toString())) + : null, action: map?["action"], data: map?["data"], - categories: map?["categories"], - extra: (map?["extra"] as Map?)?.map( - (key, value) => MapEntry(key.toString(), value)), + categories: map?["categories"] != null + ? List.unmodifiable( + (map!["categories"] as List).map((e) => e.toString())) + : null, + extra: map?["extra"] != null + ? (json.decode(map!["extra"]) as Map) + .map((key, value) => MapEntry(key.toString(), value)) + : null, ); + + Map toMap() => { + "fromPackageName": fromPackageName, + "fromSignatures": fromSignatures, + "action": action, + "data": data, + "categories": categories, + "extra": extra, + }; } class ReceiveIntent { @@ -47,7 +70,9 @@ class ReceiveIntent { .map((event) => ReceivedIntent.fromMap(event as Map?)); static Future giveResult(int resultCode, {Map? data}) async { - await _methodChannel.invokeMethod('giveResult', - {"resultCode": resultCode, "data": data}); + await _methodChannel.invokeMethod('giveResult', { + "resultCode": resultCode, + "data": json.encode(data), + }); } }