news 2026/1/11 16:29:56

Android 控件 - 悬浮常驻文本交互(IBinder 实现、BroadcastReceiver 实现)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Android 控件 - 悬浮常驻文本交互(IBinder 实现、BroadcastReceiver 实现)

IBinder 实现

1、Service
  • FloatTextService.java
publicclassFloatTextServiceextendsService{privateTextViewtvFloat;privateWindowManagerwindowManager;privatefinalIBinderbinder=newFloatTextServiceBinder();publicclassFloatTextServiceBinderextendsBinder{publicFloatTextServicegetService(){returnFloatTextService.this;}}@Nullable@OverridepublicIBinderonBind(Intentintent){returnbinder;}@OverridepublicvoidonCreate(){super.onCreate();windowManager=(WindowManager)getSystemService(WINDOW_SERVICE);// 创建布局参数WindowManager.LayoutParamsparams=newWindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.WRAP_CONTENT,Build.VERSION.SDK_INT>=Build.VERSION_CODES.O?WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY:WindowManager.LayoutParams.TYPE_PHONE,WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,PixelFormat.TRANSLUCENT);// 设置位置为左下角params.gravity=Gravity.BOTTOM|Gravity.START;params.x=0;params.y=0;LayoutInflaterinflater=LayoutInflater.from(this);tvFloat=(TextView)inflater.inflate(R.layout.float_text,null);// 添加到窗口windowManager.addView(tvFloat,params);}publicvoidshowFloatText(Stringtext){tvFloat.setText(text);}@OverridepublicvoidonDestroy(){super.onDestroy();if(tvFloat!=null){windowManager.removeView(tvFloat);}}}
  • float_text.xml
<?xml version="1.0" encoding="utf-8"?><TextViewxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/tv_float"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="12dp"android:textSize="14sp"/>
2、Manifest
  • AndroidManifest.xml
<uses-permissionandroid:name="android.permission.SYSTEM_ALERT_WINDOW"/><application>...<serviceandroid:name=".viewfixed.service.FloatTextService"android:enabled="true"android:exported="false"/></application>
3、Activity Layout
  • activity_float_text_service_test.xml
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".viewfixed.FloatTextServiceTestActivity"><Buttonandroid:id="@+id/btn_show_float_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="显示悬浮文本"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"/></androidx.constraintlayout.widget.ConstraintLayout>
4、Activity Code
  • FloatTextServiceTestActivity.java
publicclassFloatTextServiceTestActivityextendsAppCompatActivity{privateActivityResultLauncher<Intent>floatPermissionLauncher;privateFloatTextServicefloatTextService;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_float_text_service_test);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main),(v,insets)->{InsetssystemBars=insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left,systemBars.top,systemBars.right,systemBars.bottom);returninsets;});test();}privatevoidtest(){floatPermissionLauncher=registerForActivityResult(newActivityResultContracts.StartActivityForResult(),result->{if(checkFloatPermission()){createFloatText();}else{Toast.makeText(this,"未开启浮窗权限",Toast.LENGTH_SHORT).show();}});if(checkFloatPermission()){createFloatText();}else{requestFloatPermission();}ButtonbtnShowFloatText=findViewById(R.id.btn_show_float_text);btnShowFloatText.setOnClickListener(v->{floatTextService.showFloatText("Hello Float Text");});}privatebooleancheckFloatPermission(){if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){returnSettings.canDrawOverlays(this);}returntrue;}privatevoidrequestFloatPermission(){Intentintent=newIntent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,Uri.parse("package:"+getPackageName()));floatPermissionLauncher.launch(intent);}privatevoidcreateFloatText(){bindService(newIntent(this,FloatTextService.class),newServiceConnection(){@OverridepublicvoidonServiceConnected(ComponentNamecomponentName,IBinderiBinder){FloatTextService.FloatTextServiceBinderbinder=(FloatTextService.FloatTextServiceBinder)iBinder;floatTextService=binder.getService();}@OverridepublicvoidonServiceDisconnected(ComponentNamecomponentName){}},BIND_AUTO_CREATE);}}

