• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps Building a frame by frame live wallpaper

kodiak211

Member
I'm trying to build a live wallpaper using frames. I can't find any good tutorials on how to even build a live wallpaper. When I run app from eclipse i get these errors.


[2012-05-19 22:26:32 - LiveWallpaper] No Launcher activity found!
[2012-05-19 22:26:32 - LiveWallpaper] The launch will only sync the application package on the device!

It does install to the emulator. It all seems to work. I go in to the live wallpaper menu, find my live wallpaper in there open it, it loads. but its not moving through the frames. It only shows the last frame. I set it as wallpaper. It also doesn't do anything. Also would like to center the images. Hears my code...

Java class--->


import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.service.wallpaper.WallpaperService;
import android.view.SurfaceHolder;

public class WallpaperSer extends WallpaperService {
public void onCreate()
{
super.onCreate();
}

public void onDestroy()
{
super.onDestroy();
}

public Engine onCreateEngine()
{
return new WallpaperSerEngine();
}

class WallpaperSerEngine extends Engine
{
public Bitmap image1, image2, image3, image4, image5, image6, image7, image8, image9,image10,
image11, image12, image13, image14, image15, image16, image17, image18, image19,image20;

WallpaperSerEngine()
{
image1 = BitmapFactory.decodeResource(getResources(), R.drawable.and1);
image2 = BitmapFactory.decodeResource(getResources(), R.drawable.and2);
image3 = BitmapFactory.decodeResource(getResources(), R.drawable.and3);
image4 = BitmapFactory.decodeResource(getResources(), R.drawable.and4);
image5 = BitmapFactory.decodeResource(getResources(), R.drawable.and5);
image6 = BitmapFactory.decodeResource(getResources(), R.drawable.and6);
image7 = BitmapFactory.decodeResource(getResources(), R.drawable.and7);
image8 = BitmapFactory.decodeResource(getResources(), R.drawable.and8);
image9 = BitmapFactory.decodeResource(getResources(), R.drawable.and9);
image10 = BitmapFactory.decodeResource(getResources(), R.drawable.and10);
image11 = BitmapFactory.decodeResource(getResources(), R.drawable.and11);
image12 = BitmapFactory.decodeResource(getResources(), R.drawable.and12);
image13 = BitmapFactory.decodeResource(getResources(), R.drawable.and13);
image14 = BitmapFactory.decodeResource(getResources(), R.drawable.and14);
image15 = BitmapFactory.decodeResource(getResources(), R.drawable.and15);
image16 = BitmapFactory.decodeResource(getResources(), R.drawable.and16);
image17 = BitmapFactory.decodeResource(getResources(), R.drawable.and17);
image18 = BitmapFactory.decodeResource(getResources(), R.drawable.and18);
image19 = BitmapFactory.decodeResource(getResources(), R.drawable.and19);
image20 = BitmapFactory.decodeResource(getResources(), R.drawable.and20);
}

public void onCreate(SurfaceHolder surfaceHolder)
{
super.onCreate(surfaceHolder);
}

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)
{
c.drawBitmap(image1, 0, 0, null);
c.drawBitmap(image2, 0, 0, null);
c.drawBitmap(image3, 0, 0, null);
c.drawBitmap(image4, 0, 0, null);
c.drawBitmap(image5, 0, 0, null);
c.drawBitmap(image6, 0, 0, null);
c.drawBitmap(image7, 0, 0, null);
c.drawBitmap(image8, 0, 0, null);
c.drawBitmap(image9, 0, 0, null);
c.drawBitmap(image10, 0, 0, null);
c.drawBitmap(image11, 0, 0, null);
c.drawBitmap(image12, 0, 0, null);
c.drawBitmap(image13, 0, 0, null);
c.drawBitmap(image14, 0, 0, null);
c.drawBitmap(image15, 0, 0, null);
c.drawBitmap(image16, 0, 0, null);
c.drawBitmap(image17, 0, 0, null);
c.drawBitmap(image18, 0, 0, null);
c.drawBitmap(image19, 0, 0, null);
c.drawBitmap(image20, 0, 0, null);
}
} finally
{
if (c != null) holder.unlockCanvasAndPost(c);
}
}
}
}


xml code--->


<?xml version="1.0" encoding="utf-8"?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
android:thumbnail="@drawable/ic_launcher"
android:description="@string/app_name"/>

manifest--->

