Android懸浮窗的實現(xiàn)步驟
最近想做一個懸浮窗秒表的功能,所以看下懸浮窗具體的實現(xiàn)步驟
1、初識WindowManager
實現(xiàn)懸浮窗主要用到的是WindowManager
@SystemService(Context.WINDOW_SERVICE) public interface WindowManager extends ViewManager { ... }
WindowManager是接口類,繼承自接口ViewManager,可以通過獲取WINDOW_SERVICE系統(tǒng)服務得到。而ViewManager接口有addView方法,我們就是通過這個方法將懸浮窗控件加入到屏幕中去。
2、設置權(quán)限
當API Level >= 23,顯示懸浮窗功能,需要在清單文件AndroidManifest.xml中添加SYSTEM_ALERT_WINDOW權(quán)限,添加這個權(quán)限后才可以在其他應用上顯示懸浮窗。
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
通過getSystemService方式獲取WindowManager
val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
3、LayoutParam設置
WindowManager的addView方法有兩個參數(shù),一個是需要加入的控件對象,另一個參數(shù)是WindowManager.LayoutParams對象。
// view – The view to be added to this window. // params – The LayoutParams to assign to view. public void addView(View view, ViewGroup.LayoutParams params);
其中LayoutParams的type變量,這個變量是用來指定窗口的類型。在設置這個變量時,需要對不同版本的Android系統(tǒng)進行適配。
val layoutParams = WindowManager.LayoutParams() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY } else { layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE }
在Android 8.0之前,懸浮窗口設置可以為TYPE_PHONE,這種類型是用于提供用戶交互操作的非應用窗口,現(xiàn)在這個類型已棄用了。
而Android 8.0對系統(tǒng)和API行為做了修改,包括使用SYSTEM_ALERT_WINDOW權(quán)限的應用無法再使用窗口類型來在其他應用和窗口上方顯示提醒窗口:
TYPE_PHONE(已棄用)
TYPE_PRIORITY_PHONE
TYPE_SYSTEM_ALERT
TYPE_SYSTEM_OVERLAY
TYPE_SYSTEM_ERROR
如果需要實現(xiàn)在其他應用和窗口上方顯示提醒窗口,那么必須該為TYPE_APPLICATION_OVERLAY的新類型。
4、檢測是否允許開啟懸浮窗
開啟懸浮窗之前,還需要檢測用戶是否允許開啟懸浮窗,通過系統(tǒng)提供的canDrawOverlays來檢測
//檢測是否允許開啟懸浮窗 Settings.canDrawOverlays(context)
如果沒有允許開啟,需要跳轉(zhuǎn)開啟頁面,讓用戶允許開啟懸浮窗
startActivity(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION))
5、FloatingService服務
懸浮窗一直顯示在其他應用上層,需要新建FloatingService服務類,用于處理懸浮窗相關(guān)邏輯。
class FloatingService : Service() { override fun onCreate() { super.onCreate() } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { showFloatingWindow(); return super.onStartCommand(intent, flags, startId) } override fun onBind(intent: Intent?): IBinder? { return null } /** * 顯示懸浮窗 */ private fun showFloatingWindow() { // 獲取WindowManager服務 val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager // 新建懸浮窗控件 val button = Button(applicationContext) button.text = "Floating Window" button.setBackgroundColor(Color.BLUE) // 設置LayoutParam val layoutParams = WindowManager.LayoutParams() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY } else { layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE } layoutParams.format = PixelFormat.RGBA_8888 layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE layoutParams.width = ActionBar.LayoutParams.WRAP_CONTENT layoutParams.height = ActionBar.LayoutParams.WRAP_CONTENT layoutParams.x = 300 layoutParams.y = 300 // 將懸浮窗控件添加到WindowManager windowManager.addView(button, layoutParams); } }
6、啟動FloatingService
viewBinding.btnFloating.setOnClickListener { if (Settings.canDrawOverlays(this)) {//檢測是否具有懸浮窗權(quán)限 startService(Intent(this,FloatingService::class.java)) } else { startActivity(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)); } }
開啟效果如下:
7、增加拖動功能
懸浮窗顯示的位置可能會遮擋其他信息,這時就需要新增拖動功能,可以拖動到任何位置,實現(xiàn)的邏輯就是給布局View添加觸摸事件,根據(jù)觸摸和移動的位置來決定懸浮窗顯示的位置。
var x = 0 var y = 0 button.setOnTouchListener { view, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { x = event.rawX.toInt() y = event.rawY.toInt() } MotionEvent.ACTION_MOVE -> { val nowX = event.rawX.toInt() val nowY = event.rawY.toInt() val movedX = nowX - x val movedY = nowY - y x = nowX y = nowY layoutParams.x = layoutParams.x + movedX layoutParams.y = layoutParams.y + movedY // 更新懸浮窗控件布局 windowManager.updateViewLayout(view, layoutParams) } else -> {} } false }
到此這篇關(guān)于Android懸浮窗的實現(xiàn)的文章就介紹到這了,更多相關(guān)Android懸浮窗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
利用Android 防止系統(tǒng)字體變化、顯示大小變化影響
這篇文章主要介紹了利用Android 防止系統(tǒng)字體變化、顯示大小變化影響方法的相關(guān)資料,需要的朋友可以參考下面文章的具體內(nèi)容,希望對你有所幫助2021-10-10Android視頻播放器屏幕左側(cè)邊隨手指上下滑動亮度調(diào)節(jié)功能的原理實現(xiàn)
這篇文章主要介紹了Android視頻播放器屏幕左側(cè)邊隨手指上下滑動亮度調(diào)節(jié)功能的原理實現(xiàn),非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-02-02使用Java代碼在Android中實現(xiàn)圖片裁剪功能
這篇文章主要介紹了使用Java代碼在Android中實現(xiàn)圖片裁剪功能,許多應用都需要此類從相冊中選取圖片然后編輯的功能,需要的朋友可以參考下2015-07-07Android?OkHttp庫簡單使用和封裝教程助你快速掌握網(wǎng)絡請求技能
OkHttp是一個高效的HTTP客戶端庫,適用于Android和Java應用程序。它支持HTTP/2和SPDY協(xié)議,提供了同步和異步請求API、請求和響應攔截器、連接池和多路復用器、緩存支持、GZIP和DEFLATE壓縮等功能,可以大大提高網(wǎng)絡請求的性能和可擴展性2023-04-04