android byte[] 转string 好多问号_Android 仿抖音实现动态壁纸

code小生,一个专注 Android 领域的技术平台

公众号回复 Android 加入我的安卓技术群

作者:7_px
链接:https://www.jianshu.com/p/fc5cf284abbb
声明:本文已获7_px授权发表,转发等请联系原作者授权

一、概述:

壁纸运行在一个Android服务之中,这个服务的名字叫做WallpaperService。当用户选择了一个壁纸之后,此壁纸所对应的WallpaperService便会启动并开始进行壁纸的绘制工作。

Engine是WallpaperService中的一个内部类,实现了壁纸窗口的创建以及Surface的维护工作。Engine内部实现了SurfaceView,我们只需要在其内部利用MediaPlayer + SurfaceView就可以播放动态壁纸了。

二、实现:

WallpaperService需要一个xml去配置,然后在AndroidManifest.xml中声明

<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"android:thumbnail="@mipmap/icon_lacation_black___cm">
wallpaper>

继承WallpaperService实现我们自己的壁纸服务VideoLiveWallpaper

public class VideoLiveWallpaper extends WallpaperService {

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

    class VideoEngine extends Engine {
        private MediaPlayer mMediaPlayer;

        @Override
        public void onCreate(SurfaceHolder surfaceHolder) {
            super.onCreate(surfaceHolder);

        }

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

        }

        @Override
        public void onSurfaceCreated(SurfaceHolder holder) {
            super.onSurfaceCreated(holder);
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setSurface(holder.getSurface());
            try {
                mMediaPlayer.setDataSource(new File(FileUtil.getDCIMCameraDir(), "hlj_wallpaper").getAbsolutePath());
                mMediaPlayer.setLooping(true);
                mMediaPlayer.setVolume(0, 0);
                mMediaPlayer.prepare();
                mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        mMediaPlayer.start();
                    }
                });

            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        @Override
        public void onSurfaceDestroyed(SurfaceHolder holder) {
            super.onSurfaceDestroyed(holder);
            mMediaPlayer.release();
            mMediaPlayer = null;
        }

        @Override
        public void onVisibilityChanged(boolean visible) {
            if (visible) {
                mMediaPlayer.start();
            } else {
                mMediaPlayer.pause();
            }
        }
    }
}

接着声明这个服务同时声明我们上面写的xml配置

 <serviceandroid:name=".VideoLiveWallpaper"android:label="@string/app_name"android:permission="android.permission.BIND_WALLPAPER"android:process=":wallpaper">
            
            <intent-filter>
                <action android:name="android.service.wallpaper.WallpaperService" />
            intent-filter>
            
            <meta-dataandroid:name="android.service.wallpaper"android:resource="@xml/wallpaper" />
        service>

重点在onSurfaceCreated方法中,这里为了可以动态切换不同的壁纸,我是指定去加载一个固定目录下的视频文件,然后不断的复制新文件到这个目录,因为一旦开启切换壁纸这个方法就会调用,所以当调用后再动态通知去更改路径不起作用。

所以我在更换壁纸前先清空

 try {
                                WallpaperManager.getInstance(getContext())
                                        .clear();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }

再去复制需要替换的壁纸到指定目录

 copyFile(file.getAbsolutePath(),
                                    new File(FileUtil.getDCIMCameraDir(),
                                            "hlj_wallpaper").getAbsolutePath());
  /**
     * 复制单个文件
     *
     * @param oldPath String 原文件路径 如:c:/fqf.txt
     * @param newPath String 复制后路径 如:f:/fqf.txt
     * @return boolean
     */
    public void copyFile(final String oldPath, final String newPath) {
        progressBar.setVisibility(View.VISIBLE);
        Observable.create(new Observable.OnSubscribe() {@Overridepublic void call(Subscriber super Boolean> subscriber) {try {int byteSum = 0;int byteRead ;
                    File oldFile = new File(oldPath);if (oldFile.exists()) { //文件存在时
                        InputStream inStream = new FileInputStream(oldPath); //读入原文件
                        FileOutputStream fs = new FileOutputStream(newPath);byte[] buffer = new byte[1444];while ((byteRead = inStream.read(buffer)) != -1) {
                            byteSum += byteRead; //字节数 文件大小
                            System.out.println(byteSum);
                            fs.write(buffer, 0, byteRead);
                        }
                        inStream.close();
                        subscriber.onNext(true);
                        subscriber.onCompleted();
                    }
                } catch (Exception e) {
                    System.out.println("复制单个文件操作出错");
                    e.printStackTrace();
                    subscriber.onCompleted();
                }
            }
        })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer() {@Overridepublic void onCompleted() {
                        progressBar.setVisibility(View.GONE);
                    }@Overridepublic void onError(Throwable e) {
                        progressBar.setVisibility(View.GONE);
                    }@Overridepublic void onNext(Boolean aBoolean) {
                        progressBar.setVisibility(View.GONE);
                        setToWallPaper(getContext());
                    }
                });
    }

