zileyuan / umeng_analytics_push

Umeng Analytics&Push Flutter Plugins
MIT License
30 stars 21 forks source link

提3个问题 #1

Closed gaoyong06 closed 4 years ago

gaoyong06 commented 4 years ago

作者,您好,我在使用umeng_analytics_push遇到了3个问题

问题1. umeng push 集成以后,我在umeng push的后台,推送了5,6条,app的日志上都有答应,看起来都是正常的,但是手机的通知栏里面不显示

我在umeng的官网和百度上翻了一下,没找到通知栏里不显示通知原因,但是排除了几个可能的原因: 1)umeng Push后台设置的包名,和androidManifest里面的package名,以及build.grade里面的applicationId 不一致 . (我这里都是一致的) 2)手机上 app的推送通知 在手机设置 里面没有打开,(我这里是打开的) 3) "是否调用了PushAgent的setPushIntentServiceClass方法,如果调用了,需自己写代码实现通知的弹出。" (这个目前不确定,但是在umeng_analytics_push里面搜索“setPushIntentServiceClass” 也没找到相关的内容)

在umeng发送推送通知后,app显示的日志:

D/awcn.DefaultHeartbeatImpl( 2932): |[seq:umeng:55c303e067e58e1c27003b82.AWCN3_1] heartbeat session:Session@[umeng:55c303e067e58e1c27003b82.AWCN3_1|http2_0rtt_acs]
D/awcn.TnetSpdySession( 2932): |[seq:umeng:55c303e067e58e1c27003b82.AWCN3_1] ping host:https://umengacs.m.taobao.com thread:AWCN Scheduler1
D/awcn.TnetSpdySession( 2932): |[seq:umeng:55c303e067e58e1c27003b82.AWCN3_1] https://umengacs.m.taobao.com submit ping ms:45051 force:true
I/awcn.TnetSpdySession( 2932): |[seq:umeng:55c303e067e58e1c27003b82.AWCN3_1] ping receive Host:https://umengacs.m.taobao.com id:79
I/flutter ( 2932): 定时获取消息未读数 afterTimer=2020-06-06 17:00:48.668669
I/flutter ( 2932): 定时获取消息未读数 afterTimer=2020-06-06 17:01:03.668338
E/awcn.TnetSpdySession( 2932): |[seq:umeng:55c303e067e58e1c27003b82.AWCN3_1] [spdyCustomControlFrameRecvCallback] len:650 frameCb:com.taobao.accs.net.j@3514f202
I/NAccs.InAppConn_default( 2932):  onDataReceive type:200
I/NAccs.MsgRecv_default( 2932):  onMessage host:https://umengacs.m.taobao.com
D/NAccs.MsgRecv_default( 2932):  version:2
D/NAccs.MsgRecv_default( 2932):  compress:0
D/NAccs.MsgRecv_default( 2932):  totalLen:646
D/NAccs.MsgRecv_default( 2932):  buf len:644
D/NAccs.MsgRecv_default( 2932):  flag:8c80
D/NAccs.MsgRecv_default( 2932):  target:VaWBzssEPBwDAOZuBQPUikPr|cc.qzone|agooSend|
D/NAccs.MsgRecv_default( 2932):  source:1|agooSend|11.21.9.58
D/NAccs.MsgRecv_default( 2932):  dataId:34nLHU90cA8mCnez
D/NAccs.MsgRecv_default( 2932):  extHeaderLen:77
D/NAccs.MsgRecv_default( 2932):   extHeaderType:4 value:f__-jXcjUn3iuLoJ&&5edb5b4fe91673b4f9&&VaWBzssEPBwDAOZuBQPUikPr
D/NAccs.MsgRecv_default( 2932):   extHeaderType:21 value:agooAck
D/NAccs.MsgRecv_default( 2932):   extHeaderType:9 value:sh
D/NAccs.MsgRecv_default( 2932):  oriData:[B@369217f2
I/NAccs.MsgRecv_default( 2932):  handleMessage dataId:34nLHU90cA8mCnez type:DATA reqType:DATA resType:NEED_ACK target:VaWBzssEPBwDAOZuBQPUikPr|cc.qzone|agooSend|
D/NAccs.MsgRecv_default( 2932):  handleMessage onPush isBurstData:false
I/NAccs.MsgRecv_default( 2932):  handleMessage try deliverMsg dataId:34nLHU90cA8mCnez target:cc.qzone serviceId:agooSend
I/NAccs.MsgRecv_default( 2932):  handleMessage try sendAck dataId dataId:34nLHU90cA8mCnez
D/NAccs.InAppConn_default( 2932):  sendMessage ready dataId:34nLHU90cA8mCnez type:DATA delay:0
D/NAccs.InAppConn_default( 2932):  sendMessage start dataId:34nLHU90cA8mCnez type:DATA
D/awcn.SessionCenter( 2932): |[seq:umeng:55c303e067e58e1c27003b82] getInternal u:https://umengacs.m.taobao.com sessionType:LongLink timeout:60000
D/awcn.StrategyCenter( 2932):  getSchemeByHost host:umengacs.m.taobao.com scheme:https
D/awcn.SessionCenter( 2932): |[seq:umeng:55c303e067e58e1c27003b82] get internal hit cache session session:Session@[umeng:55c303e067e58e1c27003b82.AWCN3_1|http2_0rtt_acs]
D/NAccs.Msg_InAppConn_default( 2932):  Build Message dataId:34nLHU90cA8mCnez
D/NAccs.Msg_InAppConn_default( 2932):   version:2 compress:0
D/NAccs.Msg_InAppConn_default( 2932):   flag: 0x40
D/NAccs.Msg_InAppConn_default( 2932):   totalLength:166
D/NAccs.Msg_InAppConn_default( 2932):   dataLength:164
D/NAccs.Msg_InAppConn_default( 2932):   flags:ffffa480
D/NAccs.MsgDistribute( 2932):  distribute ready action:com.taobao.accs.intent.action.RECEIVE dataId:34nLHU90cA8mCnez serviceId:agooSend
D/NAccs.MsgDistribute( 2932):  distribute start appkey:umeng:55c303e067e58e1c27003b82 config:default
D/NAccs.Msg_InAppConn_default( 2932):   targetLength:21
D/NAccs.MsgDistribute( 2932):  handleControlMsg configTag:default dataId:34nLHU90cA8mCnez serviceId:agooSend command:101 errorCode:0 appReceiver:
D/NAccs.InAppConn_default( 2932):  sendMessage ready dataId:1591434064112.12 type:DATA delay:0
I/NAccs.MsgDistribute( 2932):  handleBusinessMsg start dataId:34nLHU90cA8mCnez serviceId:agooSend command:101
D/NAccs.MsgDistribute( 2932):  handleBusinessMsg to start service className:org.android.agoo.accs.AgooService
I/NAccs.a ( 2932):  dispatchIntent start service 
D/NAccs.Msg_InAppConn_default( 2932):   target:1|agooSend|11.21.9.58
D/NAccs.Msg_InAppConn_default( 2932):   sourceLength:43
D/NAccs.Msg_InAppConn_default( 2932):   source:VaWBzssEPBwDAOZuBQPUikPr|cc.qzone|agooSend|
D/NAccs.Msg_InAppConn_default( 2932):   dataIdLength:16
D/NAccs.Msg_InAppConn_default( 2932):   dataId:34nLHU90cA8mCnez
D/NAccs.Msg_InAppConn_default( 2932):   extHeader len:77
D/NAccs.Msg_InAppConn_default( 2932):   extHeader key:4 value:f__-jXcjUn3iuLoJ&&5edb5b4fe91673b4f9&&VaWBzssEPBwDAOZuBQPUikPr
D/NAccs.Msg_InAppConn_default( 2932):   extHeader key:9 value:sh
D/NAccs.Msg_InAppConn_default( 2932):   extHeader key:21 value:agooAck
D/NAccs.Msg_InAppConn_default( 2932):   oriData:
D/NAccs.InAppConn_default( 2932):  sendMessage dataId:34nLHU90cA8mCnez command: host:https://umengacs.m.taobao.com len:170 utdid:VaWBzssEPBwDAOZuBQPUikPr
E/awcn.TnetSpdySession( 2932): |[seq:umeng:55c303e067e58e1c27003b82.AWCN3_1] sendCustomFrame dataId:-11 type:200
D/NAccs.InAppConn_default( 2932):  sendMessage end dataId:34nLHU90cA8mCnez status:true
D/NAccs.InAppConn_default( 2932):  sendMessage start dataId:1591434064112.12 type:DATA
D/awcn.SessionCenter( 2932): |[seq:umeng:55c303e067e58e1c27003b82] getInternal u:https://umengacs.m.taobao.com sessionType:LongLink timeout:60000
D/awcn.StrategyCenter( 2932):  getSchemeByHost host:umengacs.m.taobao.com scheme:https
D/awcn.SessionCenter( 2932): |[seq:umeng:55c303e067e58e1c27003b82] get internal hit cache session session:Session@[umeng:55c303e067e58e1c27003b82.AWCN3_1|http2_0rtt_acs]
D/NAccs.Msg_null( 2932):  Build Message dataId:1591434064112.12
D/NAccs.Msg_null( 2932):        version:2 compress:0
D/NAccs.Msg_null( 2932):        flag: 0x40
D/NAccs.Msg_null( 2932):        totalLength:118
D/NAccs.Msg_null( 2932):        dataLength:116
D/NAccs.Msg_null( 2932):        flags:ffff8000
D/NAccs.Msg_null( 2932):        targetLength:8
D/NAccs.Msg_null( 2932):        target:4|sal|st
D/NAccs.Msg_null( 2932):        sourceLength:31
D/NAccs.Msg_null( 2932):        source:VaWBzssEPBwDAOZuBQPUikPr|null||
D/NAccs.Msg_null( 2932):        dataIdLength:16
D/NAccs.Msg_null( 2932):        dataId:1591434064112.12
D/NAccs.Msg_null( 2932):        extHeader len:0
D/NAccs.Msg_null( 2932):        oriData:0|0|34nLHU90cA8mCnez|VaWBzssEPBwDAOZuBQPUikPr|agooSend
D/NAccs.InAppConn_default( 2932):  sendMessage dataId:1591434064112.12 command:100 host:https://umengacs.m.taobao.com len:122 utdid:VaWBzssEPBwDAOZuBQPUikPr
E/awcn.TnetSpdySession( 2932): |[seq:umeng:55c303e067e58e1c27003b82.AWCN3_1] sendCustomFrame dataId:12 type:200
D/NAccs.InAppConn_default( 2932):  sendMessage end dataId:1591434064112.12 status:true
D/NAccs.TaoBaseService( 2932):  onStartCommand className:AgooService
I/NAccs.a ( 2932):  onReceiveData dataId:34nLHU90cA8mCnez serviceId:agooSend command:101 className:org.android.agoo.accs.AgooService
D/NAccs.a ( 2932):  onReceiveData COMMAND_RECEIVE_DATA onData dataId:34nLHU90cA8mCnez serviceId:agooSend
I/NAccs.AgooService( 2932):  into--[onData]:serviceId:agooSend,dataId=34nLHU90cA8mCnez
D/NAccs.AgooService( 2932):  push data:[{"p":"cc.qzone","b":"1QpB4SfNe6Yuak8FKVzTUd55nrUeeJUI0kv2ULs6rIvAOKkAnyHMfzsP-STJfe7Yuqy0jfit4k-O\nqjpRaf6xuDUu0E2MG7m4SK_HDiu3jt2VBbuFKvUquCT_lN96dtbzeTF53nOos-gSbVa1fKLNu0oB\n0V76Mzu1d1Vv2_hX0LI66scl9t5gMtPARTJ3XNo04i6tDOiREudViK7mnGr49ovhYakETRce_ZNG\npXMUcfKSLqDJv1VJnIy4oDLGz2rWINukqc28LdW-f1XeK3rB69ltwoBW7jPf8QxyqqCZFqETSOFO\n5hYzHwX35hT1tp5YJckOSqdby1YzCtzkLrMhpQ==","f":324,"i":"f__-jXcjUn3iuLoJ&&5edb5b4fe91673b4f9&&AkA_O-quBraQWnGlreJCjmajVl6_XYzkB39SyV7dnZIh&&01&&"}]
I/NAccs.AgooFactory( 2932):  into--[AgooFactory,msgRecevie]:messageSource=accs
I/NAccs.AgooFactory( 2932):  saveMsg msgId:f__-jXcjUn3iuLoJ&&5edb5b4fe91673b4f9&&AkA_O-quBraQWnGlreJCjmajVl6_XYzkB39SyV7dnZIh&&01&&,message=[{"p":"cc.qzone","b":"1QpB4SfNe6Yuak8FKVzTUd55nrUeeJUI0kv2ULs6rIvAOKkAnyHMfzsP-STJfe7Yuqy0jfit4k-O\nqjpRaf6xuDUu0E2MG7m4SK_HDiu3jt2VBbuFKvUquCT_lN96dtbzeTF53nOos-gSbVa1fKLNu0oB\n0V76Mzu1d1Vv2_hX0LI66scl9t5gMtPARTJ3XNo04i6tDOiREudViK7mnGr49ovhYakETRce_ZNG\npXMUcfKSLqDJv1VJnIy4oDLGz2rWINukqc28LdW-f1XeK3rB69ltwoBW7jPf8QxyqqCZFqETSOFO\n5hYzHwX35hT1tp5YJckOSqdby1YzCtzkLrMhpQ==","f":324,"i":"f__-jXcjUn3iuLoJ&&5edb5b4fe91673b4f9&&AkA_O-quBraQWnGlreJCjmajVl6_XYzkB39SyV7dnZIh&&01&&"}],currentPack=cc.qzone,reportTimes=0
I/NAccs.MessageService( 2932):  addAccsMessage sqlite3--->[f__-jXcjUn3iuLoJ&&5edb5b4fe91673b4f9&&AkA_O-quBraQWnGlreJCjmajVl6_XYzkB39SyV7dnZIh&&01&&,message=[{"p":"cc.qzone","b":"1QpB4SfNe6Yuak8FKVzTUd55nrUeeJUI0kv2ULs6rIvAOKkAnyHMfzsP-STJfe7Yuqy0jfit4k-O\nqjpRaf6xuDUu0E2MG7m4SK_HDiu3jt2VBbuFKvUquCT_lN96dtbzeTF53nOos-gSbVa1fKLNu0oB\n0V76Mzu1d1Vv2_hX0LI66scl9t5gMtPARTJ3XNo04i6tDOiREudViK7mnGr49ovhYakETRce_ZNG\npXMUcfKSLqDJv1VJnIy4oDLGz2rWINukqc28LdW-f1XeK3rB69ltwoBW7jPf8QxyqqCZFqETSOFO\n5hYzHwX35hT1tp5YJckOSqdby1YzCtzkLrMhpQ==","f":324,"i":"f__-jXcjUn3iuLoJ&&5edb5b4fe91673b4f9&&AkA_O-quBraQWnGlreJCjmajVl6_XYzkB39SyV7dnZIh&&01&&"}],state=0]
D/FileCheckUtils( 2932): st.getAvailableBlocks()=443667,st.getAvailableBlocks() * blockSize=1817260032
E/awcn.TnetSpdySession( 2932): |[seq:umeng:55c303e067e58e1c27003b82.AWCN3_1] [spdyCustomControlFrameRecvCallback] len:82 frameCb:com.taobao.accs.net.j@3514f202
E/awcn.TnetSpdySession( 2932): |[seq:umeng:55c303e067e58e1c27003b82.AWCN3_1] str:20 0 0 4e 0 4c 60 0 1f 56 61 57 42 7a 73 73 45 50 42 77 44 41 4f 5a 75 42 51 50 55 69 6b 50 72 7c 6e 75 6c 6c 7c 7c 8 34 7c 73 61 6c 7c 73 74 10 31 35 39 31 34 33 34 30 36 34 31 31 32 2e 31 32 0 0 7b 22 63 6f 64 65 22 3a 22 32 30 30 22 7d 
I/NAccs.AgooFactory( 2932):  msgRecevie,message--->[[{"p":"cc.qzone","b":"1QpB4SfNe6Yuak8FKVzTUd55nrUeeJUI0kv2ULs6rIvAOKkAnyHMfzsP-STJfe7Yuqy0jfit4k-O\nqjpRaf6xuDUu0E2MG7m4SK_HDiu3jt2VBbuFKvUquCT_lN96dtbzeTF53nOos-gSbVa1fKLNu0oB\n0V76Mzu1d1Vv2_hX0LI66scl9t5gMtPARTJ3XNo04i6tDOiREudViK7mnGr49ovhYakETRce_ZNG\npXMUcfKSLqDJv1VJnIy4oDLGz2rWINukqc28LdW-f1XeK3rB69ltwoBW7jPf8QxyqqCZFqETSOFO\n5hYzHwX35hT1tp5YJckOSqdby1YzCtzkLrMhpQ==","f":324,"i":"f__-jXcjUn3iuLoJ&&5edb5b4fe91673b4f9&&AkA_O-quBraQWnGlreJCjmajVl6_XYzkB39SyV7dnZIh&&01&&"}]],utdid=VaWBzssEPBwDAOZuBQPUikPr
I/NAccs.AgooFactory( 2932):  agoo msg has no time
D/NAccs.Config( 2932):  getAgooAppKey appkey:umeng:55c303e067e58e1c27003b82
I/NAccs.AgooFactory( 2932):  sendMsgToBussiness intent:Bundle[{extData=null, oriData=[{"p":"cc.qzone","b":"1QpB4SfNe6Yuak8FKVzTUd55nrUeeJUI0kv2ULs6rIvAOKkAnyHMfzsP-STJfe7Yuqy0jfit4k-O\nqjpRaf6xuDUu0E2MG7m4SK_HDiu3jt2VBbuFKvUquCT_lN96dtbzeTF53nOos-gSbVa1fKLNu0oB\n0V76Mzu1d1Vv2_hX0LI66scl9t5gMtPARTJ3XNo04i6tDOiREudViK7mnGr49ovhYakETRce_ZNG\npXMUcfKSLqDJv1VJnIy4oDLGz2rWINukqc28LdW-f1XeK3rB69ltwoBW7jPf8QxyqqCZFqETSOFO\n5hYzHwX35hT1tp5YJckOSqdby1YzCtzkLrMhpQ==","f":324,"i":"f__-jXcjUn3iuLoJ&&5edb5b4fe91673b4f9&&AkA_O-quBraQWnGlreJCjmajVl6_XYzkB39SyV7dnZIh&&01&&"}], report=1, source=cc.qzone, id=f__-jXcjUn3iuLoJ&&5edb5b4fe91673b4f9&&AkA_O-quBraQWnGlreJCjmajVl6_XYzkB39SyV7dnZIh&&01&&, body=1QpB4SfNe6Yuak8FKVzTUd55nrUeeJUI0kv2ULs6rIvAOKkAnyHMfzsP-STJfe7Yuqy0jfit4k-O
I/NAccs.AgooFactory( 2932): qjpRaf6xuDUu0E2MG7m4SK_HDiu3jt2VBbuFKvUquCT_lN96dtbzeTF53nOos-gSbVa1fKLNu0oB
I/NAccs.AgooFactory( 2932): 0V76Mzu1d1Vv2_hX0LI66scl9t5gMtPARTJ3XNo04i6tDOiREudViK7mnGr49ovhYakETRce_ZNG
I/NAccs.AgooFactory( 2932): pXMUcfKSLqDJv1VJnIy4oDLGz2rWINukqc28LdW-f1XeK3rB69ltwoBW7jPf8QxyqqCZFqETSOFO
I/NAccs.AgooFactory( 2932): 5hYzHwX35hT1tp5YJckOSqdby1YzCtzkLrMhpQ==, trace=1591434064172, encrypted=4, fromAppkey=umeng:55c303e067e58e1c27003b82}],utdid=VaWBzssEPBwDAOZuBQPUikPr,pack=cc.qzone,agooFlag=false
D/NAccs.AdapterGlobalClientInfo( 2932):  getAgooCustomServiceName serviceName:com.umeng.message.UmengIntentService
I/NAccs.a ( 2932):  dispatchIntent start service 
I/NAccs.InAppConn_default( 2932):  onDataReceive type:200
I/NAccs.MsgRecv_default( 2932):  onMessage host:https://umengacs.m.taobao.com
D/NAccs.MsgRecv_default( 2932):  version:2
D/NAccs.MsgRecv_default( 2932):  compress:0
D/NAccs.MsgRecv_default( 2932):  totalLen:78
D/NAccs.MsgRecv_default( 2932):  buf len:76
D/NAccs.MsgRecv_default( 2932):  flag:6000
D/NAccs.MsgRecv_default( 2932):  target:VaWBzssEPBwDAOZuBQPUikPr|null||
D/NAccs.MsgRecv_default( 2932):  source:4|sal|st
D/NAccs.MsgRecv_default( 2932):  dataId:1591434064112.12

问题2.

页面埋点操作 import 'package:umeng_analytics_push/umeng_analytics_push.dart';

UmengAnalyticsPush.pageStart('memberPage');
UmengAnalyticsPush.pageEnd('memberPage');

该如何使用,可不可以有个示例?

问题3: 自定义点击Push响应(需要初始化时候打开开关) import 'package:umeng_analytics_push/umeng_analytics_push.dart';

UmengAnalyticsPush.addPushCustomMessageCallback((custom) {
  print(custom);
});

该如何使用,可不可以有个示例?

gaoyong06 commented 4 years ago

问题1: 现在可以了,在umeng后台多推了几条,可以了收到了 问题3: 我现在将UmengAnalyticsPush.addPushCustomMessageCallback 叫到了app首页的build方法里面,在应用在前台的时候,是可以点击了,也能收到自定义数据。但是当点击手机的home,将应用退到后台(此时应用没有被杀死),手机可以收到推送,但是点击推送时,没有任何反应,是不是应该在androidManifest里面配置个service之类的?

zileyuan commented 4 years ago

对于第三个问题,我只是封装了Umeng的UmengNotificationClickHandler方法,在方法中调用了推送到flutter的stream,你可以跟踪看看,在后台的时候UmengNotificationClickHandler里面的dealWithCustomAction是不是调用了

zileyuan commented 4 years ago

对于第二个问题,你可以在进入flutter的某个页面widget时候,调用一下pageStart,离开的时候调用pageEnd即可

zileyuan commented 4 years ago

以下是友盟的备注: UmengNotificationClickHandler是在BroadcastReceiver中被调用,因此若需启动Activity,需为Intent添加Flag:Intent.FLAG_ACTIVITY_NEW_TASK,否则无法启动Activity。

gaoyong06 commented 4 years ago

对于第二个问题,你可以在进入flutter的某个页面widget时候,调用一下pageStart,离开的时候调用pageEnd即可

感谢回复,这个我觉得参考下 这个项目的实现 在封装一个NavigatorObserver,是不是更便利一些?

gaoyong06 commented 4 years ago

以下是友盟的备注: UmengNotificationClickHandler是在BroadcastReceiver中被调用,因此若需启动Activity,需为Intent添加Flag:Intent.FLAG_ACTIVITY_NEW_TASK,否则无法启动Activity。

嗯嗯,理论上是可以的,但实际操作的时候,确实不行。 因为现在的跳转是在flutter里面是通过Navigator.push 这样跳转,我现在的实现方案是这样的:

假设: 在umeng push的自定义数据是:qzone://www.qqhot.com/feed/feed_info?feed_id=uzV55I8aS3m5 这是一个业务上的Uri String 期望用户收到推送后点击后跳转至这个Uri 项目的首页对应的一个flutter文件是:qzone_app/lib/pages/BottomTabs.dart Android启动Activity是MainActivity.kt

流程是: 用户点击推送 先打开MainActivity.kt, 然后 BottomTabs.dart,调用MainActivity.kt中定义的方法getIntentDataString,获取到启动MainActivity.kt时传递的Android Intent.dataString(就是上面提到的Uri) 然后在Navigator.push来跳转至该Uri

实现:qzone_app/android/app/src/main/AndroidManifest.xml

<activity
    android:name=".MainActivity"
    android:launchMode="singleTop"
    android:theme="@style/LaunchTheme"
    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
    android:hardwareAccelerated="true"
    android:windowSoftInputMode="adjustResize">
    <!-- Deep Links -->
    <intent-filter>

        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
        <category android:name="android.intent.category.DEFAULT"/>

        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <!-- Accepts URIs that begin with YOUR_SCHEME://YOUR_HOST -->
        <data
        android:scheme="qzone"
        android:host="www.qqhot.com" />
    </intent-filter>
</activity>

qzone_app/android/app/src/main/kotlin/cc/qzone_app/MainActivity.kt, 定义一个getIntentDataString 方法,获取到intent.dataString,然后通过flutter的页面获取

package cc.qzone
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
import io.github.zileyuan.umeng_analytics_push.UmengAnalyticsPushFlutterAndroid
import android.os.Bundle
import android.content.Intent
import io.flutter.embedding.engine.dart.DartExecutor
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import android.util.Log

///参考文档:
/// https://flutterchina.club/platform-channels/
/// https://www.jianshu.com/p/2e48cd960531

class MainActivity: FlutterActivity() {

  private var sharedText = "NO DATA"
  private val CHANNEL = "app.channel.shared.data"

  override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
    GeneratedPluginRegistrant.registerWith(flutterEngine)

    var intent : Intent = intent
    var action : String? = intent.action
    Log.d("qzone", "action: $action")
    var type : String? = intent.type
    Log.d("qzone", "type: $type")
    var uri : String? = intent.toUri(0);
    Log.d("qzone", "uri: $uri")
    var dataString : String? = intent.dataString
    Log.d("qzone", "dataString: $dataString")

    if (Intent.ACTION_SEND.equals(action) && type != null) {
       if ("text/plain".equals(type)) {
        handleSendText(intent) // Handle text being sent
       }
    }

    var flutterView : DartExecutor? = flutterEngine.dartExecutor
    MethodChannel(flutterView, CHANNEL).setMethodCallHandler {call, result ->
      when (call.method) {
          "getSharedText" -> {

            result.success(sharedText)
            sharedText = ""

          }
          "getIntentDataString" -> {
            result.success(dataString)
          }
          else -> {
            result.notImplemented()
          }
      }
    }

  }

  override fun onResume() {
    super.onResume()
    UmengAnalyticsPushFlutterAndroid.androidOnResume(this)
  }

  override fun onPause() {
    super.onPause()
    UmengAnalyticsPushFlutterAndroid.androidOnPause(this)
  }

  private fun handleSendText(intent: Intent ) {
    sharedText =  if (intent.getStringExtra(Intent.EXTRA_TEXT) != null) intent.getStringExtra(Intent.EXTRA_TEXT) else "NO DATA"
  }
}

