针对使用WallpaperService和openGL ES得到的动态图形设置动态壁纸的说明

1.首先创建一个MyselfWallpaperService类继承于WallpaperService类。在该类中的onCreateEngine()方法中返回一个return new MyEngine()。然后在该类内部,定义一个类MyEngine类继承自WallpaperService.Engine类

这里重点说明:在实现MyEngine类时,一定要在MysekfWallpaperService类中,因为MyEngine类是Engine的子类,而Engine是WallpaperService类的内部类。这一点一定注意。

2.然后在MyselfWallpaperService类中定义一个MySurfaceView类,该类继承自GLSurfaceView类,然后该类中的getHolder()函数中,返回的是MyserfWallpaperService.MyEngine.this.getSurfaceHolder();

3.而后,在MyEngine类中创建openGL ES中需要用到的render类。其中具体实现这里不在赘述。

4.而后在res/xml目录下(没有的有键创建即可)创建一个wallpaper.xml文件,其中的代码为:

<?xml version="1.0" encoding="utf-8"?>
<wallpaper xmlns:android ="http://schemas.android.com/apk/res/android"/>

5.而后在activity_main.xml文件中设置:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

<Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/set_btn"
        android:text="设置动态壁纸"
        />

</LinearLayout>

6.然后注册该服务类。

在AndroidManifest.xml中的<application中设置:

<!--配置动态壁纸-->
<service android:name=".MyselfWallpaperService"
    android:label="@string/app_name"
    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>

7.最后,开通联网权限:

<uses-permission android:name="android.permission.SET_WALLPAPER"/>

以下为代码实现:

