详解android6.0版本下悬浮窗实现
作者:迟做总比不做强 时间:2023-09-04 18:43:34
悬浮窗在安卓中实现起来还是比较容易的,这几天在网上温习了相关资料,运行在我安卓6.0手机上才发现,原来在6.0手机上不是行的。
第一反应肯定是权限相关问题,做了相关处理后,果然让悬浮窗原形毕露了。直接贴代码。
public class MainActivity extends AppCompatActivity {
private static final int ALERT_WINDOW_PERMISSION_CODE = 100;
private Button start_float;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start_float = (Button) findViewById(R.id.start_float);
this.start_float.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (Build.VERSION.SDK_INT > 22) {
sdk23Permission();
} else {
startService(new Intent(MainActivity.this, FloatService.class));
finish();
}
}
});
}
/**
* @description 安卓6.0下权限处理
* @author ldm
* @time 2017/3/20 15:00
*/
public void sdk23Permission() {
if (!Settings.canDrawOverlays(this)) {
Toast.makeText(MainActivity.this, "当前无权限使用悬浮窗,请授权!", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, ALERT_WINDOW_PERMISSION_CODE);
} else {
startService(new Intent(MainActivity.this, FloatService.class));
finish();
}
}
/**
* 用户返回
*/
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == ALERT_WINDOW_PERMISSION_CODE) {
if (!Settings.canDrawOverlays(this)) {
Toast.makeText(MainActivity.this, "权限授予失败,无法开启悬浮窗", Toast.LENGTH_SHORT).show();
} else {
startService(new Intent(MainActivity.this, FloatService.class));
finish();
}
}
}
}
对应Service:
public class FloatService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
FloatViewUtils.getInstance(this).addFloatView();
super.onCreate();
}
}
简单地FloatView:
public class FloatView extends View {
public static final int WIDTH = 150;
public static final int HEIGHT = 150;
private Paint circlePaint;
private Paint textPaint;
private static final String text = "50%";
public FloatView(Context context) {
this(context, null, 0);
}
public FloatView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public FloatView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaints();
}
/**
* @description 初始化相关画笔Paint
* @author ldm
* @time 2017/3/20
*/
private void initPaints() {
circlePaint = new Paint();
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.GRAY);
textPaint = new Paint();
//设置抗锯齿
textPaint.setAntiAlias(true);
//设置字体大小
textPaint.setTextSize(30);
//设置颜色
textPaint.setColor(Color.WHITE);
//设置(仿)粗体
textPaint.setFakeBoldText(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(WIDTH, HEIGHT);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(WIDTH / 2, HEIGHT / 2, WIDTH / 2, circlePaint);
float textWidth = textPaint.measureText(text);
float x = WIDTH / 2 - textWidth / 2;
Paint.FontMetrics fms = textPaint.getFontMetrics();
float dy = -(fms.descent + fms.ascent) / 2;
float y = HEIGHT / 2 + dy;
canvas.drawText(text, x, y, textPaint);
}
}
以及FloatView管理工具类:
public class FloatViewUtils {
private static FloatViewUtils instance;
private Context mContext;
private WindowManager manager;
private FloatView floatView;
private FloatViewUtils(Context mContext) {
this.mContext = mContext;
manager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
floatView = new FloatView(mContext);
}
public static FloatViewUtils getInstance(Context mContext) {
if (null == instance) {
synchronized (FloatViewUtils.class) {
if (null == instance) {
instance = new FloatViewUtils(mContext);
}
}
}
return instance;
}
public void addFloatView() {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
//悬浮窗口大小
lp.width = floatView.WIDTH;
lp.height = floatView.HEIGHT;
// 调整悬浮窗口位置
lp.gravity = Gravity.LEFT | Gravity.CENTER;
// 以屏幕左上角为原点,设置x、y初始值
// lp.x = 0;
// lp.y = 0;
//设置悬浮窗口类型
lp.type = WindowManager.LayoutParams.TYPE_PHONE;
//设置悬浮窗口不接受焦点及触摸事件
lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
//设置图片格式,效果为背景透明
lp.format = PixelFormat.RGBA_8888;
manager.addView(floatView, lp);
}
}
最后不要忘记在AndroidManifest.xml中添加权限(当然还有注册Service):
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
来源:http://blog.csdn.net/true100/article/details/64126121
标签:android,悬浮窗
0
投稿
猜你喜欢
Android中ContextMenu用法实例
2023-02-12 20:09:49
Java编程中的一些常见问题汇总
2022-01-08 18:05:46
spring多数据源配置实现方法实例分析
2023-06-06 22:15:56
使用springboot logback动态获取application的配置项
2023-09-03 21:21:41
SpringMvc微信支付回调示例代码
2023-01-24 08:00:03
Java class文件格式之访问标志信息_动力节点Java学院整理
2022-10-31 18:57:29
MyBatisPlus3.x中使用代码生成器(全注释)
2022-04-06 19:34:38
Java中四种访问权限资料整理
2021-12-04 13:23:58
springcloud-gateway集成knife4j的示例详解
2023-11-29 08:56:44
spring-boot使用AOP统一处理日志
2023-06-09 05:12:35
Java 六类运算符详解
2023-08-27 20:37:37
详解Springboot对多线程的支持
2023-09-21 02:18:21
spring boot写java web和接口
2022-10-02 09:52:02
springboot docker jenkins 自动化部署并上传镜像的步骤详解
2023-07-28 01:54:38
C语言使用strcmp()函数比较两个字符串的实现
2023-10-15 13:06:55
Springmvc完成ajax功能实例详解
2021-09-07 23:23:25
Android registerForActivityResult动态申请权限案例详解
2021-10-05 17:40:42
SpringBoot创建WebService方法详解
2022-02-08 10:29:31
Android 之BottomsheetDialogFragment仿抖音评论底部弹出对话框效果(实例代码)
2023-08-06 01:01:56
Maven的porfile与SpringBoot的profile结合使用案例详解
2023-11-14 00:07:59