qzone_app/lib/pages/BottomTabs.dart 获取到intentDataString后,然后通过Navigator.push来跳转

  ///获取从qzone_app/android/app/src/main/kotlin/cc/qzone_app/MainActivity.kt
  ///中执行getIntentDataString获取到的Intent Data String
  getIntentDataString() async {
    var intentDataString = await platform.invokeMethod("getIntentDataString");
    if (intentDataString != null) {

      logger.d("intentDataString: $intentDataString");
      Routes.openQzoneUri(context, intentDataString);
    }
  }
zileyuan commented 4 years ago

对于第二个问题,你可以在进入flutter的某个页面widget时候,调用一下pageStart,离开的时候调用pageEnd即可

感谢回复,这个我觉得参考下 这个项目的实现 在封装一个NavigatorObserver,是不是更便利一些?

我觉得做的纯粹一点,不想参与到flutter本身的一些机制里面,毕竟每个人的目的和做法不一样,提供基本功能,大家自己去实现也不是多麻烦的事情

zileyuan commented 4 years ago

以下是友盟的备注: UmengNotificationClickHandler是在BroadcastReceiver中被调用,因此若需启动Activity,需为Intent添加Flag:Intent.FLAG_ACTIVITY_NEW_TASK,否则无法启动Activity。

嗯嗯,理论上是可以的,但实际操作的时候,确实不行。 因为现在的跳转是在flutter里面是通过Navigator.push 这样跳转,我现在的实现方案是这样的:

