I am trying to draw a background image in my android app. However when I try to draw it as a bitmap it says the file is not found. Can you use images from custom folders created in your project directory?
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MainGamePanel extends SurfaceView implements SurfaceHolder.Callback {
Bitmap BackgroundImage;
private static final String TAG = MainGamePanel.class.getSimpleName();
private MainThread thread;
public MainGamePanel(Context context) {
super(context);
// adding the callback (this) to the surface holder to intercept events
getHolder().addCallback(this);
// creating game thread
thread = new MainThread(getHolder(), this);
// make the GmaePanel focusable so it can handle events
setFocusable(true);
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
thread.setRunning(true);
thread.start();
Background b1 = new Background();
BackgroundImage = b1.loadBackgroundImage();
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
Log.d(TAG, "Surface is being destroyed");
boolean retry = true;
while(retry){
try{
thread.join();
retry = false;
} catch (InterruptedException e) {
// try again to shutdown thread
}
}
Log.d(TAG, "Thread was shut down cleanly");
}
#Override
public boolean onTouchEvent(MotionEvent event){
return super.onTouchEvent(event);
}
#Override
protected void onDraw(Canvas canvas){
canvas.drawBitmap(BackgroundImage, 0, 0, null);
}
}
------Background Class------
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class Background {
private String imageLoc;
public Background(){
}
public String getImageLoc() {
return imageLoc;
}
public void setImageLoc(String imageLoc) {
this.imageLoc = imageLoc;
}
public Bitmap loadBackgroundImage(){
Bitmap background = BitmapFactory.decodeFile("/Users/Justin/Documents/Project_WinterGalaxy/AndroidGalaxy/images/Background.png");
return background;
}
}
The way to show an image in your code is: put it in the relevant drawable folder and then load it like this:
Bitmap background = BitmapFactory.decodeResource(getResources(), R.drawable.Background);
Related
Please, can anybody help me with this?
I have a project using CameraBridgeViewBase and I want to take a picture and save a file, but CameraBridgeViewBase doesn't implement the function takePicture.
Result: I implemented a new class extends JavaCameraView and implemented myself the function takePicture.
import org.opencv.android.JavaCameraView;
import java.io.FileOutputStream;
import java.util.List;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.Size;
import android.util.AttributeSet;
import android.util.Log;
public class MyCameraView extends JavaCameraView implements PictureCallback {
private static final String TAG = "myCameraView";
private String mPictureFileName;
public MyCameraView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public List<String> getEffectList() {
return mCamera.getParameters().getSupportedColorEffects();
}
public boolean isEffectSupported() {
return (mCamera.getParameters().getColorEffect() != null);
}
public String getEffect() {
return mCamera.getParameters().getColorEffect();
}
public void setEffect(String effect) {
Camera.Parameters params = mCamera.getParameters();
params.setColorEffect(effect);
mCamera.setParameters(params);
}
public List<Size> getResolutionList() {
return mCamera.getParameters().getSupportedPreviewSizes();
}
public void setResolution(Size resolution) {
disconnectCamera();
mMaxHeight = resolution.height;
mMaxWidth = resolution.width;
connectCamera(getWidth(), getHeight());
}
public Size getResolution() {
return mCamera.getParameters().getPreviewSize();
}
public void takePicture(final String fileName) {
Log.i(TAG, "Taking picture");
this.mPictureFileName = fileName;
// Postview and jpeg are sent in the same buffers if the queue is not empty when performing a capture.
// Clear up buffers to avoid mCamera.takePicture to be stuck because of a memory issue
mCamera.setPreviewCallback(null);
// PictureCallback is implemented by the current class
mCamera.takePicture(null, null, this);
}
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.i(TAG, "Saving a bitmap to file");
// The camera preview was automatically stopped. Start it again.
mCamera.startPreview();
mCamera.setPreviewCallback(this);
// Write the image in a file (in jpeg format)
try {
FileOutputStream fos = new FileOutputStream(mPictureFileName);
fos.write(data);
fos.close();
} catch (java.io.IOException e) {
Log.e("PictureDemo", "Exception in photoCallback", e);
}
}
}
-
private MyCameraView mOpenCvCameraView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mOpenCvCameraView = (MyCameraView) view.findViewById(R.id.fd_activity_surface_view);
mOpenCvCameraView.setCvCameraViewListener(this);
return view;
}
#Override
public void onResume() {
super.onResume();
mOpenCvCameraView.enableView();
String filename = "teste.jpg";
mOpenCvCameraView.takePicture(filename);
mOpenCvCameraView.disableView();
}
The problem is that when I'm in the game, and click the Home button, the gameLoop thread (I guess) gets messed up and then it pops up "Unfortunately, 'app name' has stopped."
I've made a very simple program where this problem occurs. All this program does is showing a number on the screen, and increasing it when you touch the screen.
When I comment out view.onDraw(c) in GameLoopThread, everything seems to run nicely.
Error message:
FATAL EXEPTION: Thread-23207
java.lang.NullPointerExeption
at com.example.crashtest.GameView.onDraw(GameView.java:61)
at com.example.crashtest.GameLoopThread.run(GameLoopThread.java:34)
Here's the code:
MainActivity.java
package com.example.crashtest;
import android.os.Bundle;
import android.app.Activity;
import android.content.res.Configuration;
import android.view.KeyEvent;
import android.view.Window;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new GameView(this));
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
return true;
case KeyEvent.KEYCODE_MENU:
return true;
case KeyEvent.KEYCODE_VOLUME_UP:
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
return true;
default:
return false;
}
}
}
GameView.java
package com.example.crashtest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class GameView extends SurfaceView {
private SurfaceHolder holder;
private GameLoopThread gameLoopThread;
private int num = 0;
public GameView(final Context context) {
super(context);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
gameLoopThread.setRunning(false);
while (retry) {
try {
gameLoopThread.join();
retry = false;
} catch (InterruptedException e) {}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
makeThread();
gameLoopThread.start();
gameLoopThread.setRunning(true);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
});
}
private void makeThread() {
gameLoopThread = new GameLoopThread(this);
}
#SuppressLint({ "WrongCall", "DrawAllocation" })
#Override
protected void onDraw(Canvas canvas) {
// Draw black background - Write variable 'num' on the screen
canvas.drawColor(Color.BLACK);
Paint paint = new Paint();
paint.setARGB(255, 0, 255, 0);
paint.setTextSize(50);
paint.setTextAlign(Align.CENTER);
canvas.drawText(Integer.toString(num), getWidth() / 2, getHeight() / 2, paint);
}
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
// Increase 'num' with 1 every touch
num++;
}
return super.onTouchEvent(event);
}
}
GameLoopThread.java
package com.example.crashtest;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
public class GameLoopThread extends Thread {
static final long FPS = 10;
private GameView view;
public boolean running = false;
public boolean pause = false;
public GameLoopThread(GameView view) {
this.view = view;
}
public void setRunning(boolean run) {
running = run;
}
#SuppressLint("WrongCall")
#Override
public void run() {
long ticksPS = 1000 / FPS;
long startTime = 0;
long sleepTime = 0;
while (running) {
Canvas c = null;
startTime = System.currentTimeMillis();
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
view.onDraw(c);
}
} finally {
if (c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
sleepTime = ticksPS-(System.currentTimeMillis() - startTime);
try {
if (sleepTime > 0)
sleep(sleepTime);
else
sleep(10);
} catch (Exception e) {}
}
}
}
Look what you need when you close the Activity you need to stop your thread from my code implemented before see it :
GameView gameView ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
gameView = new GameView(this);
setContentView(gameView);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
gameView.StopView();
}
and you need to implement method called StopView() in your GameView like this
public void StopView() {
if (gameLoopThread != null) {
gameLoopThread.setRunning(false);
}
}
the problem because you still call the run method in thread after you try to block the thread and so you need to stop it before to block it using join.
i tested your code with new implementation and it work well with me , feed me back
I'm having trouble implementing this color picker into my live wallpaper. It works just fine out of the box by itself (I can add it to my preferences menu, open up the widget and select a color), however I want to use that selected color to detail an EditText field that the user will see on the homescreen canvas. I can easily achieve this by changing ColorDialogPreference.java's int color to a static variable and calling it from the WallpaperService class directly:
int mColor = com.my.app.ColorDialogPreference.color;
But since it's static, the color gets reset once the process gets destroyed.
I've tried saving the variable via a SharedPreferences Editor inside my PreferencesActivity.java (see below), but can't seem to retrieve that variable in the WallpaperService class.
PreferencesActivity.java:
package com.my.app;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
public class MyPreferencesActivity extends PreferenceActivity
implements SharedPreferences.OnSharedPreferenceChangeListener {
#SuppressWarnings("deprecation")
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences preferences =
getSharedPreferences("prefs", MODE_WORLD_WRITEABLE);
getPreferenceManager().setSharedPreferencesName("preferenceKeyName");
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("preferenceKeyName", Color.GRAY);
editor.commit();
getPreferenceManager().setSharedPreferencesName("text_to_display");
getPreferenceManager().getSharedPreferences().
registerOnSharedPreferenceChangeListener(this);
addPreferencesFromResource(R.xml.prefs);
}
#SuppressWarnings("deprecation")
protected void onDestroy() {
getPreferenceManager().getSharedPreferences().
unregisterOnSharedPreferenceChangeListener(this);
super.onDestroy();
}
#SuppressWarnings("deprecation")
protected void onResume() {
super.onResume();
getPreferenceManager().getSharedPreferences().
registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
getPreferenceManager().getSharedPreferences().
registerOnSharedPreferenceChangeListener(this);
}
}
WallpaperService.java:
package com.my.app;
import java.util.List;
import java.util.Random;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.service.wallpaper.WallpaperService;
import android.view.SurfaceHolder;
public class MyWallpaperService extends WallpaperService {
public MyWallpaperService() {
super();
}
#Override
public Engine onCreateEngine() {
return new MyWallpaperEngine();
}
public class MyWallpaperEngine extends Engine
implements OnSharedPreferenceChangeListener {
Context ctx = getApplicationContext();
SharedPreferences sharedPreferences2 =
getSharedPreferences("prefs", MODE_WORLD_READABLE);
private int mColor = sharedPreferences2.getInt("preferenceKeyName",
Color.RED);
private boolean mVisible = false;
Paint p = new Paint();
float x1 = 0;
float y1 = 60;
private final Handler mHandler = new Handler();
private final Runnable mUpdateDisplay = new Runnable() {
#Override
public void run() {
draw();
}};
private void draw() {
SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
String text = "1. " + mText;
c.drawRect(0, 0, c.getWidth(), c.getHeight(), p);
p.setColor(mColor);
c.drawText(text, x, y, p);
}
}
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
mHandler.removeCallbacks(mUpdateDisplay);
if (mVisible) {
mHandler.postDelayed(mUpdateDisplay, 16);
}
}
private final Handler handler = new Handler();
private final Runnable drawRunner = new Runnable() {
#Override
public void run() {
draw();
}
};
#Override
public void onVisibilityChanged(boolean visible) {
super.onVisibilityChanged(visible);
mVisible = visible;
if (visible) {
mText = sharedPreferences.getString("text_to_display",
"default");
draw();
} else {
mHandler.removeCallbacks(mUpdateDisplay);
}
}
#Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
mVisible = false;
handler.removeCallbacks(drawRunner);
mHandler.removeCallbacks(mUpdateDisplay);
}
#Override
public void onDestroy() {
super.onDestroy();
mVisible = false;
mHandler.removeCallbacks(mUpdateDisplay);
}
#Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
draw();
}
}
#Override
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
// TODO Auto-generated method stub
}
}
}
And my prefs.xml:
`<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceScreen android:title="Set Text" android:summary="Some summary" >
<EditTextPreference android:key="text_to_display" android:title="Some text" />
</PreferenceScreen>
<PreferenceScreen android:title="Colors" android:summary="Any color you want!" >
<com.my.app.ColorPickerPreference
android:defaultValue="0xffffffff"
android:key="preferenceKeyName"
android:title="#string/pref_name"
android:summary="#string/pref_summary" />
</PreferenceScreen>
</PreferenceScreen>`
If I display the value of int color on the canvas, all that ever comes up is "-65535". I know that PreferencesActivity works to some degree, because retrieving "text_to_display", which is an EditText value, works just fine. Something else that is worth noting: if the process gets killed at all (reboot phone or FC), the color that I selected in the widget stays that color if I go back to the widget after having the process killed, so it seems to be saving inside ColorDialogPreference.java, but nowhere else?
Please consider using this color picker: github.com/chiralcode/Android-Color-Picker. It can be used as a preference on PreferenceScreen. Value will be stored in shared preferences with the key you provided.
You should also consider cleaning up your code. My proposition is to change MyPreferencesActivity into this:
public class MyPreferencesActivity extends PreferenceActivity {
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getPreferenceManager().setSharedPreferencesName("sharedPreferencesFilename");
addPreferencesFromResource(R.xml.prefs);
}
}
This is all the code you need. It looks like that you do not fully understand how shared preferences works.
Your code doesn't work, because you are writing preferences to files such as "preferenceKeyName" and "text_to_display", but you are reading them from "prefs".
I'm making a drawing app, and randomly when I press down, the app crashes. I can't figure out how to fix it, and have no Idea where to start. I don't know whether it is the List or the timing, or something else. Here's my code:
package com.orangewhales.paint.views;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
public class PaintView extends SurfaceView implements Callback {
boolean run = true;
Thread tUpdate;
public List<PaintPath> paths = new ArrayList<PaintPath>();
public Paint stroke = new Paint();
#Override
public void draw(Canvas canvas) {
// TODO Auto-generated method stub
super.draw(canvas);
canvas.drawRGB(255, 255, 255);
for (PaintPath path : paths) {
canvas.drawPath(path.path, path.paint);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
Path current = new Path();
current.moveTo(event.getX(), event.getY());
paths.add(new PaintPath(current, stroke));
break;
case MotionEvent.ACTION_MOVE:
PaintPath path = paths.get(paths.size() - 1);
path.path.lineTo(event.getX(), event.getY());
break;
}
return true;
}
public PaintView(Context context, AttributeSet attrs) {
super(context, attrs);
stroke.setStyle(Style.STROKE);
stroke.setColor(Color.BLACK);
stroke.setStrokeWidth(10);
tUpdate = new Thread() {
public void run() {
while (run) {
Canvas c = getHolder().lockCanvas();
draw(c);
getHolder().unlockCanvasAndPost(c);
update();
try {
sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
getHolder().addCallback(this);
}
public void update() {
// TODO Auto-generated method stub
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
tUpdate.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
run = false;
try {
tUpdate.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I have not touched my Android SDK in a while. So I’ll start with a question.
You said the app crashes at random times when the GUI is pressed down. At function onTouchEvent, which action occurs first, ACTION_DOWN or ACTION_MOVE?
I hope it’s well defined but we can not assume that.
I find code in the function “PaintPath path = paths.get(paths.size() - 1)” to be suspicious because paths.size can be 0, in the beginning anyway.
I think it’s a good idea to monitor the function onTouchEvent closely, can use debugger. Log messages if you have nothing else.
Fixing random intermittent issues is part of the job. Learn from it and have fun.
I already asked this, but it was migrated to android.stackexchange.com and closed there as offtopic.
So here we go again:
I made a simple live wallpaper. On the preview I can see it but if I try to set it as my live wallpaper Android keeps the old wallpaper there.
Any ideas?
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.localfotos"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" />
<uses-feature android:name="android.software.live_wallpaper" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<service android:name=".MyWallpaperService"
android:label="#string/app_name"
android:icon="#drawable/icon">
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
</intent-filter>
<meta-data android:name="android.service.wallpaper"
android:resource="#xml/livewallpaper" />
</service>
</application>
</manifest>
livewallpaper.xml
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
/>
MyWallpaperService.java
package com.localfotos;
import android.service.wallpaper.WallpaperService;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
public class MyWallpaperService extends WallpaperService {
#Override
public Engine onCreateEngine() {
return new MyEngine();
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
}
public class MyEngine extends Engine {
private MyWallpaperPainting painting;
MyEngine() {
SurfaceHolder holder = getSurfaceHolder();
painting = new MyWallpaperPainting(holder,
getApplicationContext());
}
#Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
// register listeners and callbacks here
setTouchEventsEnabled(true);
}
#Override
public void onDestroy() {
super.onDestroy();
// remove listeners and callbacks here
painting.stopPainting();
}
#Override
public void onVisibilityChanged(boolean visible) {
if (visible) {
// register listeners and callbacks here
painting.resumePainting();
} else {
// remove listeners and callbacks here
painting.pausePainting();
}
}
#Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
painting.setSurfaceSize(width, height);
}
#Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
// start painting
painting.start();
}
#Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
boolean retry = true;
painting.stopPainting();
while (retry) {
try {
painting.join();
retry = false;
} catch (InterruptedException e) {}
}
}
#Override
public void onOffsetsChanged(float xOffset, float yOffset,
float xStep, float yStep, int xPixels, int yPixels) {
}
#Override
public void onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
painting.doTouchEvent(event);
}
}
}
MyWallpaperPainting.java
package com.localfotos;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
public class MyWallpaperPainting extends Thread {
private static final String TAG = "MyWallpaperPainting";
/** Reference to the View and the context */
private SurfaceHolder surfaceHolder;
private Context context;
/** State */
private boolean wait;
private boolean run;
/** Dimensions */
private int width;
private int height;
/** Time tracking */
private long previousTime;
private long currentTime;
public MyWallpaperPainting(SurfaceHolder surfaceHolder, Context context) {
// keep a reference of the context and the surface
// the context is needed if you want to inflate
// some resources from your livewallpaper .apk
this.surfaceHolder = surfaceHolder;
this.context = context;
// don't animate until surface is created and displayed
this.wait = true;
}
/**
* Pauses the live wallpaper animation
*/
public void pausePainting() {
this.wait = true;
synchronized(this) {
this.notify();
}
}
/**
* Resume the live wallpaper animation
*/
public void resumePainting() {
this.wait = false;
synchronized(this) {
this.notify();
}
}
/**
* Stop the live wallpaper animation
*/
public void stopPainting() {
this.run = false;
synchronized(this) {
this.notify();
}
}
#Override
public void run() {
this.run = true;
Canvas c = null;
while (run) {
try {
c = this.surfaceHolder.lockCanvas(null);
synchronized (this.surfaceHolder) {
currentTime = System.currentTimeMillis();
updatePhysics();
doDraw(c);
previousTime = currentTime;
}
} finally {
if (c != null) {
this.surfaceHolder.unlockCanvasAndPost(c);
}
}
// pause if no need to animate
synchronized (this) {
if (wait) {
try {
wait();
} catch (Exception e) {}
}
}
synchronized (this){
try{
wait(1000);
}catch (InterruptedException e){}
}
}
}
/**
* Invoke when the surface dimension change
*/
public void setSurfaceSize(int width, int height) {
this.width = width;
this.height = height;
synchronized(this) {
this.notify();
}
}
/**
* Invoke while the screen is touched
*/
public void doTouchEvent(MotionEvent event) {
// handle the event here
// if there is something to animate
// then wake up
this.wait = false;
synchronized(this) {
notify();
}
}
/**
* Do the actual drawing stuff
*/
private void doDraw(Canvas canvas) {
/**
* Update the animation, sprites or whatever.
* If there is nothing to animate set the wait
* attribute of the thread to true
*/
Paint mPaint = new Paint();
mPaint.setDither(true);
mPaint.setColor(0xFFFFFF00);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(3);
Path path = new Path();
path.lineTo(10, 100);
canvas.drawColor(0xFFFFFF00);
Log.d(TAG, "doDraw");
}
private void updatePhysics() {
// if nothing was updated :
// this.wait = true;
}
}
Your manifest is missing the BIND_WALLPAPER permission. See the Cube example in the SDK.
android:permission="android.permission.BIND_WALLPAPER">