抖音百萬點選的“渣男”動態桌布,喜歡的小姐姐怎麼動起來?

yilian發表於2019-12-12

最近抖音主播宸蕁櫻桃的一個小影片刷爆了社交網站,她從水中出來的剎那,擊中了不少人的心。

這個十幾秒的小影片短短几天就獲得了上百萬的點選,許多人紛紛將其設定成動態桌布,小姐姐在螢幕上游來游去,大家
又多看了好幾遍,盯著手機螢幕的時間過長,就有人戲稱“渣男”屏保。

抖音百萬點選的“渣男”動態桌布,喜歡的小姐姐怎麼動起來?

當然,我也看了好幾遍,屏保抖音上可以專門設定,那不是抖音影片的小姐姐我也想讓她動起來,畢竟美人千千萬,多看幾個是幾個,靈感來了

今天就跟大家講講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/,如需轉載,請註明出處,否則將追究法律責任。

相關文章