【www.bbyears.com--php基础】
自从Android 2.1中加入了动态壁纸,一下子牛叉了很多啊,漂亮的壁纸层出不穷,看上去老土的Android手机总算也是可以炫一下了。
动态壁纸基础
制作方法,网上太多了,虽然基本都是抄的,其实都是从sample上发展出来的,我也把要点记一下,每次写新的都要把老的工程打开看,啥记性……
res/xml中指定动态壁纸的xml文件:
android:thumbnail="@drawable/icon" />
这里是说明自己图标和设定Activity。
还有一个设定Activity的xml文件,就是普通的PreferenceScreen,省略。
创建WallpaperService的子类,需要再onCreateEngine方法中返回一个Engine,Engine中画画儿,就像用SurfaceView一样。
public class LiveWallpaper extends WallpaperService {
public static final String SHARED_PREFS_NAME = "setting_file_name";
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public Engine onCreateEngine() {
return new TestPatternEngine();
}
class TestPatternEngine extends Engine implements
SharedPreferences.OnSharedPreferenceChangeListener {
private final Handler mHandler = new Handler();
private final Runnable mDrawPattern = new Runnable() {
public void run() {
drawFrame();
}
};
private boolean mVisible;
private SharedPreferences mPreferences;
TestPatternEngine() {
mPreferences = LiveWallpaper.this.getSharedPreferences(
SHARED_PREFS_NAME, 0);
mPreferences.registerOnSharedPreferenceChangeListener(this);
onSharedPreferenceChanged(mPreferences, null);
}
public void onSharedPreferenceChanged(SharedPreferences prefs,
String key) {
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
}
@Override
public void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mDrawPattern);
}
@Override
public void onVisibilityChanged(boolean visible) {
mVisible = visible;
if (visible) {
drawFrame();
} else {
mHandler.removeCallbacks(mDrawPattern);
}
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
drawFrame();
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
mVisible = false;
mHandler.removeCallbacks(mDrawPattern);
}
@Override
public void onOffsetsChanged(float xOffset, float yOffset, float xStep,
float yStep, int xPixels, int yPixels) {
drawFrame();
}
void drawFrame() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
// draw something
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
mHandler.removeCallbacks(mDrawPattern);
if (mVisible) {
mHandler.postDelayed(mDrawPattern, 1000 / 25);
}
}
}
}
还有设定Activity的实现:
public class LiveWallpaperSettings extends PreferenceActivity
implements SharedPreferences.OnSharedPreferenceChangeListener {
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
getPreferenceManager().setSharedPreferencesName(LiveWallpaper.SHARED_PREFS_NAME);
addPreferencesFromResource(R.xml.livewallpaper_settings);
getPreferenceManager().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onDestroy() {
getPreferenceManager().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
super.onDestroy();
}
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
}
}
androidmanifest.xml中一定要加入的:
android:name=".LiveWallpaperSettings"
android:theme="@android:style/Theme.Light.WallpaperSettings"
android:exported="true"
android:icon="@drawable/icon">
“uses-feature android:name=”android.software.live_wallpaper””这句话要慎用啊!Google的电子市场会认这句话,然后把有些可以用的机器过滤掉,比如俺的破机器,本来是不支持的,升级到2.1按说是可以用的。我看了市场上很多有名的动态壁纸,就没有加这句话~~
另外,如果想在动态壁纸中使用OpenGL ES,请参考这篇文章:Android中使用OpenGL ES的一二事。
加入AdMob广告
上面都是废话,我这次想说的主题是如何在壁纸设定界面里加入AdMob广告,好不容易做好的东西,总是要意思意思是吧,加个广告是没法的事情了。
不同于一般的Activity,直接加入AdMob是不行的,连个Layout都没有,而且直接加到壁纸上则非常糟糕,谁也不希望好好的背景上塞一个广告。所以一般动态壁纸的广告都加在设置界面里,这样还真有些不容易。
一般有两种方法,把Admob的adView当做一个Preference,直接加入xml就好。
public class AdmobPreference extends Preference {
public AdmobPreference(Context context) {
super(context, null);
}
public AdmobPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected View onCreateView(ViewGroup parent) {
//override here to return the admob ad instead of a regular preference display
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return inflater.inflate(R.layout.admob_preference, null);
}
}
相对的admob_preference的配置:
android:layout_width="fill_parent" android:layout_height="fill_parent">
android:id="@+id/ad"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
ads.adSize="BANNER"
ads:adUnitId="a14e51ca560d266"
ads:loadAdOnCreate="true"
/>
Android AdView missing required XML attribute "adsize"
这里还是有些学问的,网上查一下会有无数的“AdView missing required XML attribute ‘adSize’”的问题,据说是4.1.0之后带来的问题,一定要这么写(将”http://schemas.android.com/apk/lib/com.google.ads”当做一个命名空间,而不是加入自己的程序中)才能不出错,至少大家是如此说的,可惜我不行,怎么写都有这个错,耗费了两个小时尝试了各种写法,还是不行啊!!最后还是写在代码里了:(
不过光这么写貌似还是不行,AdView周围还有留白,貌似是PreferenceActivity里的padding,去不掉,最后还是使用了Tab的方式:
public class SettingsTabActivity extends TabActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.table_layout);
TabHost tabHost = getTabHost(); // The activity TabHost
TabHost.TabSpec spec; // Resusable TabSpec for each tab
Intent intent; // Reusable Intent for each tab
// Create an Intent for the regular live wallpaper preferences activity
intent = new Intent().setClass(this, LivePaperSettings.class);
// Initialize a TabSpec and set the intent
spec = tabHost.newTabSpec("TabTitle").setContent(intent);
spec.setIndicator("TabTitle");
tabHost.addTab(spec);
tabHost.setCurrentTab(0);
}
对应的layout:
android:id="@android:id/tabhost" android:layout_width="fill_parent"
android:layout_height="fill_parent">
android:layout_width="fill_parent" android:layout_height="fill_parent">
android:layout_height="wrap_content"
ads:backgroundColor="#000000"
ads:primaryTextColor="#FFFFFF"
ads:secondaryTextColor="#CCCCCC"
ads.adSize="BANNER"
ads:adUnitId="a14e51ca560d266"
ads:loadAdOnCreate="true" />
android:visibility="invisible" />
<frameLayout android:id="@android:id/tabcontent"
android:padding="1dp" />
大概就是如此了。
对了还有一个浪费了我两个多小时的问题,对于已经按照的live wallpaper,你修改了setting的Activity,直接覆盖安装是没效果的,点配置还是出现以前的Activity,发现这一点之前,我做了不知几百次修改上传,都快整挂了,Google怎么考虑的?!