MyselfWallpaperService类代码

  1. package com.example.lab11;

    import android.content.Context;
    import android.opengl.GLSurfaceView;
    import android.service.wallpaper.WallpaperService;
    import android.util.AttributeSet;
    import android.view.SurfaceHolder;

    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.opengl.GLUtils;
    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    import java.nio.FloatBuffer;
    import javax.microedition.khronos.egl.EGLConfig;
    import javax.microedition.khronos.opengles.GL10;

    public class MyselfWallpaperService extends WallpaperService {

    // 实现WallpaperService必须实现的抽象方法
        @Override
        public Engine onCreateEngine() {
            // 返回自定义的Engine
            return new MyEngine();
        }

    //定义Engine类
        public class MyEngine extends WallpaperService.Engine {

    private long startTime;//保存开始时间

    //定义一个surfaceView对象
            private MySurfaceView mySurfaceView;

    //定义一个Render对象
            private MyRenderer myRenderer;

    @Override
            public void onSurfaceCreated(SurfaceHolder holder) {
                super.onSurfaceCreated(holder);

    //初始化surfaceView对象
                mySurfaceView = new MySurfaceView(MyselfWallpaperService.this);
                myRenderer = new MyRenderer(MyselfWallpaperService.this);
                mySurfaceView.setRenderer(myRenderer);

    }

    @Override
            public void onVisibilityChanged(boolean visible) {
                super.onVisibilityChanged(visible);

    if(myRenderer != null){
                    if(visible){  //表示显示
                        mySurfaceView.onResume();  //表示显示壁纸
                    }else {
                        mySurfaceView.onPause();  //表示暂停壁纸
                    }
                }
            }

    @Override
            public void onDestroy() {
                super.onDestroy();

    mySurfaceView.onWallpaperDestroy();  //销毁surfaceView对象

    }

    //定义MySurfaceView类
            public class MySurfaceView extends GLSurfaceView implements SurfaceHolder.Callback {

    public MySurfaceView(Context context) {
                    super(context);
                }

    public MySurfaceView(Context context, AttributeSet attrs) {
                    super(context, attrs);
                }

    @Override
                public SurfaceHolder getHolder() {
                    return MyselfWallpaperService.MyEngine.this.getSurfaceHolder();
                }

    @Override
                public void onPause() {
                    super.onPause();
                }

    @Override
                public void onResume() {
                    super.onResume();
                }

    public void onWallpaperDestroy() {
                    super.onDetachedFromWindow();
                }

    }

    //设置的Render类
            public class MyRenderer implements GLSurfaceView.Renderer {

    // 立方体的顶点坐标(一共是36个顶点,组成12个三角形)
                private float[] cubeVertices = {
                        -0.6f, -0.6f, -0.6f, -0.6f, 0.6f, -0.6f,
                        0.6f, 0.6f, -0.6f, 0.6f, 0.6f, -0.6f,
                        0.6f, -0.6f, -0.6f, -0.6f, -0.6f, -0.6f,
                        -0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f,
                        0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f,
                        -0.6f, 0.6f, 0.6f, -0.6f, -0.6f, 0.6f,
                        -0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f,
                        0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f,
                        -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, -0.6f,
                        0.6f, -0.6f, -0.6f, 0.6f, 0.6f, -0.6f,
                        0.6f, 0.6f, 0.6f, 0.6f, 0.6f,0.6f,
                        0.6f, -0.6f, 0.6f, 0.6f, -0.6f, -0.6f,
                        0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f,
                        -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f,
                        0.6f, 0.6f, 0.6f, 0.6f, 0.6f, -0.6f,
                        -0.6f, 0.6f, -0.6f, -0.6f, -0.6f,-0.6f,
                        -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, 0.6f,
                        -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, -0.6f
                };

    // 定义立方体所需要的6个面(一共是12个三角形所需的顶点)
                private byte[] cubeFacets = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
                        13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
                        30, 31, 32, 33, 34, 35, };

    // 定义纹理贴图的坐标数据
                private float[] cubeTextures = {
                        1.0000f, 1.0000f,   1.0000f, 0.0000f,   0.0000f, 0.0000f,
                        0.0000f, 0.0000f,   0.0000f, 1.0000f,   1.0000f, 1.0000f,
                        0.0000f, 1.0000f,   1.0000f, 1.0000f,   1.0000f, 0.0000f,
                        1.0000f, 0.0000f,   0.0000f, 0.0000f,   0.0000f, 1.0000f,
                        0.0000f, 1.0000f,   1.0000f, 1.0000f,   1.0000f, 0.0000f,
                        1.0000f, 0.0000f,   0.0000f, 0.0000f,   0.0000f, 1.0000f,
                        0.0000f, 1.0000f,   1.0000f, 1.0000f,   1.0000f, 0.0000f,
                        1.0000f, 0.0000f,   0.0000f, 0.0000f,   0.0000f, 1.0000f,
                        0.0000f, 1.0000f,   1.0000f, 1.0000f,   1.0000f, 0.0000f,
                        1.0000f, 0.0000f,   0.0000f, 0.0000f,   0.0000f, 1.0000f,
                        0.0000f, 1.0000f,   1.0000f, 1.0000f,   1.0000f, 0.0000f,
                        1.0000f, 0.0000f,   0.0000f, 0.0000f,   0.0000f, 1.0000f
                };

    private Context context;
                private FloatBuffer cubeVerticesBuffer;
                private ByteBuffer cubeFacetsBuffer;
                private FloatBuffer cubeTexturesBuffer;
                // 定义本程序所使用的纹理
                private int texture;

    public MyRenderer(Context main) {
                    this.context = main;
                    // 将立方体的顶点位置数据数组包装成FloatBuffer;
                    cubeVerticesBuffer = floatBufferUtil(cubeVertices);
                    // 将立方体的6个面(12个三角形)的数组包装成ByteBuffer
                    cubeFacetsBuffer = ByteBuffer.wrap(cubeFacets);
                    // 将立方体的纹理贴图的坐标数据包装成FloatBuffer
                    cubeTexturesBuffer = floatBufferUtil(cubeTextures);
                    startTime=System.currentTimeMillis();      //系统当前时间
                }

    @Override
                public void onSurfaceCreated(GL10 gl, EGLConfig config)
                {
                    // 关闭抗抖动
                    gl.glDisable(GL10.GL_DITHER);
                    // 设置系统对透视进行修正
                    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
                    gl.glClearColor(0, 0, 0, 0);
                    // 设置阴影平滑模式
                    gl.glShadeModel(GL10.GL_SMOOTH);
                    // 启用深度测试
                    gl.glEnable(GL10.GL_DEPTH_TEST);
                    // 设置深度测试的类型
                    gl.glDepthFunc(GL10.GL_LEQUAL);
                    // 启用2D纹理贴图
                    gl.glEnable(GL10.GL_TEXTURE_2D);
                    // 装载纹理
                    loadTexture(gl);

    float matAmbient[]=new float[]{1,1,1,1};         //定义材质的环境光
                    float matDiffuse[]=new float[]{1,1,1,1};         //定义材质的散射光
                    //设置材质的环境光
                    // gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, matAmbient,0);
                    //设置材质的散射光
                    //gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, matDiffuse,0);
                }

    @Override
                public void onSurfaceChanged(GL10 gl, int width, int height) {
                    // 设置3D视窗的大小及位置
                    gl.glViewport(0, 0, width, height);
                    // 将当前矩阵模式设为投影矩阵
                    gl.glMatrixMode(GL10.GL_PROJECTION);
                    // 初始化单位矩阵
                    gl.glLoadIdentity();
                    // 计算透视视窗的宽度、高度比
                    float ratio = (float) width / height;
                    // 调用此方法设置透视视窗的空间大小。
                    gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);

    float lightAmbient[]=new float[]{0.2f,0.2f,0.2f,1};             //定义环境光
                    float lightDiffuse[]=new float[]{1,1,1,1};                    //定义散射光
                    float lightSpecular[]=new float[]{1,1,1,1};                    //定义散射光
                    float lightPos[]=new float[]{1,1,1,1};                      //定义光源的位置

    gl.glEnable(GL10.GL_LIGHTING);                            //启用光源
                    gl.glEnable(GL10.GL_LIGHT0);                              //启用0号光源
                    gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient,0); //设置环境光
                    gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse, 0);    //设置散射光
                    gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, lightSpecular, 0);    //设置散射光
                    gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0);      //设置光源的位置
                }

    public void onDrawFrame(GL10 gl) {
                    // 清除屏幕缓存和深度缓存
                    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
                    // 启用顶点坐标数据
                    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
                    // 启用贴图坐标数组数据
                    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);   // ①
                    // 设置当前矩阵模式为模型视图。
                    gl.glMatrixMode(GL10.GL_MODELVIEW);
                    gl.glLoadIdentity();
                    // 把绘图中心移入屏幕2个单位
                    gl.glTranslatef(0f, 0.0f, -2.0f);

    //旋转
                    long elapsed = System.currentTimeMillis() - startTime;       //计算逝去的时间
                    gl.glRotatef(elapsed * (30f / 1000f), 0, 1, 0);                //在y轴上旋转30度
                    gl.glRotatef(elapsed * (15f / 1000f), 1, 0, 0);                //在x轴上旋转15度

    // 设置顶点的位置数据
                    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeVerticesBuffer);
                    // 设置贴图的坐标数据
                    gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, cubeTexturesBuffer);  // ②
                    // 执行纹理贴图
                    gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);  // ③
                    // 按cubeFacetsBuffer指定的面绘制三角形
                    gl.glDrawElements(GL10.GL_TRIANGLES, cubeFacetsBuffer.remaining(),
                            GL10.GL_UNSIGNED_BYTE, cubeFacetsBuffer);
                    // 绘制结束
                    gl.glFinish();
                    // 禁用顶点、纹理坐标数组
                    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
                    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
                    // 递增角度值以便每次以不同角度绘制
                }

    private void loadTexture(GL10 gl) {
                    Bitmap bitmap = null;
                    try
                    {
                        // 加载位图
                        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.bg);

    int[] textures = new int[1];

    // 指定生成N个纹理(第一个参数指定生成一个纹理)
                        // textures数组将负责存储所有纹理的代号
                        gl.glGenTextures(1, textures, 0);
                        // 获取textures纹理数组中的第一个纹理
                        texture = textures[0];
                        // 通知OpenGL将texture纹理绑定到GL10.GL_TEXTURE_2D目标中
                        gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
                        // 设置纹理被缩小(距离视点很远时被缩小)时的滤波方式
                        gl.glTexParameterf(GL10.GL_TEXTURE_2D,
                                GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
                        // 设置纹理被放大(距离视点很近时被方法)时的滤波方式
                        gl.glTexParameterf(GL10.GL_TEXTURE_2D,
                                GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
                        // 设置在横向、纵向上都是平铺纹理
                        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
                                GL10.GL_REPEAT);
                        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
                                GL10.GL_REPEAT);
                        // 加载位图生成纹理
                        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
                    }
                    finally
                    {
                        // 生成纹理之后,回收位图
                        if (bitmap != null)
                            bitmap.recycle();
                    }
                }
            }

    // 定义一个工具方法,将float[]数组转换为OpenGL ES所需的FloatBuffer
            private FloatBuffer floatBufferUtil(float[] arr) {
                FloatBuffer mBuffer;
                // 初始化ByteBuffer,长度为arr数组的长度*4,因为一个int占4个字节
                ByteBuffer qbb = ByteBuffer.allocateDirect(arr.length * 4);
                // 数组排列用nativeOrder
                qbb.order(ByteOrder.nativeOrder());
                mBuffer = qbb.asFloatBuffer();
                mBuffer.put(arr);
                mBuffer.position(0);
                return mBuffer;
            }

    }

    }

