Well I have a question that is absolutely puzzling me. I have a live wallpaper https://play.google.com/store/apps/details?id=com.simpleworkerz.boise.sunsets#?t=W251bGwsMSwyLDIxMiwiY29tLnNpbXBsZXdvcmtlcnouYm9pc2Uuc3Vuc2V0cyJd
The app contains both a live wallpaper and a slide show. The slide show version works just fine with the samsung (both live wallpaper and slide show us the same opengl renderer, but when a user goes into live wallpapers and selects "SET WALLPAPER" the following occurs.
1)The set wallpaper text changes color. (although still remains like nothing was initiated) 2)The screen goes black again and the message "Loading wallpaper begins" 3) 3-4 seconds later nothing appears and a message saying Boise Sunsets has stopped working and needs to close. Or clicking "set wallpaper a second time will cause a force close.
Everything works fine before the user clicks "set wallpaper" so everything is rendering and displaying as it should.
So I am assuming my problem has to do with oncreate or onsurface changed. I dont quite understand what exactly is called when the button "Set wallpaper" is clicked. Anyone know?
Here is my code for the wallpaper.
import android.content.SharedPreferences;
import android.service.wallpaper.*;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGL11;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
import javax.microedition.khronos.opengles.GL10;
public class BoiseSunsetsLiveWallpaper extends WallpaperService{
@Override
public Engine onCreateEngine(){
return new MyEngine();
}
class MyEngine extends Engine
{
private float mTouchX = -1;
private float mTouchY = -1;
private GLRenderer glRenderer;
private GL10 gl;
private EGL10 egl;
private EGLContext glc;
private EGLDisplay glDisplay;
private EGLSurface glSurface;
private ExecutorService executor;
private Runnable drawCommand;
@Override
public void onCreate(final SurfaceHolder holder){
super.onCreate(holder);
executor = Executors.newSingleThreadExecutor();
drawCommand = new Runnable(){
public void run(){
glRenderer.onDrawFrame(gl);
egl.eglSwapBuffers(glDisplay, glSurface);
if(isVisible()
&& egl.eglGetError() != EGL11.EGL_CONTEXT_LOST
&& !executor.isShutdown()){
executor.execute(drawCommand);
}
}
};
}
@Override
public void onDestroy(){
executor.shutdown();
//setTouchEventsEnabled(false);
//glRenderer.onSurfaceDestroyed();
glRenderer = null;
super.onDestroy();
}
@Override
public void onSurfaceCreated(final SurfaceHolder holder){
super.onSurfaceCreated(holder);
Runnable surfaceCreatedCommand = new Runnable(){
public void run(){
//Initialize Open GL
egl = (EGL10) EGLContext.getEGL();
glDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
int[] version = new int[2];
egl.eglInitialize(glDisplay, version);
int[] configSpec = {
EGL10.EGL_RED_SIZE, EGL10.EGL_DONT_CARE,
EGL10.EGL_GREEN_SIZE, EGL10.EGL_DONT_CARE,
EGL10.EGL_BLUE_SIZE, EGL10.EGL_DONT_CARE,
EGL10.EGL_DEPTH_SIZE, EGL10.EGL_DONT_CARE,
EGL10.EGL_NONE };
EGLConfig[] configs = new EGLConfig[1];
int[] numConfig = new int[1];
egl.eglChooseConfig(glDisplay, configSpec, configs, 1, numConfig);
EGLConfig config = configs[0];
glc = egl.eglCreateContext(glDisplay, config, EGL10.EGL_NO_CONTEXT, null);
glSurface = egl.eglCreateWindowSurface(glDisplay, config, holder, null);
egl.eglMakeCurrent(glDisplay, glSurface, glSurface, glc);
gl = (GL10) (glc.getGL());
//Initialize Renderer
glRenderer = new GLRenderer(BoiseSunsetsLiveWallpaper.this);
glRenderer.onSurfaceCreated(gl, config);
}
};
executor.execute(surfaceCreatedCommand);
}
@Override
public void onSurfaceDestroyed(final SurfaceHolder holder){
Runnable surfaceDestroyedCommand = new Runnable() {
public void run(){
//Free OpenGL resources
egl.eglMakeCurrent(glDisplay, EGL10.EGL_NO_SURFACE,
EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
egl.eglDestroySurface(glDisplay, glSurface);
egl.eglDestroyContext(glDisplay, glc);
egl.eglTerminate(glDisplay);
}
};
executor.execute(surfaceDestroyedCommand);
super.onSurfaceDestroyed(holder);
}
@Override
public void onSurfaceChanged(final SurfaceHolder holder, final int format, final int width, final int height){
super.onSurfaceChanged(holder, format, width, height);
Runnable surfaceChangedCommand = new Runnable(){
public void run(){
glRenderer.onSurfaceChanged(gl, width, height);
}
};
executor.execute(surfaceChangedCommand);
}
@Override
public void onVisibilityChanged(final boolean visible){
super.onVisibilityChanged(visible);
if(visible){
executor.execute(drawCommand);
}
}
@Override
public void onOffsetsChanged(final float xOffset, final float yOffset, final float xOffsetStep, final float yOffsetStep,
final int xPixelOffset,final int yPixelOffset){
super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixelOffset, yPixelOffset);
Runnable offsetsChangedCommand = new Runnable(){
public void run(){
if (xOffsetStep != 0f){
glRenderer.setParallax(xOffset - 0.5f);
}
}
};
executor.execute(offsetsChangedCommand);
}
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
}
@Override
public void onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
mTouchX = event.getX();
mTouchY = event.getY();
} else {
mTouchX = -1;
mTouchY = -1;
}
Runnable TouchChangedCommand = new Runnable(){
public void run(){
if (mTouchX >=0 && mTouchY >= 0){
glRenderer.IsPressed(mTouchX, mTouchY);
}
else{
}
}
};
executor.execute(TouchChangedCommand);
super.onTouchEvent(event);
}
}
}
Strangely enough if I click set wallpaper really fast and exit the screen real fast sometimes the wallpaper will actually work! Or a few seconds later will close.
I dont actually own a samsung phone as I was testing this at both a Verizon and Sprint store. lol. So I cant give specific errors. Once I get a samsung test phone I will. Until then I appreciate any insight you can muster!
I am using part of Ed Burnette's code from Hello, Android for live wallpaper. I thought my problem was related to this issue. http://forums.pragprog.com/forums/152/topics/8254 but I made all those changes and am still getting the issue.
Update
/AndroidRuntime( 9520): FATAL EXCEPTION: pool-1-thread-1
E/AndroidRuntime( 9520): java.lang.NullPointerException
E/AndroidRuntime( 9520): at com.simpleworkerz.boise.sunsets.BoiseSunsetsLiveWallpaper$MyEngine$1.run(BoiseSunsetsLiveWallpaper.java:55)
E/AndroidRuntime( 9520): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
E/AndroidRuntime( 9520): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
E/AndroidRuntime( 9520): at java.lang.Thread.run(Thread.java:856)
D/KeyguardViewMediator( 651): setHidden false
D/KeyguardViewMediator( 651): setHidden false
I/WindowManager( 651): WIN DEATH: Window{423d0120 XXX.XXXXX.XXX.XXXXXXX/XXX.XXXXX.XXX.XXXXXXX.XXXXXXXX.XXXXXXXXXXXX paused=false}