您的位置:首页 > 移动开发 > Unity3D

Unity Android平台AdMob应用

2011-12-28 23:51 330 查看
开发环境
Window7
Unity3D  3.4.1
MB525defy Android 2.2.1

        羽化的第二十一篇博客,这次一次发布三篇确实有点漫长。。。因为最近羽化一直很忙,没多少时间重新整理Android AdMob方面的东西,正好今天有空就把准备写的补上。其实羽化这方面也不是很熟悉,但知道的解决方法有两三种,这次就说一个最简单的解决方案,并送上代码,以后任何人开发都可以改改项目名称和ID就可以直接拿来用。很多方法来自官方的大牛们热议,大家可以可以借鉴下这些脚本写法。

        最近通关了刺客信条启示录,作为Ezio和Altair时代的终结,本作应该算是前作兄弟会的延伸,创新点不多,但依然很有趣,刺客养成方面做得过于繁琐,也没有隐藏的装备了,这点实在是可惜。想当初羽化开始玩刺客信条系列的时候,大概读大一,XBOX360才刚买不久,家里还是一个纯平电视,第一次玩的时候感觉很兴奋,开阔的场景,密集的建筑,自由的攀爬,这就是游戏的乐趣,真正的次世代体验,但初代任务方面薄弱很多,幸运的是,刺客信条系列总是在不断改进和创新,可以看到开发团队在这方面的努力,这种开发游戏的态度值得游戏制作人学习,希望这个系列能做得更好,真正做到“万物皆虚,万事皆允”,应该下一作就是终结。

本次学习:
1. Eclipse报错解决方案
2. AdMob应用
 

1.Eclipse报错解决方案
      本来不用写的,但羽化在打开Eclipse的时候遇到了几个蛋疼问题,下面羽化把这几个问题做个小小总结:
(1)Error: Unableto open class file XXX/R.java错误
      有两种解决方案:首先是Project -> clean 再勾上Build Automatically,可以解决一类常出现的脑抽问题。。。其次是Window -> Preferences -> Java -> Build Path 中选择Project -> Apply,可以解决些意外问题。。。
(2)error generating final archive 错误
   这类错误一般新手是遇不到的,因为这是证书过期引起的,一般证书有效期只有1年,超过1年后,所有新建的Android工程都会无故报错,解决方法是来到Window -> Preferences -> Android -> Build中 Default debug keystore目录下,复制里面地址打开删除debug.keystore及 ddms.cfg两个文件,重启eclipse就可以解决。


 
2.AdMob应用

      首先是Eclipse上Android项目的写法,导入羽化的项目AdMob(Import –> Existing Projects into Workspace),肯定会报错。。。



       这时修改引用,选中项目文件单击鼠标右键-> Properties -> Java Build Path里面的Libraries,把admob-sdk-android.jar和classes.jar文件重新Edit到当前的libs里面,再到Order and Export里面勾选上。

       注意: admob-sdk-android.jar是网上一个大牛封装的AdMob SDK,有一些自己的方法,但不是最新版本,下载最新版本的同学注意Android系统版本最好超过3.2,否则广告栏会显示一段错误。classes.jar是Unity里面自带的一个jar包,通过搜寻就可以知道位置,羽化就不再介绍。

       如果不出意外,现在应该完全不会报错,报错了请看上面的注意和Eclipse报错原因。。。下面我们看代码

AdMob.java

package com.LB.AdMob;   //必须改变

import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.widget.LinearLayout;
import android.os.Message;

import com.unity3d.player.*;

import com.admob.android.ads.AdView;
import com.admob.android.ads.SimpleAdListener;