MainActivity类代码:

package com.example.lab11;

import androidx.appcompat.app.AppCompatActivity;

import android.app.WallpaperManager;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

private Button mSetBtn;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

mSetBtn = (Button)findViewById(R.id.set_btn);

mSetBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startLiveWallpaperPreView(getPackageName(),MyselfWallpaperService.class.getName());
            }
        });
    }

public void startLiveWallpaperPreView(String packageName, String classFullName) {
        ComponentName componentName = new ComponentName(packageName, classFullName);
        Intent intent;
        if (android.os.Build.VERSION.SDK_INT < 16) {
            intent = new Intent(WallpaperManager.ACTION_LIVE_WALLPAPER_CHOOSER);
        } else {
            intent = new Intent("android.service.wallpaper.CHANGE_LIVE_WALLPAPER");
            intent.putExtra("android.service.wallpaper.extra.LIVE_WALLPAPER_COMPONENT", componentName);
        }
        startActivityForResult(intent, 0);
    }
}

Android使用WallpaperService和openGL ES生成的动态图形设置动态壁纸相关推荐

  1. cocos2d-x 2.X for Android中需要使用OpenGL ES 2.0

    cocos2d-x 2.X for Android中需要使用OpenGL ES 2.0 到了2.X版本中,cocos2d-x for Android已经不再支持(或者说放弃支持)opengl es 1 ...

  2. ANDROID 高性能图形处理 之 OPENGL ES

    原文:http://tangzm.com/blog/?p=20 在之前的介绍中我们说到在Android 4.2上使用RenderScript有诸多限制,我们于是尝试改用OpenGL ES 2.0来实现 ...

  3. android 视频播放滤镜,用openGL ES+MediaPlayer 渲染播放视频+滤镜效果

    之前曾经写过用SurfaceView,TextureView+MediaPlayer 播放视频,和 ffmpeg avi解码后SurfaceView播放视频,今天再给大家来一篇openGL ES+Me ...

  4. Android 3D开发,OpenGL ES 的使用(一)

    最近有人问OpenGL ES 的使用,我通过几行代码演示一下. 不需要讲 来源 历史或大篇前奏.. 通过短短的一段就能迅速理解OpenGL ES 初步使用方法,对OpenGL ES 有了大概的概念和感 ...

  5. Android 3D游戏开发——Opengl ES游戏引擎实现

    Android 3D游戏 开发 (基础篇)--Opengl ES游戏引擎实现 详情请看:http://www.hztraining.com/bbs/showtopic-26.aspx 课程描述:   ...

  6. 【OpenGL ES】二维图形绘制

    目录 OpenGL ES 学习--2D 着色器语言基础知识 绘制纯色背景 JAVA版本 C++版本 绘制圆点.直线.三角形 JAVA版本 C++版本 绘制彩色三角形 JAVA版本 C++版本 绘制纯色 ...

  7. EGL接口介绍-----Android OpenGL ES底层开发

    引自:http://www.cnitblog.com/zouzheng/archive/2011/05/30/74326.html EGL 是 OpenGL ES 和底层 Native 平台视窗系统之 ...

  8. OpenGl文章 Android OpenGL ES 简明开发教程

    Android OpenGL ES 简明开发教程 分类:android学习笔记2011-12-14 15:04375人阅读评论(0)收藏举报 ApiDemos 的Graphics示例中含有OpenGL ...

  9. Android Camera使用OpenGL ES 2.0和GLSurfaceView对预览进行实时二次处理(黑白滤镜)

    第一篇 Android Camera使用OpenGL ES 2.0和GLSurfaceView对预览进行实时二次处理(黑白滤镜) 第二篇 Android Camera使用OpenGL ES 2.0和T ...