假设: 在umeng push的自定义数据是:qzone://www.qqhot.com/feed/feed_info?feed_id=uzV55I8aS3m5 这是一个业务上的Uri String 期望用户收到推送后点击后跳转至这个Uri 项目的首页对应的一个flutter文件是:qzone_app/lib/pages/BottomTabs.dart Android启动Activity是MainActivity.kt

流程是: 用户点击推送 先打开MainActivity.kt, 然后 BottomTabs.dart,调用MainActivity.kt中定义的方法getIntentDataString,获取到启动MainActivity.kt时传递的Android Intent.dataString(就是上面提到的Uri) 然后在Navigator.push来跳转至该Uri

实现:qzone_app/android/app/src/main/AndroidManifest.xml

<activity
    android:name=".MainActivity"
    android:launchMode="singleTop"
    android:theme="@style/LaunchTheme"
    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
    android:hardwareAccelerated="true"
    android:windowSoftInputMode="adjustResize">
    <!-- Deep Links -->
    <intent-filter>

        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
        <category android:name="android.intent.category.DEFAULT"/>

        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <!-- Accepts URIs that begin with YOUR_SCHEME://YOUR_HOST -->
        <data
        android:scheme="qzone"
        android:host="www.qqhot.com" />
    </intent-filter>
</activity>