public class AdMob extends UnityPlayerActivity
{
public AdView adView;
private boolean adVisible = true;
protected void onCreate(Bundle savedInstanceState)
{
Log.i("AdMob", "onCreate");
super.onCreate(savedInstanceState);

setupAds();
}
private Handler handler = new Handler()
{
public void  handleMessage(Message msg)
{
switch (msg.what)
{
case 0:
if(adVisible)
{
adView.setVisibility(View.GONE);
adVisible = false;
}
break;
case 1:
if (!adVisible)
{
adView.setVisibility(View.VISIBLE);
AlphaAnimation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setDuration(400);
animation.setFillAfter(true);
animation.setInterpolator(new AccelerateInterpolator());
adView.startAnimation(animation);
adVisible = true;
}
break;
default:
break;
}
}
};

public void EnableAds()
{
handler.sendEmptyMessage(1);
}

public void DisableAds()
{
handler.sendEmptyMessage(0);
}
private void setupAds()
{
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
addContentView(layout, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));

adView = new AdView(this);
layout.addView(adView, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));

adView.setBackgroundColor(0xff000000);
adView.setPrimaryTextColor(0xffffffff);
adView.setSecondaryTextColor(0xffcccccc);
adView.setKeywords("kickoff Goal Pinball game spiel bundesliga male Flipper Bumper Parlotones kick off 3d soccer fussball football tor vuvuzela");
//  adView.setRequestInterval(20);       //设置自动出现频率

// add listener for easier debugging
adView.setAdListener( new SimpleAdListener()
{
public void onFailedToReceiveAd(com.admob.android.ads.AdView adView)
{
Log.d("AdListener", "onFailedToReceiveAd: " + adView.toString());
super.onFailedToReceiveAd(adView);
}

public void onFailedToReceiveRefreshedAd(com.admob.android.ads.AdView adView)
{
Log.d("AdListener", "onFailedToReceiveRefreshedAd: " + adView.toString());
super.onFailedToReceiveRefreshedAd(adView);
}

public void onReceiveAd(com.admob.android.ads.AdView adView)
{
Log.d("AdListener", "onReceiveAd: " + adView.toString());
super.onReceiveAd(adView);
}

public void onReceiveRefreshedAd(com.admob.android.ads.AdView adView)
{
Log.d("AdListener", "onReceiveRefreshedAd: " + adView.toString());
super.onReceiveRefreshedAd(adView);
}
} );
adView.requestFreshAd();
}
}

和AndroidMainifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.LB.AdMob"
android:versionCode="1"
android:versionName="1.0">

<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".AdMob"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<!-- The application's publisher ID assigned by AdMob  //android:value中放入使用者ID -->
<meta-data android:value="a14ddb78fc3babe" android:name="ADMOB_PUBLISHER_ID" />

<!-- AdMobActivity definition -->
<activity android:name="com.admob.android.ads.AdMobActivity"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:configChanges="orientation|keyboard|keyboardHidden" />

<!-- Track Market installs -->
<receiver android:name="com.admob.android.ads.analytics.InstallReceiver" android:exported="true">
<intent-filter> <action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
</application>

<!-- AdMob SDK requires Internet permission -->
<uses-permission android:name="android.permission.INTERNET" />
</manifest>


        这是个典型的Android项目代码,有几点注意下,1.如果想用在自己的应用上,就照着羽化的引用结构自己新建一个工程,把这两个文件中所有的羽化自定义名称换掉即可。2. android:value中填入自己申请的AdMob ID。3.羽化把代码简化到最少,所以并没用使用res中的所有内容,若想自定义图标等就需要自己去修改AndroidManifests实现。4.这个可以加上阻止休眠命令,在羽化上一篇Android博客里面有提到。5.Unity中的Bundle
Identifier必须与这里定义的package一致。6.这时把Eclipse项目运行肯定报错。7.这里只写了广告淡出效果,没写淡入效果- - 大家凑合看吧。。。



            当上面的都没问题后就把AdMob.java打jar包,方法是选中AdMob鼠标右键 -> Export -> java -> JAR file -> Next



[align=left]
[/align]

    选择你的到处路径和名称JAR file,直接Finish,这样的jar包里面只包括编译后的AdMob.class,很小很干净。。。然后打开羽化的Unity工程AdMobTest(File- > Open Project),双击UnityAdMob这个Sence,可以看到只有一个相机。。。上面只有一个脚本Ad.cs。
