最近抖音主播宸蕁櫻桃的一個小影片刷爆了社交網站,她從水中出來的剎那,擊中了不少人的心。
這個十幾秒的小影片短短几天就獲得了上百萬的點選,許多人紛紛將其設定成動態桌布,小姐姐在螢幕上游來游去,大家
又多看了好幾遍,盯著手機螢幕的時間過長,就有人戲稱“渣男”屏保。
當然,我也看了好幾遍,屏保抖音上可以專門設定,那不是抖音影片的小姐姐我也想讓她動起來,畢竟美人千千萬,多看幾個是幾個,靈感來了
今天就跟大家講講Android仿抖音實現動態桌布,一個小姐姐動起來了,其他的也不能落下。
第一次看文章的朋友點個關注,會不定期釋出Android面試內容、進階專題等相關內容
一、概述:
桌布執行在一個Android服務之中,這個服務的名字叫做WallpaperService。當使用者選擇了一個桌布之後,此桌布所對應的WallpaperService便會啟動並開始進行桌布的繪製工作。
Engine是WallpaperService中的一個內部類,實現了桌布視窗的建立以及Surface的維護工作。Engine內部實現了SurfaceView,我們只需要在其內部利用MediaPlayer + SurfaceView就可以播放動態桌布了。
二、實現:
WallpaperService需要一個xml去配置,然後在AndroidManifest.xml中宣告
<wallpaper xmlns: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配置
<service
android:name=".VideoLiveWallpaper"
android:label="@string/app_name"
android:permission="android.permission.BIND_WALLPAPER"
android:process=":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/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<Boolean>() {
@Override
public 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<Boolean>() {
@Override
public void onCompleted() {
progressBar.setVisibility(View.GONE);
}
@Override
public void onError(Throwable e) {
progressBar.setVisibility(View.GONE);
}
@Override
public 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);
}
至此,一個簡單的動態桌布就搞定了。
大家喜歡的人物都可以動起來,不點個贊支援一下?
還有仿抖音影片客戶端原始碼,加微信【xx13414521】贈送,實現效果如下
關注我,高階UI、Gradle、RxJava、小程式、Hybrid、移動架構、React Native、效能最佳化等技術教程相關內容贈送,
詳情直接看這個文件:
https://shimo.im/docs/x9X6TTW6KqqhHGy6
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69952849/viewspace-2668370/,如需轉載,請註明出處,否則將追究法律責任。