我的一位用户向我透露,他们正在使用我的免费应用程序,该应用程序通过广告实现盈利,但是他们正在使用广告拦截器来屏蔽广告。他嘲讽地告诉我这个信息,好像我对此无能为力。
我能否采取措施解决这个问题?有没有办法检测到广告被拦截了?
我的一位用户向我透露,他们正在使用我的免费应用程序,该应用程序通过广告实现盈利,但是他们正在使用广告拦截器来屏蔽广告。他嘲讽地告诉我这个信息,好像我对此无能为力。
我能否采取措施解决这个问题?有没有办法检测到广告被拦截了?
我知道一种广告拦截的方式(适用于任何计算机),就是编辑 hosts 文件,将所有已知的广告服务器指向本地主机。在 Android 上,这个文件位于“etc/hosts”。
例如,我使用 AdMob 广告,一个来自自定义 ROM 列表的 host 文件列出了以下的 AdMob 条目:
127.0.0.1 analytics.admob.com
127.0.0.1 mmv.admob.com
127.0.0.1 mm.admob.com
127.0.0.1 admob.com
127.0.0.1 a.admob.com
127.0.0.1 jp.admob.com
127.0.0.1 c.admob.com
127.0.0.1 p.admob.com
127.0.0.1 mm1.vip.sc1.admob.com
127.0.0.1 media.admob.com
127.0.0.1 e.admob.com
现在,任何时候,当一个进程试图解析以上地址时,它们都会被路由到其左侧列出的地址(本地主机),在这种情况下。 BufferedReader in = null;
try
{
in = new BufferedReader(new InputStreamReader(
new FileInputStream("/etc/hosts")));
String line;
while ((line = in.readLine()) != null)
{
if (line.contains("admob"))
{
result = false;
break;
}
}
}
我发誓所有广告支持的应用程序都应该检查此文件。您不需要以root身份访问它,但写入它可能会有所不同。
此外,不确定是否有其他文件在基于Linux的操作系统上起着相同的作用,但无论如何,我们都可以检查所有这些文件。
欢迎任何改进建议。
还有一个名为“Ad Free Android”的应用程序需要root访问权限,这意味着它很可能会更改hosts文件以实现其目标。
if (line.contains("admob"))
应该改为if(line.contains("admob") && !line.matches("^ *#"))
。改动后意思保持不变,但请确保语言更加通俗易懂。 - Kevin Mark我为此问题的代码如下:
try {
if (InetAddress.getByName("a.admob.com").getHostAddress().equals("127.0.0.1") ||
InetAddress.getByName("mm.admob.com").getHostAddress().equals("127.0.0.1") ||
InetAddress.getByName("p.admob.com").getHostAddress().equals("127.0.0.1") ||
InetAddress.getByName("r.admob.com").getHostAddress().equals("127.0.0.1")) {
//Naughty Boy - Punishing code goes here.
// In my case its a dialog which goes to the pay-for version
// of my application in the market once the dialog is closed.
}
} catch (UnknownHostException e) { } //no internet
希望能有所帮助。
你能检查一下广告是否已经在你的应用程序中加载了吗?
广告拦截器的作用是防止你的应用程序下载数据。你可以检查广告框架中数据的内容长度,以确保数据存在。
如果没有数据,请弹出一条消息并退出,或通过电子邮件警告你。
这可能不是你想象中的那么大的问题,因为只有很少一部分人会屏蔽广告。
如果成功,应用程序就可以开始了。
为了添加一些代码,监听器类应该是这样的:
public abstract class AdBlockerListener implements AdListener {
@Override
public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) {
if (arg1.equals(ErrorCode.NETWORK_ERROR)) {
try {
URL url = new URL("http://www.apple.com/");
URLConnection conn = url.openConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
reader.readLine();
onAdBlocked();
} catch (IOException e) {}
}
}
public abstract void onAdBlocked();
}
然后,每个带有adView的活动都会执行以下操作:
AdView adView = (AdView) findViewById(R.id.adView);
adView.setAdListener(new AdBlockerListener() {
@Override
public void onAdBlocked() {
AlertDialog ad = new AlertDialog.Builder(CalendarView.this)
.setMessage("nono")
.setCancelable(false)
.setNegativeButton("OK", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
System.exit(1);
}
})
.show();
}
});
你做的任何事情,你的用户都可以做得更好。
唯一能够在某种程度上有效的方法是将广告作为程序的不可分割部分,这样如果广告被屏蔽,用户就无法理解/与应用程序进行交互。
用户绕过广告有两种方法:
1)在没有联网的情况下使用应用程序。
2)使用已 root 的手机和修改后的主机文件。
我制作了两个工具,您可以实现,请参见以下代码。
checkifonline(); 用于解决问题1:
public void checkifonline() {
boolean haveConnectedWifi = false;
boolean haveConnectedMobile = false;
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
if (ni.getTypeName().equalsIgnoreCase("WIFI"))
if (ni.isConnected())
haveConnectedWifi = true;
if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
if (ni.isConnected())
haveConnectedMobile = true;
}
if(haveConnectedWifi==false && haveConnectedMobile==false){
// TODO (could make massage and than finish();
}
}
adblockcheck();是针对问题2的
private void adblockcheck() {
BufferedReader in = null;
boolean result = true;
try
{
in = new BufferedReader(new InputStreamReader(
new FileInputStream("/etc/hosts")));
String line;
while ((line = in.readLine()) != null)
{
if (line.contains("admob"))
{
result = false;
break;
}
}
} catch (UnknownHostException e) { }
catch (IOException e) {e.printStackTrace();}
if(result==false){
// TODO (could make massage and than finish();
}
}
我认为这取决于广告内容提供商。我知道AdMob SDK在广告请求失败时提供回调。我猜想你可以注册这个回调,然后在回调中检查连接 - 如果有连接而你没有收到广告 - 注意一下,如果发生了一两次以上的情况,很可能你的广告被阻止了。我没有使用过Google的AdSense for Mobile工具集,但如果有类似的回调机制,我也不会感到惊讶。
PackageManager pm = activity.getPackageManager ();
Intent intent = pm.getLaunchIntentForPackage ( "de.ub0r.android.adBlock" );
if ( Reflection.isPackageInstalled ( activity, intent ) ) {
// they have adblock installed
}