news 2026/4/23 8:22:50

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/4/23 8:15:36

发音纠正反馈:结合ASR判断用户读音并与IndexTTS对比

发音纠正反馈&#xff1a;结合ASR判断用户读音并与IndexTTS对比 在虚拟偶像直播中&#xff0c;粉丝模仿主播语调朗读弹幕却总被吐槽“不像”&#xff1b;语言学习App里&#xff0c;用户反复练习“地道美音”&#xff0c;系统却只能冷冰冰地提示“发音错误”。这些场景背后&…

作者头像 李华
网站建设 2026/4/23 8:17:20

3步掌握Matminer:材料科学数据挖掘的完整入门指南

3步掌握Matminer&#xff1a;材料科学数据挖掘的完整入门指南 【免费下载链接】matminer Data mining for materials science 项目地址: https://gitcode.com/gh_mirrors/ma/matminer 材料科学数据挖掘正在改变传统材料研究的模式&#xff0c;而Matminer作为专业的开源工…

作者头像 李华
网站建设 2026/4/23 8:22:20

终极Emby美化插件2025:快速打造个性化媒体中心完整指南

还在为Emby媒体服务器的单调界面而烦恼吗&#xff1f;想要让影音库焕然一新却不知从何入手&#xff1f;这款Emby美化插件专为Chrome内核浏览器和EmbyServer设计&#xff0c;无需专业技能&#xff0c;轻松实现界面个性化定制。无论你是家庭影院爱好者还是小型媒体中心管理员&…

作者头像 李华
网站建设 2026/4/22 8:34:22

Trelby:颠覆传统剧本创作的开源利器深度剖析

Trelby&#xff1a;颠覆传统剧本创作的开源利器深度剖析 【免费下载链接】trelby The free, multiplatform, feature-rich screenwriting program! 项目地址: https://gitcode.com/gh_mirrors/tr/trelby 在数字创作浪潮席卷全球的今天&#xff0c;剧本创作者们正迫切寻求…

作者头像 李华
网站建设 2026/4/23 8:15:31

鸿蒙开发一多适配入门指南之一次开发,多端部署的实践路径

鸿蒙&#xff08;HarmonyOS&#xff09;的“一多适配”能力&#xff08;一次开发&#xff0c;多端部署&#xff09;是其核心优势&#xff0c;可让应用自动适配手机、平板、智慧屏等不同设备。本文将通过响应式布局、断点系统、三层架构三大模块&#xff0c;带你掌握一多适配的核…

作者头像 李华
网站建设 2026/4/22 22:20:36

中国行政区划数据完整指南:从省到村的五级联动解决方案

在中国互联网应用开发过程中&#xff0c;地址选择功能是必不可少的基础组件。无论是电商平台的收货地址、信息系统的信息登记&#xff0c;还是数据分析的区域划分&#xff0c;都需要准确、完整的行政区划数据支撑。本项目提供了从省级到村级的完整五级行政区划数据&#xff0c;…

作者头像 李华