通过一个星期的研究,终于把GooglePlay下载来源数据统计按小于Google Play8.3.73版本和大于等于Google Play8.3.73版本做了版本的区分并在代码上实现,通过这篇文章记录一下自己的实现过程和遇到的问题或许能帮助一些刚接触这个的人。由于之前完全对这东西没有什么概念所以花了不少时间才弄明白。所谓的GooglePlay下载来源数据,就是你的应用通过广告推广到各个渠道,当某个用户点击这条广告之时,会跳转到Google Play的此应用的下载页面Google Play会记录你是在哪个推广渠道跳转到Google Play的,当你下载安装之后你可以用谷歌提供的api来获取到这些信息,这些数据信息能够帮助你去分析哪个渠道带来的用户量更多。在Google Play8.3.73之前通过广播来获取来源信息,在Google Play8.3.73版本和之后的版本通过新版的api与Google Play建立链接之后获取,虽然旧版的api在新版Google Play上也能用,但是新版的api可以获取到更多的信息(安装时间,和点击时间),所以做了版本的区分。
1.添加谷歌api依赖,每个都要用最新的版本不然会出现有些类找不到的问题,可以通过以下链接去查看自己引用的包是否是最新的: https://developers.google.com/android/guides/setup
implementation 'com.google.android.gms:play-services-gcm:15.0.1'
implementation 'com.android.installreferrer:installreferrer:1.0'
implementation 'com.google.android.gms:play-services-analytics:16.0.3'
implementation 'com.google.android.gms:play-services-auth:16.0.0'
2.在Googl play<8.3.73时候通过广播获取来源数据,所以需要在自己的AndroidManifest.xml配置广播,代码如下,一个是谷歌的广播,一个 是我自定义的广播。当应用安装成功并第一次启动的时候谷歌会发送com.android.vending.INSTALL_REFERRER广播到当前应用(此广播不会被其它应用所接收,只会被当前应用所接收)。由于新版的i获取来源信息的api也要保证获取一次,避免数据重复统计,所以我也把新版的接入依赖于这个广播(谷歌推荐监听 Intent.ACTION_PACKAGE_FIRST_LAUNCH这个广播,但是通过很多测试根本收不到这个广播)。
<!-- Google Analytics -->
<receiver android:name="com.google.android.gms.analytics.CampaignTrackingReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
<!--自己写的监听广播-->
<receiver
android:name=".InstallReferrerBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER"/>
</intent-filter>
</receiver>
3.下面是直接对自定义的广播的onReceive里面做我们的数据分版本获取。之前一直纠结Googl play的版本是否大于等于8.3.73的问题,后来反编译发现8.3.73的版本versionCode="80837300",所以可以通过获取versionCode,如果versionCode<80837300就用旧版api,不然旧用新版api。下面附上我的广播类代码供参考。
package 包名;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.RemoteException;
import com.android.installreferrer.api.InstallReferrerClient;
import com.android.installreferrer.api.InstallReferrerStateListener;
import com.android.installreferrer.api.ReferrerDetails;
import com.google.android.gms.analytics.CampaignTrackingReceiver;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
/**
* 监听Google play下载安装来源的广播
*/
public class InstallReferrerBroadcastReceiver extends BroadcastReceiver {
private InstallReferrerClient mReferrerClient;
private Context context;
private Intent intent;
@Override
public void onReceive(Context context, Intent intent) {
int appVersionCode = getAppVersionCode(context);
this.context = context;
this.intent = intent;
String mAction = intent.getAction();
DebugSetting.toLog("收到广播的回调mAction=" + mAction);
if (appVersionCode < 80837300) {
DebugSetting.toLog("旧版获取渠道来源数据");
getInstallReferrerData();
} else {
DebugSetting.toLog("新版获取渠道来源数据");
getConnect();
}
}
/**
* Google Play版本<8.3.73时获取安装来源数据
*/
private void getInstallReferrerData() {
Bundle extras = intent.getExtras();
String referrer = "";
if (extras != null) {
referrer = extras.getString("referrer");
// 格式:utm_source=testSource&utm_medium=testMedium&utm_term=testTerm&utm_content=11
upLoadinstallReferrer(referrer);
}
new CampaignTrackingReceiver().onReceive(context, intent);//调用谷歌广播的方法
}
/**
* 获取版本号
*
* @return Google Play应用的版本号
*/
public static int getAppVersionCode(Context context) {
try {
PackageManager manager = context.getPackageManager();
PackageInfo info = manager.getPackageInfo("com.android.vending", 0);
int version = info.versionCode;
return version;
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
/**
* 与谷歌商店建立连接
*/
private void getConnect() {
mReferrerClient = InstallReferrerClient.newBuilder(context).build();
mReferrerClient.startConnection(installReferrerStateListener);
}
private InstallReferrerStateListener installReferrerStateListener = new InstallReferrerStateListener() {
@Override
public void onInstallReferrerSetupFinished(int responseCode) {
switch (responseCode) {
case InstallReferrerClient.InstallReferrerResponse.OK:
// Connection established
// Toast.makeText(context, "与谷歌商店连接成功", Toast.LENGTH_LONG).show();
DebugSetting.toLog("与谷歌商店连接成功");
getMessage();
break;
case InstallReferrerClient.InstallReferrerResponse.FEATURE_NOT_SUPPORTED:
// API not available on the current Play Store app
// Toast.makeText(context, "与谷歌商店连接失败", Toast.LENGTH_LONG).show();
DebugSetting.toLog("与谷歌商店连接失败败:API not available on the current Play Store app");
break;
case InstallReferrerClient.InstallReferrerResponse.SERVICE_UNAVAILABLE:
// Connection could not be established
DebugSetting.toLog("InstallReferrerClient.InstallReferrerResponse.SERVICE_UNAVAILABLE");
// Toast.makeText(context, "与谷歌商店连接失败", Toast.LENGTH_LONG).show();
break;
}
}
@Override
public void onInstallReferrerServiceDisconnected() {
// Try to restart the connection on the next request to
// Google Play by calling the startConnection() method.
DebugSetting.toLog("onInstallReferrerServiceDisconnected()");
//重新连接
getConnect();
}
};
/**
* Google Play版本>=8.3.73时获取安装来源数据
*/
private void getMessage() {
try {
ReferrerDetails response = mReferrerClient.getInstallReferrer();
String installReferrer = response.getInstallReferrer();
long referrerClickTimestampSeconds = response.getReferrerClickTimestampSeconds();
installReferrer = installReferrer + "&" + "referrerClickTimestampSeconds=" + referrerClickTimestampSeconds;
long installBeginTimestampSeconds = response.getInstallBeginTimestampSeconds();
installReferrer = installReferrer + "&" + "installBeginTimestampSeconds=" + installBeginTimestampSeconds;
upLoadinstallReferrer(installReferrer);
} catch (RemoteException e) {
e.printStackTrace();
}
new CampaignTrackingReceiver().onReceive(context, intent);//调用谷歌广播的方法
}
/**
* 上传数据到服务器
*/
private void upLoadinstallReferrer(String referer) {
JSONObject object = getSplitData(referer);
//下面做自己上传数据到服务端的操作,数据为object,要加参数自己加
}
/**
* 把格式:utm_source=testSource&utm_medium=testMedium&utm_term=testTerm&utm_content=11
* 这种格式的数据切割成key,value的形式并put进JSONObject对象,用于上传
* @param referer
* @return
*/
private JSONObject getSplitData(String referer) {
JSONObject object = new JSONObject();
for (String data : referer.split("&")) {
String[] split = data.split("=");
for (int i = 0; i < split.length; i++) {
try {
object.put(split[0], split[1]);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
return object;
}
}
4.接下来就是如何测试的问题,由于之前完全没有接触所以在摸索如何测试之时花了许多时间,首先进行本地测试(因为应用发布到GooglePlay是要时间审核的,并且上传的应用不能够打印日志,所以先本地测试,节约时间),所谓的本地测试就是通过adb命令发送一个广播,然后通过日志或者打印看是否能获取到数据,如果有加上统计看是否能统计到来源信息,由于GooglePlay8.3.73版本和之后的版本来源信息不是通过广播传给我们应用而是通过与GooglePlay建立连接之后获取,所以本地测试只能测试GooglePlay8.3.73之前的来源信息获取,测试方法:
4.1通过Android Studio的Terminal窗口下输入adb shell然后点击enter键如果有下面截图现象则成功进入到adb命令模式,如果 提示不是内部命令或者命令不存在等问题是因为没有配置环境变量,可以百度搜一下这里不再细说。
4.2模拟GooglePlay发送com.android.vending.INSTALL_REFERRER广播,根据下面的adb命令,替换自己的包名和自定义的广 播路径,然后输入,回车。
am broadcast -a com.android.vending.INSTALL_REFERRER -n 应用包名/包名.自定义的广播名 --es "referrer" "utm_source=testSource&utm_medium=testMedium&utm_term=testTerm&utm_content=11"
4.3如果有result=0则表明广播发送成功,如果没有检查一下自己的包名和广播的路径是否正确。发送广播成功就可以验证自己的 代码是否获取来源数据成功了。
5.本地测试成功之后那么接下来就是发布一个Beat版应用到GooglePlay进行真实的环境测试了。如何发布Beat版应用到 GooglePlay 这里不再说明,直接说上传之后的测试流程。
5.1当你的应用上传之后,你需要通过谷歌的一个Url构建网址去创建一个模拟广告的的url,
网址:https://www.digitangle.co.uk/toolsandresources/google-play-url-builder/#sthash.HLdt4vXJ.dpbs
如下图所示填写各个信息,最种要的就是你的应用包名(决定最后生成的url能指向你发布的应用),其它的信息可自行有道翻译,填写完之后点击“Generate URL”就能帮你生成一个模拟广告链接的Url
5.2在手机上装上Opera浏览器(之所以使用这个浏览器是因为他能够跳转到GooglePlay,像百度,火狐,qq这些浏览器是跳不过去的,导致你的url不能满足广告链接,不能统计到来源数据,被坑死了),将5.1生成的url在这个浏览器打开,然后他会将你带到GooglePlay商店并且是你的应用的下载页面,然后你直接就可以下载了。下载完之后打开应用,看看是否有统计到来源信息,统计到的数据是否是自己在谷歌Url构建网址上构建url时填写的信息。由于com.android.vending.INSTALL_REFERRER广播只会在第一次启动的时候发送,所以有问题的话要反复卸载再重装,如果是代码问题就需要更新应用了,谷歌审核一个应用大概半个小时,所以尽量确定代码没问题之后再更新。
5.3如果当前的Googleplay版本能正常统计到数据,那就卸载当前的GooglePlay装不同的版本进行测试。主要是测一个8.3.73之前的版本和一个8.3.73版本或之后的版本都能统计到准确的数据那么测试就算完成了。
6.获取GooglePlay下载来源广告数据统计接入完成。