当前位置:网站首页>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();
边栏推荐
- Oracle数据库EXPDP只导出表的方法
- Codeforces Round #392 (Div. 2) D. Ability To Convert
- [redis implements seckill business ①] seckill process overview | basic business implementation
- 【自定义Endpoint 及实现原理】
- Ggplot2 color setting summary
- 文献调研报告
- 2021-05-20computed and watch applications and differences
- Project deployment related
- P6698-[balticoi 2020 day2] virus [AC automata, DP, SPFA]
- 活动报名|Apache Pulsar x KubeSphere 在线 Meetup 火热报名中
猜你喜欢

深度学习论文阅读目标检测篇(七)中英对照版:YOLOv4《Optimal Speed and Accuracy of Object Detection》

latex公式及表格识别

小白学习MySQL - 增量统计SQL的需求

当程序员被问会不会修电脑时… | 每日趣闻

Oracle数据文件头SCN不一致处理方法

读CVPR 2022目标检测论文得到的亿点点启发
Depens:*** but it is not going to be installed

Oracle 12c升级至19c后ORA-28000错误

jupyter入门常见的几个坑:

Time series data augmentation for deep learning: paper reading of a survey
随机推荐
e的lnx为什么等于x
Groovy通过withCredentials获取Jenkins凭据
Easyexcel single sheet and multi sheet writing
数字化转型的失败原因及成功之道
【bug】@JsonFormat 使用时出现日期少一天的问题
Time series data augmentation for deep learning: paper reading of a survey
ApplicationContextInitializer的三种使用方法
Every (), map (), forearch () methods. There are objects in the array
【输入法】迄今为止,居然有这么多汉字输入法!
PostgreSQL
When should gridfs be used?
Jincang KFS replicator installation (oracle-kes)
Vidéo courte recommandée chaque semaine: Soyez sérieux en parlant de "métaunivers"
Niuke network realizes simple calculator function
带文字的seekbar : 自定义progressDrawable/thumb :解决显示不全
Redis implements a globally unique ID
浮点数表示法(总结自CS61C和CMU CSAPP)
Oracle的tnsnames.ora文件配置
开源一款监控数据采集器,啥都能监控
【自定义Endpoint 及实现原理】