Ad.cs

using UnityEngine;

using System.Collections;

using System;

public class Ad : MonoBehaviour

{

void OnGUI()

{

if(Input.GetKey(KeyCode.Escape))

{

Application.Quit();

}

if(GUI.Button(new Rect(0,Screen.height-220,100,100),"EnableAds!"))

{

EnableAds();

}

if(GUI.Button(new Rect(0,Screen.height-110,100,100),"DisableAds!"))

{

DisableAds();

}

if(GUI.Button(new Rect(Screen.width-120,Screen.height-40,120,30),"Click to YUHUA!"))

{

Application.OpenURL("http://blog.csdn.net/libeifs");

}

}

public void EnableAds()

{

#if UNITY_ANDROID

AndroidJNI.AttachCurrentThread();

// first we try to find our main activity..

IntPtr cls_Activity = AndroidJNI.FindClass("com/unity3d/player/UnityPlayer");

IntPtr fid_Activity = AndroidJNI.GetStaticFieldID(cls_Activity, "currentActivity", "Landroid/app/Activity;");

IntPtr obj_Activity = AndroidJNI.GetStaticObjectField(cls_Activity, fid_Activity);

//Debug.Log("obj_Activity = " + obj_Activity);

IntPtr cls_OurAppNameActivityClass = AndroidJNI.FindClass("com/LB/AdMob/AdMob"); //this has to be changed

IntPtr startAdsMethod = AndroidJNI.GetMethodID(cls_OurAppNameActivityClass, "EnableAds", "()V");

//Debug.Log("m_startAdsMethod = " + startAdsMethod);

if (AndroidJNI.IsInstanceOf(obj_Activity, cls_OurAppNameActivityClass) != false)

{

//Debug.Log("Activity IS a OurAppNameActivity");

jvalue[] myArray = new jvalue[1];

AndroidJNI.CallVoidMethod(obj_Activity, startAdsMethod,myArray);

}

#else

m_adShowing = true;

#endif //UNITY_ANDROID

}

public void DisableAds()

{

#if UNITY_ANDROID

AndroidJNI.AttachCurrentThread();

// first we try to find our main activity..

IntPtr cls_Activity = AndroidJNI.FindClass("com/unity3d/player/UnityPlayer");

IntPtr fid_Activity = AndroidJNI.GetStaticFieldID(cls_Activity, "currentActivity", "Landroid/app/Activity;");

IntPtr obj_Activity = AndroidJNI.GetStaticObjectField(cls_Activity, fid_Activity);

IntPtr cls_OurAppNameActivityClass = AndroidJNI.FindClass("com/LB/AdMob/AdMob"); //this has to be changed

IntPtr stopAdsMethod = AndroidJNI.GetMethodID(cls_OurAppNameActivityClass, "DisableAds", "()V");

if (AndroidJNI.IsInstanceOf(obj_Activity, cls_OurAppNameActivityClass) != false)

{

jvalue[] myArray = new jvalue[1];

AndroidJNI.CallVoidMethod(obj_Activity, stopAdsMethod,myArray);

}

#else //UNITY_ANDROID

m_adShowing = false;

#endif //UNITY_ANDROID

}

}




       看起很简单,确实也不难,首先建立Plugins -> Android -> bin | libs这个文件集,把Eclipse项目里面的AndroidManifest.xml放在Android目录下,把打包的UnityAdMob.jar放在bin下,把这个重写的AdMob SDK放在libs下,注意:把Bundle Identifier设置成和Eclipse项目包一样的名字,就算没有Ad.cs程序运行也会执行一次广告,这个C#类只是个广告开关,还有里面的两个AndroidJNI.FindClass("XXX")自行修改。。。

 

运行效果: (有空就帮羽化点下广告吧- -)



 

     这个应该能满足大部分广告显示方式,置于显示位置就麻烦大家自行修改了,谢谢大家支持~ ~

 

老样子,项目送上:

http://dl.dbank.com/c0ya3iynro

 

下集预告:

Thinking inShader(5)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息