android - 设置动态壁纸时出错

标签 android live-wallpaper

我正在尝试创建动态壁纸。当我在 Activity 中使用相同的代码时,我会产生所需的结果。但如果我使用相同的代码创建动态壁纸,我总是会出现黑屏。请帮忙。

主要文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.wavingflaglwp"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="17" />

<uses-feature
    android:name="android.software.live_wallpaper"
    android:required="true" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <service
        android:name="com.example.wavingflaglwp.FlagWallpaperService"
        android:enabled="true"
        android:label="Wallpaper Example "
        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>

    <activity
        android:name="com.example.wavingflaglwp.WavingFlag"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

FlagWallpaperRenderer.java

public class FlagWallpaperRenderer implements Renderer {

FlagWallpaper flagWall;
private int surfaceWidth;
private int surfaceHeight;

public FlagWallpaperRenderer(Bitmap bitmap) {
    Log.d("TAG", "Flag Wall Renderer");
    flagWall = new FlagWallpaper(bitmap);
}

@Override
public void onDrawFrame(GL10 gl) {
    flagWall.drawFrame(gl, surfaceWidth, surfaceHeight);
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    flagWall.initialize(gl, width, height);
    this.surfaceWidth = width;
    this.surfaceHeight = height;
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    flagWall.onCreate(gl);
}

}

FlagWallpaper.java

public class FlagWallpaper {

private static final boolean IS_WIREFRAME_VISIBLE = false;

private static final boolean ISPRINTFPS = true;

private static final int m = 45;

private static final int n = 45;

private static final float hPercent = 0.66f;

private static final float wPercent = 1.0f;

float[][][] points = new float[m][n][3];
int wiggle_count = 0;
float xrot;
float yrot;
float zrot;
float hold;
int[] textures = new int[1];

FloatBuffer mVerticesBuffer;
FloatBuffer mTextureBuffer;

int trianglesInARow = (m - 1) * 2;
int verticesOfTrianglesInARow = (trianglesInARow - 1) + 3;

float mVertices[] = new float[(((n - 1) * verticesOfTrianglesInARow) + (n - 2) * 2) * 3];
float mTextures[] = new float[(((n - 1) * verticesOfTrianglesInARow) + (n - 2) * 2) * 2];

long time, frameTime, fpsTime;
short avgFPS, framerate;

Bitmap mBitmap;

public FlagWallpaper(Bitmap bitmap) {
    mBitmap = bitmap;
    ByteBuffer vbb = ByteBuffer.allocateDirect(mVertices.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    mVerticesBuffer = vbb.asFloatBuffer();

    ByteBuffer byteBuf = ByteBuffer.allocateDirect(mTextures.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    mTextureBuffer = byteBuf.asFloatBuffer();
}

public void drawFrame(GL10 gl, int surfaceWidth, int surfaceHeight) {
    int x, y;

    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

    gl.glLoadIdentity();
    gl.glClearColor(0f, 0f, 0f, 0f);

    gl.glTranslatef(0.0f, 0.0f, -12.0f);

    gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);
    gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);
    gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f);

    if (IS_WIREFRAME_VISIBLE) {
        gl.glColor4f(1f, 1f, 1f, 1f);
        gl.glDisable(GL10.GL_TEXTURE_2D);
    }

    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, mVertices.length / 3);

    if (IS_WIREFRAME_VISIBLE) {
        gl.glEnable(GL10.GL_BLEND);
        gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
        gl.glLineWidth(1.0f);
        gl.glColor4f(1f, 0f, 0f, 1.0f);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVerticesBuffer);
        gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, mVertices.length / 3);
        gl.glDisable(GL10.GL_BLEND);
        gl.glColor4f(1f, 1f, 1f, 1f);
        gl.glDisable(GL10.GL_TEXTURE_2D);
    }

    if (wiggle_count == 2) {
        for (y = 0; y < n; y++) {
            hold = points[0][y][2];
            for (x = 0; x < m - 1; x++) {
                points[x][y][2] = points[x + 1][y][2];
            }
            points[m - 1][y][2] = hold;
        }
        wiggle_count = 0;
        populateVertexBuffer(gl);
    }

    wiggle_count++;

    xrot += 0.3f;
    yrot += 0.2f;
    zrot += 0.4f;

    printFPS();
}

public void onCreate(GL10 gl) {
    try {
        loadGLTextures(gl);
    } catch (IOException e) {
        System.out.println("Failed to load Textures, Bailing!");
        throw new RuntimeException(e);
    }

    gl.glEnable(GL10.GL_TEXTURE_2D);
    gl.glShadeModel(GL10.GL_SMOOTH);
    gl.glClearColor(0, 0, 0, 0);
    gl.glClearDepthf(1.0f);
    gl.glEnable(GL10.GL_DEPTH_TEST);
    gl.glDepthFunc(GL10.GL_LEQUAL);
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);

    for (int x = 0; x < m; x++) {
        for (int y = 0; y < n; y++) {
            points[x][y][0] = ((x / 5.0f) - 4.5f) * wPercent;
            points[x][y][1] = ((y / 5.0f) - 4.5f) * hPercent;
            points[x][y][2] = (float) (Math
                    .sin((((x / 5.0f) * 40.0f) / 360.0f) * 3.141592654 * 2.0f));
        }
    }
    gl.glDisable(GL10.GL_DEPTH_TEST);
    gl.glDisable(GL10.GL_TEXTURE_2D);
    populateVertexBuffer(gl);
    populateTexBuffer(gl);

}

public void initialize(GL10 gl, int surfaceWidth, int surfaceHeight) {
    if (surfaceHeight == 0) {
        surfaceHeight = 1;
    }

    gl.glViewport(0, 0, surfaceWidth, surfaceHeight);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();
    GLU.gluPerspective(gl, 45.0f, (float) surfaceWidth / (float) surfaceHeight, 0.1f, 100.0f);
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();
}

