赞
踩
最近遇到了这个问题,其实这个问题在源生开发中算是一个很常见的问题。有很多场景都需要通过其他APP或者H5来打开APP并且有时候会携带参数。
所以在这里我说一下我的做法(大神勿喷,有更好的办法请评论区留言,不胜感激)。
我的思路就是:1.APP接收第三方平台的请求方式与源生处理方式不变,然后存储好请求的参数;2.利用平台提供的Flutter与源生交互的通道MethodChannel(android)以及FlutterMethodChannel(iOS),在双端分别创建一个可以访问到存储的请求数据的通道,通过判断存储的数据,来响应第三方平台的请求。
1.首先在AndroidManifest.xml中修改入口Activity的配置:
android:name=".MainActivity" android:launchMode="singleTask" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:exported="true" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:scheme="scheme" android:host="host" android:pathPrefix="/path"/> </intent-filter> </activity>
其中 android:launchMode=“singleTask” android:exported=“true” 是新增的
以及
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="scheme" android:host="host" android:pathPrefix="/path"/>
2.在MainActivity中接收并保存第三方传递过来的参数信息:
private void getOpenData(){ try { Uri uri = getIntent().getData(); if (uri==null){ return; } String query = uri.getQuery(); String openpage = uri.getQueryParameter("openpage"); String data = uri.getQueryParameter("data"); Log.d("scheme-", "openpage: " + openpage + ", data: " + data + ", query: " + query); JSONObject jsonObject=new JSONObject(); jsonObject.put("openpage",openpage); jsonObject.put("data",data); CampusBarApplication.schemeInfo=jsonObject; } catch (Exception e) { Log.e("scheme-", e.getMessage(), e); } }
我这里用了一个静态变量保存 CampusBarApplication.schemeInfo=jsonObject; 用数据库、SP,文件等都可以,这里为了方便就用了个静态变量。
3.定义一个Flutter与源生交互的通道:
什么是通道?https://book.flutterchina.club/chapter12/platform-channel.html
private void initOpenPage() { // new MethodChannel() new MethodChannel(getFlutterView(), openpage_chanel).setMethodCallHandler( (methodCall, result) -> { if (methodCall.method.equals(checkOpenPage)) { Map<String,String> map=new HashMap<>(); if (CampusBarApplication.schemeInfo==null){ map.put("code","201"); }else { map.put("code","200"); map.put("openpage",CampusBarApplication.schemeInfo.getString("openpage")); map.put("data",CampusBarApplication.schemeInfo.getString("data")); CampusBarApplication.schemeInfo=null;//记得在每次相应完清空保存的数据 } result.success(map); } } ); }
4.在flutter代码使用:
var platform = MethodChannel(NetUrlConstant.OPENPAGE_CHANEL);
platform.invokeMethod(NetUrlConstant.CHECK_OPEN_PAGE).then((onValue){
if(onValue["code"]=="200"){
println(onValue["data"]+"aassddffgg-----------------------------");
//TODO
}else if(onValue["code"]=="201"){
}
});
这样就可以在flutter响应到第三方的请求。
1.首先开始跟源生开发一样去配置URL Scheme 或者使用universal link,我在这就不讲怎么配置了。
2.在AppDelegate.m中接收并保存第三方传递过来的参数信息:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options { NSLog(@"URL scheme:%@", [url scheme]); NSLog(@"URL query: %@", [url query]); NSMutableDictionary * dic=[NSMutableDictionary dictionary]; [dic setObject:[url scheme] forKey:@"openpage"]; [dic setObject:[url query] forKey:@"data"]; NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults setObject:dic forKey:@"openinfo"]; //这里建议同步存储到磁盘中,但是不是必须的 [userDefaults synchronize]; return YES; }
3.在AppDelegate.m 中同样是定义一个通道:
FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController; FlutterMethodChannel* channel = [FlutterMethodChannel methodChannelWithName:@"openpage_chanel" binaryMessenger:controller]; [channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { // TODO if ([@"checkOpenPage" isEqualToString:call.method]) { NSUserDefaults *userDefaultes = [NSUserDefaults standardUserDefaults]; //读取字典类型NSDictionary类型的数据 NSMutableDictionary *dic = [userDefaultes dictionaryForKey:@"openinfo"]; if (dic) { [dic setObject:@"200" forKey:@"code"]; //记得清除保存的信息 }else{ dic=[NSMutableDictionary dictionary]; [dic setObject:@"201" forKey:@"code"]; } result(dic); } }];
注意:Android跟iOS要协商好,将通道返回的信息格式保持一致,这样在Flutter就不用判断平台,用一套代码就可以完成双端的操作。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。