BroadcastReceiver 实现

1、Service
  • FloatTextService.java
publicclassFloatTextServiceextendsService{privateTextViewtvFloat;privateWindowManagerwindowManager;privatefinalIBinderbinder=newFloatTextServiceBinder();publicclassFloatTextServiceBinderextendsBinder{publicFloatTextServicegetService(){returnFloatTextService.this;}}publicstaticfinalStringACTION="SHOW_FLOAT_TEXT";privateBroadcastReceiverFloatTextServiceBroadcastReceiver;@Nullable@OverridepublicIBinderonBind(Intentintent){returnbinder;}@OverridepublicvoidonCreate(){super.onCreate();windowManager=(WindowManager)getSystemService(WINDOW_SERVICE);// 创建布局参数WindowManager.LayoutParamsparams=newWindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,WindowManager.LayoutParams.WRAP_CONTENT,Build.VERSION.SDK_INT>=Build.VERSION_CODES.O?WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY:WindowManager.LayoutParams.TYPE_PHONE,WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,PixelFormat.TRANSLUCENT);// 设置位置为左下角params.gravity=Gravity.BOTTOM|Gravity.START;params.x=0;params.y=0;LayoutInflaterinflater=LayoutInflater.from(this);tvFloat=(TextView)inflater.inflate(R.layout.float_text,null);// 添加到窗口windowManager.addView(tvFloat,params);FloatTextServiceBroadcastReceiver=newBroadcastReceiver(){@OverridepublicvoidonReceive(Contextcontext,Intentintent){if(intent.hasExtra("text")){StringnewText=intent.getStringExtra("text");tvFloat.setText(newText);}}};IntentFilterintentFilter=newIntentFilter();intentFilter.addAction(ACTION);registerReceiver(FloatTextServiceBroadcastReceiver,intentFilter);}publicvoidshowFloatText(Stringtext){tvFloat.setText(text);}@OverridepublicvoidonDestroy(){super.onDestroy();if(tvFloat!=null){windowManager.removeView(tvFloat);}}}
  • float_text.xml
<?xml version="1.0" encoding="utf-8"?><TextViewxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/tv_float"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="12dp"android:textSize="14sp"/>
2、Manifest
  • AndroidManifest.xml
<uses-permissionandroid:name="android.permission.SYSTEM_ALERT_WINDOW"/><application>...<serviceandroid:name=".viewfixed.service.FloatTextService"android:enabled="true"android:exported="false"/></application>
3、Activity Layout
  • activity_float_text_service_test.xml
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".viewfixed.FloatTextServiceTestActivity"><Buttonandroid:id="@+id/btn_show_float_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="显示悬浮文本"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"/></androidx.constraintlayout.widget.ConstraintLayout>
4、Activity Code
  • FloatTextServiceTestActivity.java
publicclassFloatTextServiceTestActivityextendsAppCompatActivity{privateActivityResultLauncher<Intent>floatPermissionLauncher;privateFloatTextServicefloatTextService;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_float_text_service_test);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main),(v,insets)->{InsetssystemBars=insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left,systemBars.top,systemBars.right,systemBars.bottom);returninsets;});test();}privatebooleancheckFloatPermission(){if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){returnSettings.canDrawOverlays(this);}returntrue;}privatevoidrequestFloatPermission(){Intentintent=newIntent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,Uri.parse("package:"+getPackageName()));floatPermissionLauncher.launch(intent);}privatevoidcreateFloatText(){bindService(newIntent(this,FloatTextService.class),newServiceConnection(){@OverridepublicvoidonServiceConnected(ComponentNamecomponentName,IBinderiBinder){FloatTextService.FloatTextServiceBinderbinder=(FloatTextService.FloatTextServiceBinder)iBinder;floatTextService=binder.getService();}@OverridepublicvoidonServiceDisconnected(ComponentNamecomponentName){}},BIND_AUTO_CREATE);}privatevoidtest(){floatPermissionLauncher=registerForActivityResult(newActivityResultContracts.StartActivityForResult(),result->{if(checkFloatPermission()){createFloatText();}else{Toast.makeText(this,"未开启浮窗权限",Toast.LENGTH_SHORT).show();}});if(checkFloatPermission()){createFloatText();}else{requestFloatPermission();}ButtonbtnShowFloatText=findViewById(R.id.btn_show_float_text);btnShowFloatText.setOnClickListener(v->{Intentintent=newIntent(FloatTextService.ACTION);intent.putExtra("text","Hello Float Text");sendBroadcast(intent);});}}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/8 22:12:29