private void populateVertexBuffer(GL10 gl) {

    int curVIndex = 0;
    for (int y = 0; y < n - 1; y++) {
        mVertices[curVIndex++] = points[0][y][0];
        mVertices[curVIndex++] = points[0][y][1];
        mVertices[curVIndex++] = points[0][y][2];
        if (y > 0) {
            mVertices[curVIndex++] = points[0][y][0];
            mVertices[curVIndex++] = points[0][y][1];
            mVertices[curVIndex++] = points[0][y][2];
        }
        for (int x = 0; x < m - 1; x++) {
            mVertices[curVIndex++] = points[x][y + 1][0];
            mVertices[curVIndex++] = points[x][y + 1][1];
            mVertices[curVIndex++] = points[x][y + 1][2];
            mVertices[curVIndex++] = points[x + 1][y][0];
            mVertices[curVIndex++] = points[x + 1][y][1];
            mVertices[curVIndex++] = points[x + 1][y][2];

        }
        mVertices[curVIndex++] = points[m - 1][y + 1][0];
        mVertices[curVIndex++] = points[m - 1][y + 1][1];
        mVertices[curVIndex++] = points[m - 1][y + 1][2];

        if (y < n - 2) {
            mVertices[curVIndex++] = points[m - 1][y + 1][0];
            mVertices[curVIndex++] = points[m - 1][y + 1][1];
            mVertices[curVIndex++] = points[m - 1][y + 1][2];

        }
    }
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    mVerticesBuffer.put(mVertices);
    mVerticesBuffer.position(0);
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVerticesBuffer);
}

private void populateTexBuffer(GL10 gl) {
    int curTIndex = 0;
    float float_x = 0, float_y = 0, float_xb = 0, float_yb = 0;
    for (int y = 0; y < n - 1; y++) {
        float_y = (float) (y) / (n - 1);
        float_y *= hPercent;
        float_yb = (float) (y + 1) / (n - 1);
        float_yb *= hPercent;

        mTextures[curTIndex++] = 0;
        mTextures[curTIndex++] = float_y;
        if (y > 0) {
            mTextures[curTIndex++] = 0;
            mTextures[curTIndex++] = float_y;
        }
        for (int x = 0; x < m - 1; x++) {
            float_x = (float) (x) / (m - 1);
            float_x *= wPercent;
            float_xb = (float) (x + 1) / (m - 1);
            float_xb *= wPercent;
            mTextures[curTIndex++] = float_x;
            mTextures[curTIndex++] = float_yb;
            mTextures[curTIndex++] = float_xb;
            mTextures[curTIndex++] = float_y;
        }
        mTextures[curTIndex++] = float_xb;
        mTextures[curTIndex++] = float_yb;
        if (y < n - 2) {
            mTextures[curTIndex++] = float_xb;
            mTextures[curTIndex++] = float_yb;

        }
    }
    gl.glEnable(GL10.GL_TEXTURE_2D);
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    mTextureBuffer.put(mTextures);
    mTextureBuffer.position(0);
    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);
}

private void loadGLTextures(GL10 gl) throws IOException {
    gl.glGenTextures(1, textures, 0);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap, 0);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
}

private void printFPS() {
    if (!ISPRINTFPS) {
        return;
    }
    time = SystemClock.uptimeMillis();
    if (time >= (frameTime + 1000.0f)) {
        frameTime = time;
        avgFPS += framerate;
        framerate = 0;
    }
    if (time >= (fpsTime + 3000.0f)) {
        fpsTime = time;
        avgFPS /= 3.0f;
        Log.d("FPS: ", Float.toString(avgFPS));
        avgFPS = 0;
    }
    framerate++;
}

}

FlagWallpaperService.java

public class FlagWallpaperService extends WallpaperService {

@Override
public Engine onCreateEngine() {
    return new FlagWallpaperEngine();
}

private class FlagWallpaperEngine extends Engine {

    @Override
    public void onSurfaceCreated(SurfaceHolder holder) {
        super.onSurfaceCreated(holder);
        Log.d("TAG", "Surface created");
        GLSurfaceView view = new GLSurfaceView(FlagWallpaperService.this);
        Bitmap flagBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flag);
        FlagWallpaperRenderer renderer = new FlagWallpaperRenderer(flagBitmap);
        view.setRenderer(renderer);
    }

    public FlagWallpaperEngine() {
        Log.d("TAG", "WS CONTR");
    }   
}
}

最佳答案

我建议你查看this project .该代码与您的非常相似。

我注意到您的代码中没有的一件事是可见性更改管理......像这样:

 @Override 
 public void onVisibilityChanged(boolean visible) {
    super.onVisibilityChanged(visible);
    if (visible) {
      mSurfaceView.onResume();
    } else { 
      mSurfaceView.onPause();
    } 
 } 

此外,请记住,当您使用动态壁纸时,可能同时存在多个引擎。

关于android - 设置动态壁纸时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15861032/

相关文章:

android - locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);返回空指针异常

android - 如何在Android中播放mp4文件中的声音?

c - 如何为 Mac OS X Lion 编写交互式壁纸

java - 关于如何优化这段代码有什么想法吗?我似乎想不出任何有效的办法

Android:如何使用 AlarmManager 在特定时间查看电子邮件?

android - 缩放动画循环不执行?

android - Android 上的 Unity 雾故障

android - 从 WallpaperService 启动 Intent 或向 WallpaperService 启动 Intent

Android Permission Denial 启动Intent for Wallpaper Settings

java - 使用安卓相机的简单 OCR 应用程序