Android QQ音樂/酷狗音樂鎖屏控制實現原理,酷狗鎖屏
我實現的效果
混亂的鎖屏控制
Android自4.0版本, 也就是API level 14開始, 加入了鎖屏控制的功能, 相關的類是RemoteControlClient
, 這個類在API level 21中被標記為deprecated, 被新的類MediaSession
所替代. 我們的音樂App中最開始使用的是原生鎖屏控制API, 說實話這個API不好用, 遇到了一些小坑, 最要命的是不同品牌的手機, 鎖屏介面長的還不一樣, 就連我自己都沒見過原生4.0的鎖屏控制介面是什麼樣的. 國內的手機廠商都自以為自己的審美很強,
設計了千奇百怪的鎖屏控制介面, MIUI更奇怪, MIUI 6是在原生4.4.4的基礎上改的, 竟然有一段時間都沒有鎖屏控制介面, 後來更新才有. 而原生Android在5.0時, 將鎖屏和通知欄控制合併, 整個邏輯非常混亂. 我們還是決定像QQ音樂/酷狗音樂那樣, 自己做一個鎖屏控制頁面
題外話: 給RemoteControlClient設定封面時, 引數是一個Bitmap, 這個引數傳入後, 千萬不要在其他地方使用這個Bitmap, 也不要持有它的引用, 更不要自作聰明呼叫它的recycle方法.
實現思路
鎖屏應用: 大炮打蚊子
首先想到的因該是做一個鎖屏, 也就是使用Android的API, 做一個鎖屏應用, 和輸入法等應用一樣, 但這個方法成本很高. 國內的那些鎖屏應用, 首先要做的就是引導使用者設定鎖屏應用, 步驟相當繁雜, 只是為了一個播放控制就用一個鎖屏應用, 沒有哪個使用者會這麼有耐心.
懸浮窗: 黑魔法
得益於我國程式設計師的腦洞, 我們有了第二種思路: 懸浮窗.
懸浮窗的一個比較嚴謹的名字叫系統警告視窗, 國內外的一些流氓廠商, 經常用懸浮窗彈一些廣告, 這個懸浮窗是浮在正常的app的上面的, 所以如果它不消失, 很可能你連正常使用手機都有問題.
這是一個比較打擾使用者的東西, 而且也有一定的安全風險. MIUI的許可權管理預設是將懸浮窗關閉的, 而有道詞典的複製查詞功能, 就是用懸浮窗做的, 如果你沒給有道詞典開啟這個許可權, 複製查詞這個功能就廢了.
普通Activity偽造鎖屏
文章開頭的GIF圖片展示的效果, 就是用一個普通Activity做的.
國內的app們, 最終都選擇了這條道路, 不知道他們是誰抄的誰, 第一個想到使用普通Activity偽造一個鎖屏的開發者, 我只能說非常有創造力.
監聽鎖屏事件
準確來說我們監聽的是螢幕熄滅事件, 關屏事件的Intent是Intent.ACTION_SCREEN_OFF
, 不需要任何許可權就可以監聽, 但是必須使用程式碼註冊, 也就是說我們必須有一個Service在後臺監聽才行, 對音樂類app來說, 這不是問題, 音樂app本身就是使用Service來控制MediaPlayer
的. 只需要在Service中註冊監聽Intent.ACTION_SCREEN_OFF
就行. 監聽到這個事件, 我們就啟動一個Activity,
這就是我們的鎖屏Activity.
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_SCREEN_OFF)) {
Intent lockscreen = new Intent(PlaybackService.this, LockScreenActivity.class);
lockscreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(lockscreen);
}
}
注意我們在Service中啟動一個Activity, 需要加上Intent.FLAG_ACTIVITY_NEW_TASK
這個flag才行.
透明背景
要想做到鎖屏那樣滑動解鎖, 比如像圖中的樣子, 我們除了要根據手勢移動View以外, 還要讓Activity的背景透明, 比如將theme設定成下面這樣.
<style name="LockScreenBase" parent="AppBaseTheme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowContentOverlay">@null</item>
</style>
這個style其實做了很多東西, 大家根據自己的需要可以刪減一部分, 比如狀態列透明, 不使用TitleBar之類的.
解鎖螢幕與顯示在鎖屏之上
在顯示我們的假鎖屏的時候, 我們應當幫使用者解鎖, 這樣我們才能冒充鎖屏, 而不會出現使用者”解鎖”兩次的情況, 但我們只能要求系統解鎖沒有密碼的鎖屏, 有密碼的情況下, 我們是不能解鎖螢幕的, 這時我們應該覆蓋在鎖屏介面上, 幸好, 在API level 5中就引入了兩個Flag,FLAG_DISMISS_KEYGUARD
和FLAG_SHOW_WHEN_LOCKED
在鎖屏Activity的onCreate
方法中給Activity加上兩個Flag
this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
一定要兩個一起用, 否則效果不大好, 當時測試了好久, 後來看了一下QQ音樂的實現, 才發現兩個一起用效果才好, 否則會有一些奇怪的問題.
隱藏蹤跡與獨立的Task
作為一個鎖屏介面, 應當是獨立的, 也就是說, 我們這個Activity應當獨立於我們的App存在, 至少看起來是這樣. 從Android的角度來看, 我們app的主介面裡的所有Activity, 應當在一個Task裡, 而鎖屏Activity, 應當在一個獨立的Task裡, 因此我們需要給鎖屏Activity一個獨立的Task, 而且無論何時, 都只有一個鎖屏Activity例項存在.
另外, Android有檢視近期任務的功能, 我們不希望鎖屏介面這個獨立的Task顯示在裡面, 所以鎖屏Activity不能顯示在近期任務中.
說了這麼多, 要做很簡單, 只需要在Manifest裡面宣告Activity時加入幾個屬性即可
<activity android:excludeFromRecents="true"
android:exported="false"
android:launchMode="singleInstance"
android:name=".view.lockscreen.LockScreenActivity"
android:screenOrientation="portrait"
android:taskAffinity="com.package.name.lockscreen"
android:theme="@style/LockScreenTheme">
</activity>
上面的屬性中android:excludeFromRecents="true"
讓鎖屏Activity不顯示在近期任務中,android:launchMode="singleInstance"
和android:taskAffinity="com.package.name.lockscreen"
保證鎖屏Activity有一個單獨的Task, 且這個Task裡永遠只有它一個例項.
不響應Back按鍵
鎖屏介面當然不響應Back按鍵, 只需要重寫Activity的onBackPressed
方法即可
@Override
public void onBackPressed() {
// do nothing
}
對Home按鍵的處理
我們無法監聽Home按鍵, 但是可以改變因Home進入後臺時的處理, 比如在Manifest的activity宣告中加上
android:noHistory="true"
這樣如果使用者通過Home按鍵讓我們的應用進入後臺, 我們會讓這個activity銷燬, 就像我們被滑動關閉一樣.
如果不加, 最好重寫Activity的onNewIntent
來應對因Home進入後臺, 然後Service再次啟動鎖屏Activity的情況.
處理黑色閃屏
我們的鎖屏Activity在滑動”解鎖”之後, 理論上是直接進入下面的介面, 但有時如果下面不是launcher, 而是一個app, 有可能會閃一下黑屏, 這個其實是底下activity的入場動畫導致的, 某些Android版本會對頂部activity透明時處理有些奇怪, 我們不能保證其他的應用不閃黑屏, 但是對自己的的應用還是可以的, 只需要在我們的主體activity的style中加上
<item name="android:windowAnimationStyle">@null</item>
就不會有這種情況發生了, 但是這樣的話入場動畫也沒了, 總之如何取捨看大家了.
相關文章
- QQ音樂再出招,與酷狗酷我音樂簽署轉授權協議協議
- Python從網易雲音樂、QQ 音樂、酷狗音樂等搜尋和下載歌曲Python
- 酷狗酷我與QQ音樂簽署相互轉授權協議協議
- Windows 7系統聲音正常酷狗音樂無聲音Windows
- python 爬蟲 1 爬取酷狗音樂Python爬蟲
- python 突破酷狗收費音樂下載Python
- win10電腦酷狗沒聲音怎麼辦_win10酷狗音樂沒有聲音怎麼設定Win10
- win10系統下如何去掉酷狗音樂廣告Win10
- Thinkphp3.2高仿酷狗音樂官網|DJ舞曲程式|MP3音樂程式|PHP
- 騰訊與酷狗酷我聯姻:網路音樂市場將被壟斷
- 自己動手寫類似酷狗播放器(2)_音樂播放模組實現播放器
- Win10系統怎麼設定酷狗音樂全透明皮膚Win10
- Java爬蟲系列之實戰:爬取酷狗音樂網 TOP500 的歌曲Java爬蟲
- Win10 UWP版音樂酷狗更新:新增蝰蛇音效 優化掃描速度Win10優化
- Python爬蟲:通過做專案,小編了解了酷狗音樂的加密過程Python爬蟲加密
- 一篇文章教會你使用Python網路爬蟲下載酷狗音樂Python爬蟲
- Android開屏、鎖屏、解鎖監聽實現Android
- 酷狗面試感想面試
- jQuery實現高仿QQ音樂jQuery
- Android 音視訊 遇上鎖屏那些事Android
- QQ音樂音質加密加密
- Windows 7系統下QQ來訊息是酷狗播放器聲音變小Windows播放器
- 酷狗音樂的爬取,基於python,從無到有完整教程-上:搭建環境及爬取原理講解Python
- iPhone8鎖屏聲音怎麼關閉? iPhone8關閉鎖屏聲音教程iPhone
- 如何使用 python 爬取酷我線上音樂Python
- 總結獲得【酷我音樂】歌曲URL地址
- 網易雲音樂解鎖灰色歌曲教程
- 音樂播放器WordPress外掛 WP-Player (支援網易雲音樂, 蝦米音樂, QQ音樂, 百度音播放器
- QQ音樂api介面梳理API
- QQ音樂API koa2實現 - 全介面實現API
- 音樂App評測之QQ音樂篇:音樂圈多樣演算法差評APP演算法
- 微信小程式-仿QQ音樂微信小程式
- Python 爬蟲QQ音樂Python爬蟲
- Android自定義View–仿QQ音樂歌詞AndroidView
- 如何實現炫酷的數字大屏
- vue 音樂App QQ音樂搜尋列表最新介面跨域設定VueAPP跨域
- 【mybatis-plus】什麼是樂觀鎖?如何實現“樂觀鎖”MyBatis
- AI音樂,騰訊音樂、網易雲音樂的新版圖?AI