悬浮窗可以一直在前台显示一些信息,无论当前的Activity是哪个应用的。比如显示当前的上下行网速等
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.IBinder;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnTouchListener;
import android.view.WindowManager.LayoutParams;
/**
* 悬浮窗Service 该服务会在后台一直运行一个悬浮的透明的窗体。
*
* @author
*
*/
public class FloatingService extends Service {
private int statusBarHeight;// 状态栏高度
private View view;// 透明窗体
private boolean viewAdded = false;// 透明窗体是否已经显示
private WindowManager windowManager;
private WindowManager.LayoutParams layoutParams;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
view = LayoutInflater.from(this).inflate(R.layout.floating, null);
windowManager = (WindowManager) this.getSystemService(WINDOW_SERVICE);
/*
* LayoutParams.TYPE_SYSTEM_ERROR:保证该悬浮窗所有View的最上层
* LayoutParams.FLAG_NOT_FOCUSABLE:该浮动窗不会获得焦点,但可以获得拖动
* PixelFormat.TRANSPARENT:悬浮窗透明
*/
layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, LayoutParams.TYPE_SYSTEM_ERROR,
LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSPARENT);
// layoutParams.gravity = Gravity.RIGHT|Gravity.BOTTOM; //悬浮窗开始在右下角显示
layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
view.setOnTouchListener(new OnTouchListener() {
float[] temp = new float[] { 0f, 0f };
public boolean onTouch(View v, MotionEvent event) {
layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
int eventaction = event.getAction();
switch (eventaction) {
case MotionEvent.ACTION_DOWN: // 按下事件,记录按下时手指在悬浮窗的XY坐标值
temp[0] = event.getX();
temp[1] = event.getY();
break;
case MotionEvent.ACTION_MOVE:
refreshView((int) (event.getRawX() - temp[0]), (int) (event
.getRawY() - temp[1]));
break;
}
return true;
}
});
}
/**
* 刷新悬浮窗
*
* @param x
* 拖动后的X轴坐标
* @param y
* 拖动后的Y轴坐标
*/
public void refreshView(int x, int y) {
//状态栏高度不能立即取,不然得到的值是0
if(statusBarHeight == 0){
View rootView = view.getRootView();
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
statusBarHeight = r.top;
}
layoutParams.x = x;
// y轴减去状态栏的高度,因为状态栏不是用户可以绘制的区域,不然拖动的时候会有跳动
layoutParams.y = y - statusBarHeight;//STATUS_HEIGHT;
refresh();
}
/**
* 添加悬浮窗或者更新悬浮窗 如果悬浮窗还没添加则添加 如果已经添加则更新其位置
*/
private void refresh() {
if (viewAdded) {
windowManager.updateViewLayout(view, layoutParams);
} else {
windowManager.addView(view, layoutParams);
viewAdded = true;
}
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
refresh();
}
/**
* 关闭悬浮窗
*/
public void removeView() {
if (viewAdded) {
windowManager.removeView(view);
viewAdded = false;
}
}
@Override
public void onDestroy() {
super.onDestroy();
removeView();
}
class StatusBarReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//intent.get
}
}
}
floating.xml
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<!-- android:updatePeriodMillis="10000"> -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/floating"
android:gravity="center_vertical"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:src="@drawable/upload"/>
<TextView
android:id="@+id/flowing"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="right"
android:text="0K/s"
android:textColor="#000000"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:src="@drawable/download"/>
<TextView
android:gravity="right"
android:id="@+id/flowspeed"
android:paddingRight="10.0dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:text="17K/s"
android:textColor="#000000"
/>
</LinearLayout>
<ImageButton
android:id="@+id/floating_button_hide"
android:background="@drawable/floatingwindowhidebutton"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="\?android:buttonStyleSmall" />
</LinearLayout>
最后还要在AndroidManifest.xml加一个权限
<!-- 悬浮窗(FloatingService) permission -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
分享到:
相关推荐
开启录制后,你可以持续更新悬浮窗中的截图,以实现类似录屏的效果。 总的来说,Android后台服务悬浮窗动态截屏涉及了IntentService、悬浮窗、系统权限、反射、屏幕捕获和MediaProjection等多个技术点。理解并熟练...
悬浮窗,大家应该也不陌生,凌驾于应用之上的一个小弹窗,实现上很简单,就是添加一个系统级别的窗口,Android中通过WindowManagerService( WMS)来管理所有的窗口,对于WMS来说,管你是Activity、Toast、Dialog,...
4. 添加悬浮窗到窗口: 使用`WindowManager`的`addView()`方法将我们的视图添加到屏幕上。在这个过程中,我们需要传递布局、布局参数以及视图的父容器(通常是空的FrameLayout): ```java FrameLayout parent...
然后,使用`WindowManager`的`addView()`方法将自定义视图添加到悬浮窗中。 3. **覆盖导航栏和状态栏**:Android 5.0(API 21)及以上版本引入了`SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN`和`SYSTEM_UI_FLAG_LAYOUT_HIDE_...
在AndroidManifest.xml文件中,添加悬浮窗所需的权限: ```xml <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> ``` 2. 创建悬浮视图: 悬浮窗的核心是通过`WindowManager`接口来管理...
1、可执行demo2、service中添加悬浮窗,可增加,删除,悬浮窗。3、可点击悬浮窗事件,4、点击悬浮窗可将点击事件穿透到桌面5、只是demo,ui与逻辑不完美
同时,为了在悬浮窗中显示视频,我们需要将`MediaPlayer`的`Surface`与`SurfaceView`关联: ```java Surface surface = new Surface(mySurfaceView.getHolder().getSurface()); mediaPlayer.setDisplay(surface); `...
在`AndroidManifest.xml`中,需要添加悬浮窗所需的权限: ``` <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> ``` 这个权限使得应用可以在其他应用之上显示窗口。 3. **悬浮窗...
在Android开发中,实现一个无需额外权限的悬浮窗功能是一个常见的需求,特别是在打造辅助工具或者个性化应用时。本文将详细讲解如何在Android系统4.4(API Level 19)及以上版本实现这样的功能,主要涉及的技术点是...
3. 获取`WindowManager`服务并添加悬浮窗:通过`Context.getSystemService()`方法获取到`WindowManager`服务,然后调用`addView()`方法将自定义的视图添加到悬浮窗中。 ```java WindowManager windowManager = ...
主要涉及的核心类是`WindowManager`和`LayoutParams`,以及如何通过`addView`方法将自定义视图添加到悬浮窗中。开发者还需要理解AndroidManifest.xml中的相关权限设置,如`SYSTEM_ALERT_WINDOW`。 3. **android桌面...
5. 使用WindowManager对象,添加悬浮窗视图,使用addView方法来添加View。 6. 最后,使用updateViewLayout方法来更新悬浮窗的位置和大小。 四、WindowManager类型 WindowManager提供了多种类型的窗口,包括: * ...
首先,我们要了解的是Android中的悬浮窗技术基于系统的`SYSTEM_ALERT_WINDOW`权限。在Android 6.0(API级别23)之后,应用需要在运行时请求这一权限,而不仅仅是包含在Manifest.xml中。因此,我们需要在代码中检查...
在悬浮窗中,可以实时显示设备的网络流量数据,这通常涉及到监听网络状态变化,获取数据使用情况,然后更新悬浮窗中的数据显示。 10. **悬浮窗的生命周期**: 由于悬浮窗基于Service,其生命周期会受到Service的...
Android 悬浮窗权限各机型各系统适配大全(总结) 本篇博客主要介绍了 Android 悬浮窗权限各机型各系统适配大全,涵盖了 Android 主流各种机型和各种版本的悬浮窗权限适配。鉴于 Android 系统的碎片化问题,在适配...
在Android开发中,实现一个高仿微信文章悬浮窗涉及到多个核心组件和技术,其中包括Activity、Service以及BroadcastReceiver。本文将深入探讨这些组件的使用方法及其在悬浮窗实现中的关键作用。 首先,Activity是...
接着,在`Activity`或`Service`中,通过`WindowManager`的`addView()`方法添加悬浮窗: ```java WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); // 设置窗口类型、大小、位置等参数...
3. 使用`WindowManager`添加悬浮窗到屏幕上,通过`addView()`方法。 ```java WindowManager.LayoutParams params = new WindowManager.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup....
4. **添加和移除悬浮窗**:通过`WindowManager`的`addView()`方法添加悬浮窗,`removeView()`方法移除它。同时,可能还需要处理用户的触摸事件,以便在用户触摸到悬浮窗时做出响应。 5. **动态更新**:如果需要实时...