• 周三. 4 月 22nd, 2026

物嫩软件资讯网

软件资讯来物嫩

动态壁纸和shortcut学习

admin@wunen

6 月 3, 2025

package org.crazyit.desktop;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.os.Handler;

import android.service.wallpaper.WallpaperService;

import android.view.MotionEvent;

import android.view.SurfaceHolder;


/**

为了开发动态壁纸,android使用了WallpaperService,子类必须实现它的onCreateEngine()方法

该服务必须包括一个引擎(WallpaperService.Engine)。该引擎是连接用户、桌面、系统之间的桥梁。

它也可以绘制桌面壁纸,并采用了与surfaceview相同的绘图机制。所以,需实现WallpaperService.Engine的子类,并重写onVisibilityChanged

onOffsetsChanged等方法。

*/

public class LiveWallpaper extends WallpaperService

{


// 实现WallpaperService必须实现的抽象方法

@Override

public Engine onCreateEngine()

{


// 返回自定义的Engine

return new MyEngine();

}

class MyEngine extends Engine

{


// 记录程序界面是否可见

private boolean mVisible;

// 记录当前当前用户动作事件的发生位置

private float mTouchX = -1;

private float mTouchY = -1;

// 记录当前圆圈的绘制位置

private float cx = 15;

private float cy = 20;

// 定义画笔

private Paint mPaint = new Paint();

// 定义一个Handler

Handler mHandler = new Handler();

// 定义一个周期性执行的任务

private final Runnable drawTarget = new Runnable()

{


public void run()

{


drawFrame();

}

};

@Override

public void onCreate(SurfaceHolder surfaceHolder)

{


super.onCreate(surfaceHolder);

// 初始化画笔

mPaint.setColor(0xffffffff);

mPaint.setAntiAlias(true);

mPaint.setStrokeWidth(2);

mPaint.setStrokeCap(Paint.Cap.ROUND);

mPaint.setStyle(Paint.Style.STROKE);

// 设置处理触摸事件

setTouchEventsEnabled(true);

}

@Override

public void onDestroy()

{


super.onDestroy();

// 删除回调

mHandler.removeCallbacks(drawTarget);

}

@Override

public void onVisibilityChanged(boolean visible)

{


mVisible = visible;

// 当界面可见时候,执行drawFrame()方法。

if (visible)

{


// 动态地绘制图形

drawFrame();

}

else

{


// 如果界面不可见,删除回调

mHandler.removeCallbacks(drawTarget);

}

}

@Override

public void onOffsetsChanged(float xOffset, float yOffset, float xStep,

float yStep, int xPixels, int yPixels)

{


drawFrame();

}

WallpaperService.Engine采用了与surfaceview相同的绘图机制,因此可以有选择性的重写下面3个方法

// // 当屏幕大小改变时候调用该方法

// @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(drawTarget);

// }

@Override

public void onTouchEvent(MotionEvent event)

{


// 如果检测到滑动操作

if (event.getAction() == MotionEvent.ACTION_MOVE)

{


mTouchX = event.getX();

mTouchY = event.getY();

}

else

{


mTouchX = -1;

mTouchY = -1;

}

super.onTouchEvent(event);

}

// 定义绘制图形的工具方法

private void drawFrame()

{


// 获取该壁纸的SurfaceHolder

final SurfaceHolder holder = getSurfaceHolder();

Canvas c = null;

try

{


// 对画布加锁

c = holder.lockCanvas();

if (c != null)

{


c.save();

// 绘制背景色

c.drawColor(0xff000000);

// 在触碰点绘制圆圈

drawTouchPoint(c);

// 绘制圆圈

c.drawCircle(cx, cy, 80, mPaint);

c.restore();

}

}

finally

{


if (c != null)

holder.unlockCanvasAndPost(c);

}

mHandler.removeCallbacks(drawTarget);

// 调度下一次重绘

if (mVisible)

{


cx += 15;

cy += 20;

// 如果cx、cy移出屏幕后从左上角重新开始

if (cx > 320)

cx = 15;

if (cy > 400)

cy = 20;

// 指定0.1秒后重新执行mDrawCube一次

mHandler.postDelayed(drawTarget, 100);

}

}

// 在屏幕触碰点绘制圆圈

private void drawTouchPoint(Canvas c)

{


if (mTouchX >= 0 && mTouchY >= 0)

{


c.drawCircle(mTouchX, mTouchY, 40, mPaint);

}

}

}

}

<!– 配置实时壁纸Service –>

<service android:label=”@string/app_name”

android:name=”.LiveWallpaper”

android:permission=”android.permission.BIND_WALLPAPER”>

<!– 为实时壁纸配置intent-filter –>

<intent-filter>

<action android:name=”android.service.wallpaper.WallpaperService” />

</intent-filter>

<!– 为实时壁纸配置meta-data –>

<meta-data android:name=”android.service.wallpaper”

android:resource=”@xml/livewallpaper” />

</service>

<?xml version=”1.0″ encoding=”utf-8″?>

<wallpaper xmlns:android=”

>

动态壁纸的原理和surfaceview原理差不多。

/**

快捷方式添加

*/

public class AddShortcut extends Activity

{


ImageView flower;

// 定义两份动画资源

Animation anim, reverse;

final Handler handler = new Handler()

{


@Override

public void handleMessage(Message msg)

{


if (msg.what == 0x123)

{


flower.startAnimation(reverse);

}

}

};

@Override

public void onCreate(Bundle savedInstanceState)

{


super.onCreate(savedInstanceState);

setContentView(R.layout.main);

flower = (ImageView) findViewById(R.id.flower);

// 加载第一份动画资源

//补间动画 Teen Animation

Android中实现补间动画的思路是这样的,

1、首先用XML定义一个动画效果

2、依据这个XML使用AnimationUtils工具类创建一个Animationd对象

3、调用View组件的startAnimation方法实现动画。使用动画的对象是一个view,这里是imageview

anim = AnimationUtils.loadAnimation(this, R.anim.anim);

// 设置动画结束后保留结束状态

anim.setFillAfter(true);

// 加载第二份动画资源

reverse = AnimationUtils.loadAnimation(this, R.anim.reverse);

// 设置动画结束后保留结束状态

reverse.setFillAfter(true);

Button bn = (Button) findViewById(R.id.bn);

// 下面的代码是点击了按钮即为本应用创建一个shortcut 快捷方式

bn.setOnClickListener(new OnClickListener()

{


@Override

public void onClick(View source)

{


// 创建添加快捷方式的Intent

Intent addIntent = new Intent(

“com.android.launcher.action.INSTALL_SHORTCUT”);

String title = getResources().getString(R.string.title);

// 加载快捷方式的图标

Parcelable icon = Intent.ShortcutIconResource.fromContext(

AddShortcut.this, R.drawable.icon);

// 创建点击快捷方式后操作Intent,该处当点击创建的快捷方式后,再次启动该程序

Intent myIntent = new Intent(AddShortcut.this,

AddShortcut.class);

// 设置快捷方式的标题

addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, title);

// 设置快捷方式的图标

addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);

// 设置快捷方式对应的Intent

addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, myIntent);

// 发送广播添加快捷方式

sendBroadcast(addIntent);

}

});

}

@Override

public void onResume()

{


super.onResume();

// 开始执行动画

flower.startAnimation(anim);

// 设置3.5秒后启动第二个动画

new Timer().schedule(new TimerTask()

{


@Override

public void run()

{


handler.sendEmptyMessage(0x123);

}

}, 3500);

}

}

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注