提交 a6f7f0d0 authored 作者: JarvanMo's avatar JarvanMo

Pass extMessage when cold launch FlutterApp from h5.

上级 36ab4af3
...@@ -16,7 +16,7 @@ import io.flutter.plugin.common.MethodChannel.Result ...@@ -16,7 +16,7 @@ import io.flutter.plugin.common.MethodChannel.Result
import io.flutter.plugin.common.PluginRegistry import io.flutter.plugin.common.PluginRegistry
/** FluwxPlugin */ /** FluwxPlugin */
public class FluwxPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { class FluwxPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
companion object { companion object {
@JvmStatic @JvmStatic
...@@ -39,12 +39,18 @@ public class FluwxPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { ...@@ -39,12 +39,18 @@ public class FluwxPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
private var authHandler: FluwxAuthHandler? = null private var authHandler: FluwxAuthHandler? = null
private var fluwxChannel: MethodChannel? = null
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
val channel = MethodChannel(flutterPluginBinding.binaryMessenger, "com.jarvanmo/fluwx") if (fluwxChannel == null) {
channel.setMethodCallHandler(this) fluwxChannel = MethodChannel(flutterPluginBinding.binaryMessenger, "com.jarvanmo/fluwx")
FluwxResponseHandler.setMethodChannel(channel) fluwxChannel?.setMethodCallHandler(this)
FluwxRequestHandler.setMethodChannel(channel) }
authHandler = FluwxAuthHandler(channel) fluwxChannel?.let {
FluwxResponseHandler.setMethodChannel(it)
FluwxRequestHandler.setMethodChannel(it)
authHandler = FluwxAuthHandler(it)
}
shareHandler = FluwxShareHandlerEmbedding(flutterPluginBinding.flutterAssets, flutterPluginBinding.applicationContext) shareHandler = FluwxShareHandlerEmbedding(flutterPluginBinding.flutterAssets, flutterPluginBinding.applicationContext)
} }
......
...@@ -14,26 +14,98 @@ ...@@ -14,26 +14,98 @@
* limitations under the License. * limitations under the License.
*/ */
package com.jarvan.fluwx.handlers package com.jarvan.fluwx.handlers
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.util.Log
import com.tencent.mm.opensdk.modelmsg.ShowMessageFromWX import com.tencent.mm.opensdk.modelmsg.ShowMessageFromWX
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
import com.tencent.mm.opensdk.modelbase.BaseReq import com.tencent.mm.opensdk.modelbase.BaseReq
import java.lang.Exception
object FluwxRequestHandler { object FluwxRequestHandler {
private const val KEY_FLUWX_REQUEST_INFO_BUNDLE = "KEY_FLUWX_REQUEST_INFO_BUNDLE"
var customOnReqDelegate: ((baseReq: BaseReq, activity: Activity) -> Unit)? = null
private var channel: MethodChannel? = null private var channel: MethodChannel? = null
fun setMethodChannel(channel: MethodChannel) { fun setMethodChannel(channel: MethodChannel) {
FluwxRequestHandler.channel = channel FluwxRequestHandler.channel = channel
} }
fun handleRequest(req: BaseReq) {
fun handleRequestInfoFromIntent(intent: Intent) {
intent.getBundleExtra(KEY_FLUWX_REQUEST_INFO_BUNDLE)?.run {
val type = getInt("_wxapi_command_type", -9999)
if (type == 4) {
handleShowMessageFromWXBundle(this)
}
}
}
private fun handleShowMessageFromWXBundle(bundle: Bundle) = handleWXShowMessageFromWX(ShowMessageFromWX.Req(bundle))
private fun handleRequest(req: BaseReq) {
when (req) { when (req) {
is ShowMessageFromWX.Req -> hanleWXShowMessageFromWX(req) is ShowMessageFromWX.Req -> handleWXShowMessageFromWX(req)
} }
} }
private fun hanleWXShowMessageFromWX(req: ShowMessageFromWX.Req) { private fun handleWXShowMessageFromWX(req: ShowMessageFromWX.Req) {
val result = mapOf( val result = mapOf(
"extMsg" to req.message.messageExt, ) "extMsg" to req.message.messageExt,
)
channel?.invokeMethod("onWXShowMessageFromWX", result) channel?.invokeMethod("onWXShowMessageFromWX", result)
} }
private fun defaultOnReqDelegate(baseReq: BaseReq, activity: Activity) {
// FIXME: 可能是官方的Bug,从微信拉起APP的Intent类型不对,无法跳转回Flutter Activity
// 稳定复现场景:微信版本为7.0.5,小程序SDK为2.7.7
if (baseReq.type == 4) {
// com.tencent.mm.opensdk.constants.ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX = 4
if (WXAPiHandler.wxApiRegistered) {
handleRequest(baseReq)
startSpecifiedActivity(defaultFlutterActivityAction(activity), activity = activity)
} else {
startSpecifiedActivity(defaultFlutterActivityAction(activity), bundle = Bundle().apply {
baseReq.toBundle(this)
}, bundleKey = KEY_FLUWX_REQUEST_INFO_BUNDLE, activity = activity)
}
}
}
fun onReq(baseReq: BaseReq, activity: Activity) {
try {
val appInfo = activity.packageManager.getApplicationInfo(activity.packageName, PackageManager.GET_META_DATA)
val defaultHandle = appInfo.metaData.getBoolean("handleWeChatRequestByFluwx", true)
if (defaultHandle) {
defaultOnReqDelegate(baseReq, activity)
} else {
customOnReqDelegate?.invoke(baseReq, activity)
}
} catch (e: Exception) {
Log.i("Fluwx", "can't load meta-data handleWeChatRequestByFluwx")
}
}
private fun startSpecifiedActivity(action: String, activity: Activity, bundle: Bundle? = null, bundleKey: String? = null) {
Intent(action).run {
bundleKey?.let {
putExtra(bundleKey, bundle)
}
addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
activity.packageManager?.let {
resolveActivity(it)?.also {
activity.startActivity(this)
activity.finish()
}
}
}
}
private fun defaultFlutterActivityAction(context: Context): String = "$context.packageName.FlutterActivity"
} }
\ No newline at end of file
...@@ -30,6 +30,18 @@ object WXAPiHandler { ...@@ -30,6 +30,18 @@ object WXAPiHandler {
private var context: Context? = null private var context: Context? = null
private var registered: Boolean = false
val wxApiRegistered get() = registered
fun setupWxApi(appId: String, context: Context, force: Boolean = true): Boolean {
if (force || !registered) {
setContext(context)
registerWxAPIInternal(appId, context)
}
return registered
}
fun setContext(context: Context?) { fun setContext(context: Context?) {
WXAPiHandler.context = context WXAPiHandler.context = context
} }
...@@ -51,9 +63,9 @@ object WXAPiHandler { ...@@ -51,9 +63,9 @@ object WXAPiHandler {
return return
} }
val api = WXAPIFactory.createWXAPI(context?.applicationContext, appId) context?.let {
val registered = api.registerApp(appId) registerWxAPIInternal(appId, it)
wxApi = api }
result.success(registered) result.success(registered)
} }
...@@ -64,6 +76,11 @@ object WXAPiHandler { ...@@ -64,6 +76,11 @@ object WXAPiHandler {
} else { } else {
result.success(wxApi?.isWXAppInstalled) result.success(wxApi?.isWXAppInstalled)
} }
}
private fun registerWxAPIInternal(appId: String, context: Context) {
val api = WXAPIFactory.createWXAPI(context.applicationContext, appId)
registered = api.registerApp(appId)
wxApi = api
} }
} }
\ No newline at end of file
...@@ -23,7 +23,6 @@ import com.jarvan.fluwx.handlers.FluwxRequestHandler ...@@ -23,7 +23,6 @@ import com.jarvan.fluwx.handlers.FluwxRequestHandler
import com.jarvan.fluwx.handlers.WXAPiHandler import com.jarvan.fluwx.handlers.WXAPiHandler
import com.tencent.mm.opensdk.modelbase.BaseReq import com.tencent.mm.opensdk.modelbase.BaseReq
import com.tencent.mm.opensdk.modelbase.BaseResp import com.tencent.mm.opensdk.modelbase.BaseResp
import com.tencent.mm.opensdk.modelmsg.ShowMessageFromWX
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler
...@@ -38,7 +37,7 @@ open class FluwxWXEntryActivity : Activity(), IWXAPIEventHandler { ...@@ -38,7 +37,7 @@ open class FluwxWXEntryActivity : Activity(), IWXAPIEventHandler {
WXAPiHandler.wxApi?.handleIntent(intent, this) WXAPiHandler.wxApi?.handleIntent(intent, this)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
startSpecifiedActivity() startSpecifiedActivity(defaultFlutterActivityAction())
finish() finish()
} }
} }
...@@ -52,7 +51,7 @@ open class FluwxWXEntryActivity : Activity(), IWXAPIEventHandler { ...@@ -52,7 +51,7 @@ open class FluwxWXEntryActivity : Activity(), IWXAPIEventHandler {
WXAPiHandler.wxApi?.handleIntent(intent, this) WXAPiHandler.wxApi?.handleIntent(intent, this)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
startSpecifiedActivity() startSpecifiedActivity(defaultFlutterActivityAction())
finish() finish()
} }
} }
...@@ -61,11 +60,7 @@ open class FluwxWXEntryActivity : Activity(), IWXAPIEventHandler { ...@@ -61,11 +60,7 @@ open class FluwxWXEntryActivity : Activity(), IWXAPIEventHandler {
override fun onReq(baseReq: BaseReq) { override fun onReq(baseReq: BaseReq) {
// FIXME: 可能是官方的Bug,从微信拉起APP的Intent类型不对,无法跳转回Flutter Activity // FIXME: 可能是官方的Bug,从微信拉起APP的Intent类型不对,无法跳转回Flutter Activity
// 稳定复现场景:微信版本为7.0.5,小程序SDK为2.7.7 // 稳定复现场景:微信版本为7.0.5,小程序SDK为2.7.7
if (baseReq.type == 4) { FluwxRequestHandler.onReq(baseReq,this)
// com.tencent.mm.opensdk.constants.ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX = 4
FluwxRequestHandler.handleRequest(baseReq)
startSpecifiedActivity()
}
} }
// 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法 // 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
...@@ -74,11 +69,20 @@ open class FluwxWXEntryActivity : Activity(), IWXAPIEventHandler { ...@@ -74,11 +69,20 @@ open class FluwxWXEntryActivity : Activity(), IWXAPIEventHandler {
finish() finish()
} }
private fun startSpecifiedActivity() { private fun startSpecifiedActivity(action: String, bundle: Bundle? = null, bundleKey: String? = null) {
Intent("$packageName.FlutterActivity").run { Intent(action).run {
bundleKey?.let {
putExtra(bundleKey, bundle)
}
addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
packageManager?.let {
resolveActivity(packageManager)?.also {
startActivity(this) startActivity(this)
}
finish() finish()
} }
}
}
}
private fun defaultFlutterActivityAction(): String = "$packageName.FlutterActivity"
} }
\ No newline at end of file
...@@ -5,22 +5,23 @@ ...@@ -5,22 +5,23 @@
In most cases you can leave this as-is, but you if you want to provide In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. --> FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application <application
android:name="io.flutter.app.FlutterApplication" android:name="io.flutter.app.FlutterApplication"
android:label="fluwx_example" android:icon="@mipmap/ic_launcher"
android:icon="@mipmap/ic_launcher"> android:label="fluwx_example">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN" />
<action android:name="${applicationId}.FlutterActivity"/> <action android:name="${applicationId}.FlutterActivity" />
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<!-- Don't delete the meta-data below. <!-- Don't delete the meta-data below.
...@@ -28,5 +29,8 @@ ...@@ -28,5 +29,8 @@
<meta-data <meta-data
android:name="flutterEmbedding" android:name="flutterEmbedding"
android:value="2" /> android:value="2" />
<meta-data
android:name="handleWeChatRequestByFluwx"
android:value="false" />
</application> </application>
</manifest> </manifest>
package com.jarvan.fluwx_example package com.jarvan.fluwx_example
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.jarvan.fluwx.handlers.FluwxRequestHandler
import com.jarvan.fluwx.handlers.WXAPiHandler
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant import io.flutter.plugins.GeneratedPluginRegistrant
...@@ -8,5 +10,9 @@ import io.flutter.plugins.GeneratedPluginRegistrant ...@@ -8,5 +10,9 @@ import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterActivity() { class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine); GeneratedPluginRegistrant.registerWith(flutterEngine);
//If you didn't configure WxAPI, add the following code
WXAPiHandler.setupWxApi("wxd930ea5d5a258f4f",this)
//Get Ext-Info from Intent.
FluwxRequestHandler.handleRequestInfoFromIntent(intent)
} }
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论