<application android:label="demo Live Wallpaper"
android:icon="@drawable/ic_launcher">
<service android:label="demo Live Wallpaper"
android:name=".WallpaperSer"

android:permission="android.permission.BIND_WALLPAPER">
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
</intent-filter>
<meta-data android:name="android.service.wallpaper"

android:resource="@xml/wallpaper" />
</service>
</application>
<uses-sdk android:minSdkVersion="8" />

<uses-feature android:name="android.software.live_wallpaper" />
</manifest>
 
You are drawing all the bitmaps each time drawFrame() is called so the only one you see drawn is the last one (image20).

You need to increment a counter over a period of time and draw the bitmap relating to the value of the counter.

Try storing Bitmap objects in an array (so you don't need image1, image2 etc you can reference them by images[counter])

For example:
Code:
void drawFrame() {
              final SurfaceHolder holder = getSurfaceHolder();

  Canvas c = null;
  try 
  {
     c = holder.lockCanvas();
     if (c != null) {              
       frames ++;
       if(frames > 120){ //2 seconds, if drawFrame is called every refresh @ 60Hz
         count++;
         if(count > images.length) count = 0;
         c.drawBitmap(images[count], 0, 0, null);
         frames = 0;
       }
    }
    } finally {
       if (c != null) holder.unlockCanvasAndPost(c);
                }
          }
    }
And for centering the image, take a look at the other ways you can use drawBitmap.

edit:
Oh, drawFrame is fired by onOffsetChanged. You will need to use some sort of timing instead. (take a look at AsyncTask and Handler)
 
This Is a edit To my code. But not the solution.... When loaded to the emulator, the app shows "loading live wallpaper" but nothing loads...


import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.os.Handler;

import android.service.wallpaper.WallpaperService;

import android.view.SurfaceHolder;

public class WallpaperSer extends WallpaperService {
int incrementer=0;
Bitmap bmps[]=new Bitmap[10];

public void onCreate()
{
super.onCreate();
}

public void onDestroy()
{
super.onDestroy();
}

public Engine onCreateEngine()
{
return new WallpaperSerEngine();
}

class WallpaperSerEngine extends Engine
{

int res[]={R.drawable.and1,R.drawable.and2,R.drawable.and3,R.drawable.and4,R.drawable.and5,R.drawable.and6,R.drawable.and7,R.drawable.and8,R.drawable.and9,R.drawable.and10};
WallpaperSerEngine()
{
for(int i=0;i<=10;i++)
{
bmps= BitmapFactory.decodeResource(getResources(),res);
}
}
}

private final Handler handler = new Handler();
private final Runnable drawRunner = new Runnable() {
@Override
public void run() {

drawFrame();
handler.removeCallbacks(drawRunner);

handler.postDelayed(drawRunner, 200);
}

};
void drawFrame()
{
final SurfaceHolder holder = getSurfaceHolder();

Canvas c = null;
try
{
c = holder.lockCanvas();
if (c != null)
{

c.drawBitmap(bmps[incrementer], 0, 0, null);

incrementer=(incrementer==10)?0 : incrementer+1;
}
} finally
{
if (c != null) holder.unlockCanvasAndPost(c);
}
}

private SurfaceHolder getSurfaceHolder() {
// TODO Auto-generated method stub
return null;
}
}
 
You are drawing all the bitmaps each time drawFrame() is called so the only one you see drawn is the last one (image20).

You need to increment a counter over a period of time and draw the bitmap relating to the value of the counter.

Try storing Bitmap objects in an array (so you don't need image1, image2 etc you can reference them by images[counter])

For example:
Code:
void drawFrame() {
              final SurfaceHolder holder = getSurfaceHolder();

  Canvas c = null;
  try 
  {
     c = holder.lockCanvas();
     if (c != null) {              
       frames ++;
       if(frames > 120){ //2 seconds, if drawFrame is called every refresh @ 60Hz
         count++;
         if(count > images.length) count = 0;
         c.drawBitmap(images[count], 0, 0, null);
         frames = 0;
       }
    }
    } finally {
       if (c != null) holder.unlockCanvasAndPost(c);
                }
          }
    }
And for centering the image, take a look at the other ways you can use drawBitmap.

edit:
Oh, drawFrame is fired by onOffsetChanged. You will need to use some sort of timing instead. (take a look at AsyncTask and Handler)

:D
 
Back
Top Bottom