当前位置:网站首页>Implementation of simple floating frame in WindowManager
Implementation of simple floating frame in WindowManager
2022-06-24 09:35:00 【Mars-xq】
Reference resources :
permission denied for window type 2003
WindowManager( Window management service )
10.7 WindowManager( Window management service )
jurisdiction :
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.GET_TASKS" />
// Check authority
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
// start-up Activity Let the user authorize
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
startActivity(intent);
return;
}
}
Definition service :
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import java.util.ArrayList;
import java.util.List;
public class MainService extends Service {
private boolean isAdded = false; // Whether the suspension window has been added
public static final int OPERATION_SHOW = 100;
public static final int OPERATION_HIDE = 101;
private static final int HANDLE_CHECK_ACTIVITY = 200;
public static final String OPERATION = "operation";
private WindowManager mWindowManager;
private WindowManager.LayoutParams mLayoutParams;
private Button btnView;
private ActivityManager mActivityManager;
private List<String> homeList; // List of desktop application package names
// Define an update interface Handler
@SuppressLint("HandlerLeak")
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case HANDLE_CHECK_ACTIVITY:
if (isHome()) {
if (!isAdded) {
mWindowManager.addView(btnView, mLayoutParams);
isAdded = true;
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message m = new Message();
m.what = 2;
mHandler.sendMessage(m);
}
}
}).start();
}
} else {
if (isAdded) {
mWindowManager.removeView(btnView);
isAdded = false;
}
}
mHandler.sendEmptyMessageDelayed(HANDLE_CHECK_ACTIVITY, 0);
break;
}
}
};
@Override
public void onCreate() {
super.onCreate();
homeList = getHomes();
createWindowView();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int operation = intent.getIntExtra(OPERATION, OPERATION_SHOW);
switch (operation) {
case OPERATION_SHOW:
mHandler.removeMessages(HANDLE_CHECK_ACTIVITY);
mHandler.sendEmptyMessage(HANDLE_CHECK_ACTIVITY);
break;
case OPERATION_HIDE:
mHandler.removeMessages(HANDLE_CHECK_ACTIVITY);
break;
}
return super.onStartCommand(intent, flags, startId);
}
// Define a method to create a hover box :
@SuppressLint({
"ClickableViewAccessibility", "RtlHardcoded"})
private void createWindowView() {
btnView = new Button(getApplicationContext());
btnView.setBackgroundResource(R.mipmap.ic_launcher);
mWindowManager = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
mLayoutParams = new WindowManager.LayoutParams();
// Set up Window Type
//【 Be careful 】 Check version , Pay attention to when type by TYPE_APPLICATION_OVERLAY when , Spread the active windows , But below the critical system window , Such as status bar or IME
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
mLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
}
// Set the suspension box to be untouchable
mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
// The suspended window cannot be touched , Do not accept any events , At the same time, it does not affect the subsequent event response
mLayoutParams.format = PixelFormat.RGBA_8888;
// Set the width and height of the floating box
mLayoutParams.width = 200;
mLayoutParams.height = 200;
mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
mLayoutParams.x = 200;
mLayoutParams.y = 0;
// Set the... Of the hover box Touch monitor
btnView.setOnTouchListener(new View.OnTouchListener() {
// Save the variable of the last position of the hover box
int lastX, lastY;
int paramX, paramY;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = (int) event.getRawX();
lastY = (int) event.getRawY();
paramX = mLayoutParams.x;
paramY = mLayoutParams.y;
break;
case MotionEvent.ACTION_MOVE:
int dx = (int) event.getRawX() - lastX;
int dy = (int) event.getRawY() - lastY;
mLayoutParams.x = paramX + dx;
mLayoutParams.y = paramY + dy;
// Update the position of the suspended window
mWindowManager.updateViewLayout(btnView, mLayoutParams);
break;
}
return true;
}
});
mWindowManager.addView(btnView, mLayoutParams);
isAdded = true;
}
/** * Determine whether the current interface is a desktop */
public boolean isHome() {
if (mActivityManager == null) {
mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
}
List<ActivityManager.RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);
return homeList.contains(rti.get(0).topActivity.getPackageName());
}
/** * Get the application package name of the application belonging to the desktop * * @return Returns a list of strings containing all package names */
private List<String> getHomes() {
List<String> names = new ArrayList<String>();
PackageManager packageManager = this.getPackageManager();
// attribute
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
@SuppressLint("QueryPermissionsNeeded")
List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo ri : resolveInfo) {
names.add(ri.activityInfo.packageName);
}
return names;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
start-up service :
Intent mIntent = new Intent(MainActivity5.this, MainService.class);
mIntent.putExtra(MainService.OPERATION, MainService.OPERATION_SHOW);
startService(mIntent);
Toast.makeText(MainActivity5.this, " The hover box has been opened ~", Toast.LENGTH_SHORT).show();
边栏推荐
- Event registration Apache pulsar x kubesphere online meetup hot registration
- 小白学习MySQL - 增量统计SQL的需求
- 12、 Demonstration of all function realization effects
- Easyexcel single sheet and multi sheet writing
- php文件锁
- 2022.06.23 (traversal of lc_144,94145\
- 牛客网 十进制整数转十六进制字符串
- 浮点数表示法(总结自CS61C和CMU CSAPP)
- R 椭圆随机点产生并画图
- Vidéo courte recommandée chaque semaine: Soyez sérieux en parlant de "métaunivers"
猜你喜欢

The border problem after the focus of input

零基础自学SQL课程 | HAVING子句

实战剖析:app扫码登陆实现原理(app+网页端详细逻辑)附源码

Inspiration from reading CVPR 2022 target detection paper

IDEA 无法保存设置 源根 D:XXXX在模块XXX中重复

Recommendation - Secret of curiosity: how many dancing angels can stand on the tip of a needle?

Webrtc series - network transmission 5: select the optimal connection switching

Cdga | how can we do well in data governance?
![[GDB debugging tool] | how to debug under multithreading, multiprocessing and running programs](/img/b5/38a53c88240c4308452d0208173461.png)
[GDB debugging tool] | how to debug under multithreading, multiprocessing and running programs

20、 Processor scheduling (RR time slice rotation, mlfq multi-level feedback queue, CFS fully fair scheduler, priority reversal; multiprocessor scheduling)
随机推荐
正则匹配邮箱
零基础自学SQL课程 | SQL语句语法顺序与执行顺序
php单例模式详解
Threejs MMD model loading + contour loading + animation loading + Audio loading + camera animation loading +ammojs loading gltf model loading +gltf reflection adjustment
Inspiration from reading CVPR 2022 target detection paper
jupyter入门常见的几个坑:
[redis implements seckill business ①] seckill process overview | basic business implementation
June 13-19, 2022 AI industry weekly (issue 102): career development
Xiaobai needs to learn MySQL - incremental statistical SQL
Turn to: CEO of Samsung Electronics: all decisions should start from recognizing yourself
Reasons for the failure of digital transformation and the way to success
带文字的seekbar : 自定义progressDrawable/thumb :解决显示不全
学习太极创客 — ESP8226 (十二)ESP8266 多任务处理
关于thinkphp5 使用模型save()更新数据提示 method not exist:think\db\Query-&gt; 报错解决方案
PhpStrom代码格式化设置
latex公式及表格识别
CF566E-Restoring Map【bitset】
【gdb调试工具】| 如何在多线程、多进程以及正在运行的程序下调试
Zero foundation self-study SQL course | having clause
R ellipse random point generation and drawing