广大的开发者吃糠咽菜开发了一两款APP,获取了一些流量后自然就会想到流量变现,一般情况下大家会选择到百度联盟或者Google Admob这些广告服务提供商注册开发者账号,在自己的APP里面加上几行广告位代码,集成他们的广告SDK包。然后谋事在人,成事在天,只有每天看报表查查收益。
也有一些开发者为了能够提高自己的变现水平,同时接入了好几家的sdk,哪家出的收益高一点我就出哪家的广告,但是这样做也不是没有代价的,一是包的体积会增加不少,对下载成功率影响很大,二是市面上的广告SDK也良莠不齐,有些SDK在可能在后台会做一些“高级”工作,轻则导致用户流失重则导致开发账号被禁。
本文的目的就是告诉你一款广告SDK在我们的系统里面到底会做什么以及应该做什么,知道了这些的话,聪明的开发者就可以更好的优化自己的广告获取更多的收入,甚至可以根据这些步骤自己开发一款自己的广告SDK,用于制作自己的广告投放系统。
文末还有福利,介绍一种不用开发和对接就可以管理自己广告资源的方法。
1 SDK工作流程
一般情况下移动广告SDK的大致工作流程如下:
如上图所示,其实广告SDK充当了一个中间代理角色,它负责App的事件处理,向服务器发送广告请求,渲染广告创意,上报广告展示事件等等,开发者不需要自己和广告服务器进行交互,不需要自己渲染广告位,不需要自己处理事件,极大的简化了开发的复杂度,下面我们详细讲解每一个步骤:
1.1 广告位展示机会
移动广告位有多种多样的展示形式,应用使用的不同时机可以展示不同形式的广告,一般常用的广告展示机会是用户打开App是加载启动页广告,玩游戏暂停的时候进入插屏,在页面顶部或者底部加载横幅广告等。广告位设计的原则是清楚的展示广告创意信息,并且不至于影响用户体验。最近原生广告比较流行,原因就是原生广告可以和应用本身内容的上下文保持一致不会显得非常突兀。
1.2 系统软硬件信息获取
SDK获取适当系统信息有助于精准投放广告以及广告反作弊和广告计费,比如获取用户手机型号,系统软件版本,IP,MAC,IMEI等等,有些SDK会获取用户的隐私信息,比如获取用户联系人通讯录,账号信息,手机号等等,这些我们是不提倡的。
获取这些适当的信息需要增加一些系统权限:
<uses-permissionandroid:name="android.permission.INTERNET"/>
<uses-permissionandroid:name="android.permission.READ_PHONE_STATE"/>
<uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
下面是获得一些系统软硬件系统的代码:
public class DeviceInfoUtil {
private Activity activity;
public DeviceInfoUtil(Activity activity) {
this.activity = activity;
}
private String getIP() {
try {
Context context =activity.getApplicationContext();
NetworkInfo info =((ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
if (info != null &&info.isConnected()) {
if (info.getType() ==ConnectivityManager.TYPE_MOBILE) {//当前使用2G/3G/4G网络
for(Enumeration<NetworkInterface> en =NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
NetworkInterfaceintf = en.nextElement();
for(Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses();enumIpAddr.hasMoreElements(); ) {
InetAddressinetAddress = enumIpAddr.nextElement();
if(!inetAddress.isLoopbackAddress() && inetAddress instanceofInet4Address) {
returninetAddress.getHostAddress();
}
}
}
} else if (info.getType()== ConnectivityManager.TYPE_WIFI) {
WifiManager wifiManager= (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo =wifiManager.getConnectionInfo();
String ipAddress =intIP2StringIP(wifiInfo.getIpAddress());
return ipAddress;
}
}
} catch (Exception e) {
return "";
}
return "";
}
private String getAppversion() {
PackageManager pm =activity.getApplicationContext().getPackageManager();
try {
PackageInfo pi =pm.getPackageInfo(activity.getPackageName(), 0);
String appVersion =pi.versionName;
return appVersion;
} catch (Exception e) {
return "1.0";
}
}
private String intIP2StringIP(int ip) {
return (ip & 0xFF) + "." +
((ip >> 8) &0xFF) + "." +
((ip >> 16) &0xFF) + "." +
(ip >> 24 &0xFF);
}
private String getCurrentUserAgent() {
try {
String userAgent =System.getProperty("http.agent");
return userAgent;
} catch (Exception e) {
return "";
}
}
private String getPhoneIMEI() {
try {
TelephonyManager mTm =(TelephonyManager)activity.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);