手机透明壁纸

    最近看到个一个透明壁纸的应用,感觉很好玩,所以就想弄弄。

    完整代码已经传到github上,地址是https://github.com/SZJing/Screen

    应用下载地址https://pan.baidu.com/s/1smhfByP


    其实他的思路很简单,就是打开手机摄像头的预览,让这个预览作为壁纸。因为一直打开这摄像头,所以又耗费资源又耗电。因此这个应用的实际用处并不大,只是比较新奇,做来玩玩的。

    这个应用好像最初是在Google Play上的,而且下载量很高。有兴趣的可以看看。

     接下来就是代码了,我也是看着别人的代码做的,有些甚至是直接copy的,但是我在原来的基础上又增加了双击拍照的功能,感觉有点类似偷拍的功能了。但是偷拍被打,概不负责。

首先是AndroidMainfest.xml文件

<service
            android:label="@string/app_name"
            android:name=".MyService"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.BIND_WALLPAPER">

            <!-- 为实时壁纸配置intent-filter -->
            <intent-filter>
                <action  android:name="android.service.wallpaper.WallpaperService" />
            </intent-filter>
            <!-- 为实时壁纸配置meta-data -->
            <meta-data android:name="android.service.wallpaper"
                android:resource="@xml/livewallpaper" />
        </service>
这是服务部分,并进行相应的配置。
<uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.SET_WALLPAPER" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

这是要申请的权限,不过要注意照相机和内存读取要进行运行时权限的设置,否则程序不能使用。当然这是6.0之后才有的。
 

 
接下来就是service的代码部分了
public class MyService extends WallpaperService {
    public MyService() {
    }
    @Override
    public Engine onCreateEngine() {
        return new CameraEngine();
    }
    class CameraEngine extends Engine implements android.hardware.Camera.PreviewCallback{
            private Camera camera;
        private int count = 0;
        private long firClick = 0;
        private long secClick = 0;
        private final int interval = 500;
        @Override
        public void onCreate(SurfaceHolder surfaceHolder){
            super.onCreate(surfaceHolder);
            startPreview();
            setTouchEventsEnabled(true);
        }
        @Override
        public void onTouchEvent(MotionEvent event) {
            super.onTouchEvent(event);
            if (event.getAction() == MotionEvent.ACTION_DOWN){
                count++;
                if (1 == count){
                    firClick = System.currentTimeMillis();
                }else if (2 == count){
                    secClick = System.currentTimeMillis();
                    if (secClick  - firClick <interval){
                        camera.autoFocus(new Camera.AutoFocusCallback() {
                            @Override
                            public void onAutoFocus(boolean success, Camera camera) {
                                camera.takePicture(null,null,mPicture);
                            }
                        });
                    }else {
                        firClick = secClick;
                        count = 1;
                    }
                    secClick = 0;
                }
            }
            // 时间处理:点击拍照,长按拍照
        }
        private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                File pictureFile = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg");
                try{
                    FileOutputStream fos = new FileOutputStream(pictureFile);
                    fos.write(data);
                    fos.close();
                    count = 0;
                    firClick = 0;
                    startPreview();
                }catch (Exception e){
                    Log.i("qwdfdf","保存失败");
                }
            }
        };
        @Override
        public void onDestroy() {
            super.onDestroy();
            stopPreview();
        }
        @Override
        public void onVisibilityChanged(boolean visible) {
            if (visible) {
                startPreview();
            } else {
                stopPreview();
            }
        }
        public void startPreview() {
            camera = Camera.open();
            camera.setDisplayOrientation(90);
            try {
                camera.setPreviewDisplay(getSurfaceHolder());
            } catch (IOException e) {
                e.printStackTrace();
            }
            camera.startPreview();
        }
        /**
         * 停止预览
         */
        public void stopPreview() {
            if (camera != null) {
                try {
                    camera.stopPreview();
                    camera.setPreviewCallback(null);
                    // camera.lock();
                    camera.release();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                camera = null;
            }
        }
        @Override
        public void onPreviewFrame(byte[] data, android.hardware.Camera camera) {
                camera.addCallbackBuffer(data);
        }
    }
}
看着很多,但是其实好理解。首先是要继承WallpaperService,接下来是重写他的onCreateEngine方法,这个是必须重写的。我们在其中实例化自己的一个类,并让它继承Engine。
在这个类中我们就要设置预览,要预览就得有SurfaceHolder。同时我们也要设置他的点击事件,(这是我自己加的)在onTouchEvent中就是判断是否是两次连续的点击事件。这里注意的是,拍照用的是takePicture,他会回调PictureCallback,在这个回调完成之后我们需要重新开始预览,要不然留下的是我们拍照的照片。但是这也存在一些小问题,就是重新预览会有一点卡顿,这也是需要改进的地方。
最后我们在MainActivity中申请权限,开始服务就好了。这还有点注意的是启动服务高版本的只能用显示启动,不能隐式启动,否则会报错。

   完整代码已经传到github上,地址是https://github.com/SZJing/Screen

    应用下载地址https://pan.baidu.com/s/1smhfByP

 
 

                
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值