Steam Deck控制器Windows驱动:从问题识别到完美配置的完整指南

当您在Steam Deck上安装Windows系统后&#xff0c;最令人困扰的问题莫过于内置控制器无法被游戏识别。SWICD开源驱动程序正是为解决这一兼容性难题而生&#xff0c;通过虚拟XBox 360控制器技术&#xff0c;让Steam Deck在Windows平台上重获完整的游戏控制体验。 【免费下载链接…

作者头像 李华
网站建设 2026/1/7 6:59:09

有声小说制作新方案:IndexTTS 2.0支持多情感演绎和长文本合成

有声小说制作新方案&#xff1a;IndexTTS 2.0支持多情感演绎和长文本合成 在短视频与有声内容爆发式增长的今天&#xff0c;一个令人头疼的问题始终困扰着创作者&#xff1a;如何让AI生成的声音不只是“念字”&#xff0c;而是真正像人一样说话&#xff1f;尤其在有声小说、虚拟…

作者头像 李华
网站建设 2026/1/6 23:49:11

实时语音驱动:IndexTTS 2.0能否用于直播场景即时生成

实时语音驱动&#xff1a;IndexTTS 2.0能否用于直播场景即时生成 在虚拟主播直播间里&#xff0c;观众一句“你看起来好生气啊”&#xff0c;下一秒主播便用带着委屈又轻嗔的语气回应&#xff1a;“我才没有生气呢&#xff01;”——语气自然、口型同步、声线熟悉。这样的交互体…

作者头像 李华
网站建设 2026/1/7 4:02:42

GBase8s 集合类型之变长数组简介

GBase 8s兼容oracle的PL/SQL编程语言&#xff0c;PL/SQL 语法需要显式设置环境变量SQLMODE为’ORACLE’后才能生效&#xff0c;默认情况下8s的SQLMODE为’GBASE’&#xff0c;此时不支持 PL/SQL 语法。本文将介绍GBase 8s兼容ORACLE模式中的变长数组类型&#xff0c;包括它们的…

作者头像 李华
网站建设 2026/1/7 7:00:37

从创作困境到专业编剧:Trelby开源剧本软件的完美解决方案

从创作困境到专业编剧&#xff1a;Trelby开源剧本软件的完美解决方案 【免费下载链接】trelby The free, multiplatform, feature-rich screenwriting program! 项目地址: https://gitcode.com/gh_mirrors/tr/trelby 你是否曾为剧本格式的繁琐规范而头疼&#xff1f;是否…

作者头像 李华
网站建设 2026/1/6 14:53:44

基于Springboot的防诈骗管理系统设计实现

社会背景与需求电信诈骗、网络诈骗等犯罪形式日益猖獗&#xff0c;手段不断翻新&#xff0c;对公众财产安全和社会稳定构成严重威胁。根据公开数据&#xff0c;2023年我国公安机关破获电信网络诈骗案件数量持续攀升&#xff0c;但受害者损失金额仍居高不下。传统人工预警和防范…

作者头像 李华