qzone_app/android/app/src/main/kotlin/cc/qzone_app/MainActivity.kt, 定义一个getIntentDataString 方法,获取到intent.dataString,然后通过flutter的页面获取

package cc.qzone
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
import io.github.zileyuan.umeng_analytics_push.UmengAnalyticsPushFlutterAndroid
import android.os.Bundle
import android.content.Intent
import io.flutter.embedding.engine.dart.DartExecutor
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import android.util.Log

///参考文档:
/// https://flutterchina.club/platform-channels/
/// https://www.jianshu.com/p/2e48cd960531

class MainActivity: FlutterActivity() {

  private var sharedText = "NO DATA"
  private val CHANNEL = "app.channel.shared.data"

  override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
    GeneratedPluginRegistrant.registerWith(flutterEngine)

    var intent : Intent = intent
    var action : String? = intent.action
    Log.d("qzone", "action: $action")
    var type : String? = intent.type
    Log.d("qzone", "type: $type")
    var uri : String? = intent.toUri(0);
    Log.d("qzone", "uri: $uri")
    var dataString : String? = intent.dataString
    Log.d("qzone", "dataString: $dataString")

    if (Intent.ACTION_SEND.equals(action) && type != null) {
       if ("text/plain".equals(type)) {
        handleSendText(intent) // Handle text being sent
       }
    }