setToWallPaper 方法就是真正的开启设置壁纸操作了

public static void setToWallPaper(Context context) {
        final Intent intent = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
        intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
                new ComponentName(context, VideoLiveWallpaper.class));
        context.startActivity(intent);
    }

至此,一个简单的动态壁纸就搞定了。

推荐阅读

该用路由来管理你的界面跳转了

Android:手把手教你如何优雅的实现APP启动速度优化

ae77df6f170b59999d5849396bb44af3.png

登不上高峰,看到的风景始终有限

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/574446.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

游戏编程与游戏种类

游戏编程指利用计算机编程语言&#xff0c;如C编程语言、C、java等&#xff0c;编写计算机、手机或游戏机上的游戏。 目前流行的游戏编程语言为C编程语言&#xff0c;目前流行的游戏编程接口为DirectX9.0&#xff0c;还有OpenGL、SDL(Simple DirectMedia Layer)等。现在手机上玩…

print输出 pytorch_pytorch打印网络结构的实例

最简单的方法当然可以直接print(net)&#xff0c;但是这样网络比较复杂的时候效果不太好&#xff0c;看着比较乱&#xff1b;以前使用caffe的时候有一个网站可以在线生成网络框图&#xff0c;tensorflow可以用tensor board&#xff0c;keras中可以用model.summary()、或者plot_…

li:nth-child()和 li:nth-of-type()选择器区别

.demo li:nth-child(2)&#xff1a;表示demo下面第二个元素&#xff0c;若此元素不是li,则选择失败。.demo li:nth-of-type(2)&#xff1a;表示demo下面第二个li元素。转载于:https://www.cnblogs.com/lily2015/p/4661244.html

升序排序中国_干货满满!6行python代码挑战展示2020下半年中国最娱乐的人气男明星人气排行榜top10!...

本回答主要以2020下半年中国最娱乐的人气男明星top10变化动态条形图为例来展示如何用python生成动态条形图。知乎视频​www.zhihu.com一、 python生成动态条形图&#xff1a;以2020下半年中国最娱乐的人气男明星top10变化动态条形图为例。1. 安装第三方库1.1 下载第三方库的网址…

YII2 实现后台操作记录日志

一、连接linux服务器&#xff0c;创建数据文件 php yii migrate/create user_log 二、修改数据文件 console/migrations/m150721_032220_admin_log.php <?phpuse yii\db\Schema; use yii\db\Migration;class m150721_032220_admin_log extends Migration {public function…

cmd批量修改文件名 增加文字_Dynamo自动批量化修改文件名称

今天我们说一下如何批量化的修改文件名称&#xff0c;都9102年了总不能一个一个手动去修改吧。比如我们要对现有的族修改为带有我们企业缩写的族库,于是乎我把朋友的族就借过来了可以是下面这样&#xff1a;当然也不仅仅是修改族文件名称&#xff0c;我们可以修改任意文件夹下的…

CSS入门学习(转)

一、基础学习 1、何为CSS CSS是Cascading Style Sheets(层叠样式表)的简称&#xff0c;是一种标记语言,它不需要编译,可以直接由浏览器执行(属于浏览器解释型语 言). CSS文件也可以说是一个文本文件,它包含了一些CSS标记,CSS文件必须使用css为文件名后缀&#xff0c; 可以通…

在电脑上显示未知发布者怎么办_电脑开机后显示器黑屏只有鼠标能动,怎么办呢?...

开机黑屏进不了系统是很常见的电脑故障&#xff0c;导致该现象的原因也有很多种&#xff0c;有些用户是电脑开机后显示器黑屏只有鼠标能动&#xff0c;如果是这种情况该怎么办呢&#xff1f;出现电脑开机后显示器黑屏只有鼠标很有可能是资源管理器的问题&#xff0c;下面由维度…

ios图文详情加载html_前端项目009 Vue 信息分享系统 商品列表、详情

頔言頔语&#xff1a;进步&#xff0c;一定要进步&#xff0c;进步是跟收入持平的本钱。01 商品列表0101 路由配置和数据请求0102 上拉加载更多02 商品详情0201 详情数据请求和展示0202 轮播图组件提取0203 商品详情&#xff08;路由的本质理解&#xff09;01 商品列表0101 路由…

理解函数指针

