在我的安卓应用中,我有一个 Activity,其中包含 3 或 4 个片段,这些片段可以根据一些用户或服务器事件依次连接。
我想将所有这些片段作为屏幕在 Firebase 中进行跟踪。
因此,如果可能的话,是否有一个 API 可以在片段的 onCreate 中调用,并告诉 Firebase 用户当前正在 fragment1、fragment2 或 fragment3 中?
在我的安卓应用中,我有一个 Activity,其中包含 3 或 4 个片段,这些片段可以根据一些用户或服务器事件依次连接。
我想将所有这些片段作为屏幕在 Firebase 中进行跟踪。
因此,如果可能的话,是否有一个 API 可以在片段的 onCreate 中调用,并告诉 Firebase 用户当前正在 fragment1、fragment2 或 fragment3 中?
更新
由于setCurrentScreen
已经被弃用,您可以使用logEvent
方法。
Bundle bundle = new Bundle();
bundle.putString(FirebaseAnalytics.Param.SCREEN_NAME, fragment.getClass().getSimpleName());
bundle.putString(FirebaseAnalytics.Param.SCREEN_CLASS, fragment.getClass().getSimpleName());
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW, bundle);
我使用以下adb命令来检查是否一切正常。
adb shell setprop log.tag.FA VERBOSE
adb shell setprop log.tag.FA-SVC VERBOSE
adb logcat -v time -s FA FA-SVC
执行此操作后,您将在logcat中看到screen_view
事件。就像这个:
10-15 13:14:13.744 V/FA-SVC (20323): Logging event: origin=app,name=screen_view(_vs),params=Bundle[{ga_event_origin(_o)=app, engagement_time_msec(_et)=31600, ga_previous_class(_pc)=ContentsFragment, ga_previous_id(_pi)=8077407744361472421, ga_previous_screen(_pn)=ContentsFragment, ga_screen_class(_sc)=TestFragment, ga_screen_id(_si)=8077407744361472423, ga_screen(_sn)=TestFragment}]
有一个特殊的方法可以设置当前屏幕 - setCurrentScreen
。
我是这样使用它的:
mFirebaseAnalytics.setCurrentScreen(this, fragment.getClass().getSimpleName(), fragment.getClass().getSimpleName());
一旦调用该方法,LogCat中会出现以下消息:
Logging event (FE): screen_view(_vs), Bundle[{firebase_event_origin(_o)=auto, firebase_previous_class(_pc)=HomeFragment, firebase_previous_id(_pi)=4121566113087629222, firebase_previous_screen(_pn)=HomeFragment, firebase_screen_class(_sc)=StatisticsFragment, firebase_screen_id(_si)=4121566113087629223, firebase_screen(_sn)=StatisticsFragment}]
自动活动跟踪中出现以下事件:
Logging event (FE): screen_view(_vs), Bundle[{firebase_event_origin(_o)=auto, firebase_previous_class(_pc)=StatisticsFragment, firebase_previous_id(_pi)=4121566113087629223, firebase_previous_screen(_pn)=StatisticsFragment, firebase_screen_class(_sc)=LoginActivity, firebase_screen_id(_si)=4121566113087629224}]
正如您所见,它们几乎相同,所以 setCurrentScreen
正常工作。
我只能在第二天在 Firebase 控制台中看到这些类。这对于 Firebase 来说是正常的-处理这些数据需要时间。
在Artem Mostyaev的回答中,我希望能够增加更多深入的见解。GA/Firebase面板在DEV版本中反映出了类名,但在PROD版本中没有反映出来。这里的主要罪魁祸首是
fragment.getClass().getSimpleName()
在生产环境中,我们对片段名称进行了混淆。因此,GA/Firebase 显示的类名会像 (a,b,ah 等)。
在其他情况下使用getSimpleName()也是危险的。
Proguard 规则
-keepnames class com.somepackage.yourclass
-keepnames class * extends androidx.fragment.app.Fragment
。 - mindw0rk由于 setCurrentScreen
已经弃用,您可以使用 firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW, bundle)
代替。
这里有一篇博客文章here,详细解释了如何手动跟踪屏幕。
以下是一个例子:
private fun setCurrentScreen(screenName: String) = firebaseAnalytics?.run {
val bundle = Bundle()
bundle.putString(FirebaseAnalytics.Param.SCREEN_NAME, screenName)
bundle.putString(FirebaseAnalytics.Param.SCREEN_CLASS, this@BaseFragment.javaClass.simpleName)
logEvent(FirebaseAnalytics.Event.SCREEN_VIEW, bundle)
}
BaseFragment
生命周期方法(如onResume
)中调用此函数。请注意,有些片段可能不必更改当前屏幕,例如那些在ViewPager
中创建的片段,因此我声明了一个open val
,您可以override
以更改默认行为。BaseFragment
中的代码:protected open val trackScreenView: Boolean = true
override fun onResume() {
super.onResume()
if (trackScreenView) setCurrentScreen(this.javaClass.simpleName)
}
你可以通过在目标Fragment
中覆盖它来禁用它:
override val trackScreenView: Boolean = false
NavigationUI
组件,则目前没有自动跟踪屏幕的解决方案,它只会跟踪您拥有的单个活动,因此您可以通过在应用程序清单中添加此meta-data
来防止Firebase自动屏幕报告:<application
android:name=".App"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<!-- .... -->
<meta-data
android:name="google_analytics_automatic_screen_reporting_enabled"
android:value="false" />
</application>
NavController.OnDestinationChangedListener
在 onCreate()
内部。override fun onCreate() {
super.onCreate()
.
.
.
.
navController = Navigation.findNavController(context!!, R.id.nav_host_fragment)
navController?.addOnDestinationChangedListener(listener)
}
在这3个监听函数参数中,
controller
用于获取类名信息。destination
用于获取目标布局 XML 名称字符串,可以通过 android:label
属性在 nav_host_fragment 中找到。private val listener = NavController.OnDestinationChangedListener { controller, destination, arguments ->
val bundle = Bundle()
val currentFragmentClassName = (controller.currentDestination as FragmentNavigator.Destination).className
bundle.putString(FirebaseAnalytics.Param.SCREEN_NAME, destination.label.toString())
bundle.putString(FirebaseAnalytics.Param.SCREEN_CLASS, currentFragmentClassName)
FirebaseAnalytics.getInstance(requireContext()).logEvent(FirebaseAnalytics.Event.SCREEN_VIEW, bundle)
}
不要忘记清理
override fun onDestroy() {
super.onDestroy()
navController?.removeOnDestinationChangedListener(listener)
}
onStart
、onResume
还是其他方法中?(在一个片段中) - Thomas VosonResume
是最好的选择,因为当你从另一个片段返回时,它会被调用。 - Artem MostyaevsetCurrentScreen
的时间。 - Artem MostyaevsetCurrentScreen
已经过时了 :( - Kartik Garasia