    var flutterView : DartExecutor? = flutterEngine.dartExecutor
    MethodChannel(flutterView, CHANNEL).setMethodCallHandler {call, result ->
      when (call.method) {
          "getSharedText" -> {

            result.success(sharedText)
            sharedText = ""

          }
          "getIntentDataString" -> {
            result.success(dataString)
          }
          else -> {
            result.notImplemented()
          }
      }
    }

  }

  override fun onResume() {
    super.onResume()
    UmengAnalyticsPushFlutterAndroid.androidOnResume(this)
  }

  override fun onPause() {
    super.onPause()
    UmengAnalyticsPushFlutterAndroid.androidOnPause(this)
  }

  private fun handleSendText(intent: Intent ) {
    sharedText =  if (intent.getStringExtra(Intent.EXTRA_TEXT) != null) intent.getStringExtra(Intent.EXTRA_TEXT) else "NO DATA"
  }
}

qzone_app/lib/pages/BottomTabs.dart 获取到intentDataString后,然后通过Navigator.push来跳转

  ///获取从qzone_app/android/app/src/main/kotlin/cc/qzone_app/MainActivity.kt
  ///中执行getIntentDataString获取到的Intent Data String
  getIntentDataString() async {
    var intentDataString = await platform.invokeMethod("getIntentDataString");
    if (intentDataString != null) {

      logger.d("intentDataString: $intentDataString");
      Routes.openQzoneUri(context, intentDataString);
    }
  }

你的做法可以给后来人参~~~

zileyuan commented 4 years ago

内置解决了问题