在学习函数指针, 我遇到了问题, 我定义一个指针指向负责打印参数的函数, 1 void (*p)( int ) Fun; 好奇该指针存放的是什么&#xff08; 原以为是函数的入口地址&#xff09;&#xff0c;便调试观察一下他们的内存&#xff0c; Fun的值是 函数入口地址 0x00401030 Fun(i…

单元测试概念记录

单元测试 孤立的运行和测试某一个单元&#xff08;注重于每一个可能出错的细节&#xff09;。 优秀的单元测试的特性 1.自动的&#xff0c;可重复的 2.容易实现的 3.一旦写好将来都可以使用 4.任何人都可以运行 5.单击一个按钮就可以运行 6.可以快速的运行 判断是否是单元测试 …

zemax设置 像方远心_ZEMAX相机标定非常不完全指南

ZEMAX是广为使用的一款光学仿真软件&#xff0c;是进行光路设计和分析的利器&#xff1b;而相机标定&#xff0c;则是进行机器视觉任务时&#xff0c;拿到一款相机&#xff0c;对其实际参数进行确定的过程。因此看起来&#xff0c;二者其实主要是针对不同的侧重点。前者主要面向…

[转载]大型网站架构演变和知识体系

之前也有一些介绍大型网站架构演变的文章&#xff0c;例如LiveJournal的、ebay的&#xff0c;都是非常值得参考的&#xff0c;不过感觉他们讲的更多的是每次演变的结果&#xff0c;而没有很详细的讲为什么需要做这样的演变&#xff0c;再加上近来感觉有不少同学都很难明白为什么…

activiti 生命周期_一文让你读懂什么是Activiti工作流

Activiti工作流学习经验总结(一)什么是工作流&#xff1f;工作流指通过计算机对业务流程进行自动化管理&#xff0c;实现多个参与者按照预定义的流程去自动执行业务流程。什么是Activiti&#xff1f;Activiti 是一个开源架构的工作流引擎&#xff0c;基于bpmn2.0 标准进行流程定…

关于hkcmd.exe造成的和Eclipse之间热键冲突

可能是自己新买的笔记本比较强大,显卡也比较牛叉.当使用一些常用的Eclipse快捷键的时候Eclipse本身没有反应,反而显示器有了反应. 经常用的Eclispse中的快捷键CtrlAlt↑ 和CtrlAlt↓ 造成显示器内容的上翻转和下翻转 解决方式: 下载Windows Hot Key Explore 软件 在安装启动后…

中对曲线进行斜率提取_Au中的EQ处理方法——图形均衡器和参数均衡器

之前的文章详细讲过使用Cubase进行EQ处理&#xff0c;其实如果只是要对录音进行混音修音的话&#xff0c;使用Au也可以&#xff0c;Adobe Audition作为音乐录制及后期软件&#xff0c;具有很强大的后期功能&#xff0c;而且也可以添加插件&#xff0c;是修音混音非常好的工具。…

YUV格式转换RGB(基于opencv)

在编写代码将需要处理YUV格从每个视频帧中提取&#xff0c;然后将其保存为图片。有两种常见的方法在线&#xff0c;第一种是通过opencv自带cvCvtColor&#xff0c;可是这样的方法有bug。得到的图片会泛白。另外一种方法是公式法。 法一&#xff1a;opencv自带cvCvtColor 说明&a…

2 数据源配置_Spring, MyBatis 多数据源的配置和管理

作者&#xff1a;digdeep出处&#xff1a;https://www.cnblogs.com/digdeep/p/4512368.html热门推荐vuewebsocketSpringboot实现的即时通信开源项目springboot炸翔版CMS开源系统同一个项目有时会涉及到多个数据库&#xff0c;也就是多数据源。多数据源又可以分为两种情况&#…

(九十)使用多个storyboard+代码实现控制器的分开管理

使用单个storyboard会使得项目难与管理&#xff0c;使用纯代码又会过于麻烦&#xff0c;因此如果能将二者结合起来&#xff0c;并且使用多个storyboard&#xff0c;会使得项目简单简单、方便许多。 下面以一个简单的视图关系为例&#xff0c;介绍多个storyboard的用法。 ①有pa…

吗 支持windows_M1能否原生支持Windows 苹果把问题抛给了微软

关于苹果M1处理器近期已经有了非常多的报道&#xff0c;人们对其出色的性能表现以及较低的功耗还是充满了期待。那么最后一个也是最重要的一个问题&#xff0c;基于苹果M1处理器的电脑能原生支持微软Windows吗&#xff1f;毕竟很多人买回苹果MacBook第一件事就是安装Windows 10…