news 2026/4/18 11:12:14

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/18 10:52:55

Dify文档存储瓶颈如何破局?(深度优化方案全公开)

第一章&#xff1a;Dify文档存储瓶颈的现状与挑战在当前大模型驱动的应用场景中&#xff0c;Dify作为一款支持可视化编排和知识库集成的AI应用开发平台&#xff0c;其文档存储系统的性能直接影响到检索效率与响应延迟。随着用户上传文档数量的增加&#xff0c;传统的基于关系型…

作者头像 李华
网站建设 2026/4/18 8:50:28

【Dify DOCX图片丢失难题】:3步快速修复外部图片链接的终极方案

第一章&#xff1a;Dify DOCX图片丢失难题的背景与挑战在现代低代码平台 Dify 的文档处理流程中&#xff0c;DOCX 文件作为用户上传内容的重要载体&#xff0c;常用于知识库构建、AI 内容生成等场景。然而&#xff0c;许多开发者和企业在使用过程中发现&#xff0c;当通过 Dify…

作者头像 李华
网站建设 2026/4/18 11:05:19

如何用Matminer实现高效材料数据分析:新手完整指南

如何用Matminer实现高效材料数据分析&#xff1a;新手完整指南 【免费下载链接】matminer Data mining for materials science 项目地址: https://gitcode.com/gh_mirrors/ma/matminer Matminer材料数据挖掘工具为材料科学研究提供了强大的数据处理能力。无论你是刚接触…

作者头像 李华
网站建设 2026/4/18 8:50:16

Figma转HTML终极指南:3步将设计稿一键变网页代码

还在为设计到代码的转换而头疼吗&#xff1f;Figma转HTML工具正是你需要的智能转换神器&#xff0c;它能将Figma设计原型无缝转换为高质量的HTML和CSS代码&#xff0c;彻底改变你的前端开发工作流。这款强大的工具让设计稿到网页的转换变得前所未有的简单高效。 【免费下载链接…

作者头像 李华
网站建设 2026/4/13 12:35:17

基于SpringBoot的番茄种植水肥一体化管理系统

背景分析现代农业正面临资源短缺、劳动力成本上升和环境压力增大等问题。传统番茄种植模式中&#xff0c;水肥管理依赖人工经验&#xff0c;存在资源浪费、效率低下和环境污染风险。随着物联网、云计算等技术的发展&#xff0c;精准农业成为解决这些问题的有效途径。技术支撑Sp…

作者头像 李华
网站建设 2026/4/16 16:52:32

VR视频转换终极指南:从3D到2D的完整解决方案

VR视频转换终极指南&#xff1a;从3D到2D的完整解决方案 【免费下载链接】VR-reversal VR-Reversal - Player for conversion of 3D video to 2D with optional saving of head tracking data and rendering out of 2D copies. 项目地址: https://gitcode.com/gh_mirrors/vr/…

作者头像 李华