最新文章

  1. Educational Codeforces Round 108(Rated for Div. 2) E - Off by One(一种一般图的边最大匹配,好题)
  2. iptables配置
  3. JavaScript 如何使用闭包
  4. 好好学python·集合
  5. JAVA 入门(一)
  6. 《Pytorch - 神经风格转换》
  7. 【ES6】Class 类的使用与继承方法详解
  8. “简易四则运算生成程序——第一次改进后的单元测试”链接
  9. 计算机一级wps选择题必背知识点,计算机一级考试wps选择题专项训练
  10. 优秀雇员必备六大关键技能(2)
  11. 我的世界java材质包推荐下载_我的世界材质包排行-Minecraft材质包-我的世界高清材质包下载大全-Minecraft中文分享站...
  12. BackTrack5 (BT5) 无线wpa密码破解教程 gerix
  13. typora实现上划线等操作
  14. 微信支付签名失败(几种解决方案)
  15. html四舍五入函数,Javascript四舍五入(Math.round()与Math.pow())
  16. Android 中Native方法是怎样调用的
  17. 一元三次函数的最值计算
  18. PythonStock(29)股票系统:涛动周期论 经济周期决定人生财富命运,下一步的研究方向,从宏观角度进行市场行情研究。
  19. 编写程序,解决鸡兔同笼问题:一个笼子里关着鸡和兔子。问笼中各有多少只鸡和兔?
  20. HD-SDI芯片方案选择及其应用与发展方向

热门文章

  1. 初学者对爬虫的一些基本的理解
  2. 哈希和一致性哈希算法
  3. 华为荣耀android进入,抱团升级:华为/荣耀共四款机型开启Android 9内部测试
  4. java实现excel导出合并单元格
  5. 《阿里云科技评论》第五期
  6. 两核云服务器python,硬核分享:一套云操作,让Dynamo成为变形金刚
  7. remote: You are not allowed to push code to this project.unable to access .. 403
  8. 混合App自动化测试
  9. 使用ESXi-Customizer-PS为esxi集成第三方驱动
  10. java怎么配置_怎么配置java环境变量