android - 创建 Xamarin 应用程序并覆盖其他应用程序
问题描述
我正在尝试创建一个 xamarin android 应用程序,它应该有一个显示在其他应用程序上方的小覆盖窗口。
不幸的是,我还没有找到示例代码或文档。
我想要实现的是类似于 Apple 控制点、Facebook 聊天点或谷歌地图导航覆盖的东西。
我的手机上还安装了一个简单的 makro 记录器应用程序,只要启用了“在其他应用程序之上绘制”的可访问性权限,它就可以做到这一点。
在上面的屏幕截图中,您可以看到右侧的小录制控件。控制覆盖可以在屏幕上拖动,打开设置等。
任何人都知道如何做到这一点?
最好的祝福,
朱利安
解决方案
这是一个您可以参考的简单示例。
创建一个浮动服务:
[Service]
class FloatingService : Service,Android.Views.View.IOnTouchListener
{
WindowManagerLayoutParams layoutParams;
IWindowManager windowManager;
View floatView;
public override void OnCreate()
{
base.OnCreate();
}
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
showFloatingWindow();
return StartCommandResult.NotSticky;
}
public override IBinder OnBind(Intent intent)
{
return null;
}
private void showFloatingWindow()
{
windowManager = GetSystemService(WindowService).JavaCast<IWindowManager>();
LayoutInflater mLayoutInflater = LayoutInflater.From(ApplicationContext);
floatView = mLayoutInflater.Inflate(Resource.Layout.floatview, null);
floatView.SetBackgroundColor(Android.Graphics.Color.Transparent);
floatView.SetOnTouchListener(this);
ImageView iv1 = floatView.FindViewById<ImageView>(Resource.Id.iv1);
ImageView iv2 = floatView.FindViewById<ImageView>(Resource.Id.iv2);
ImageView iv3 = floatView.FindViewById<ImageView>(Resource.Id.iv3);
iv1.Click += delegate { Toast.MakeText(ApplicationContext, "The first Image Click", ToastLength.Short).Show(); };
iv2.Click += delegate { Toast.MakeText(ApplicationContext, "The second Image Click", ToastLength.Short).Show(); };
iv3.Click += delegate { Toast.MakeText(ApplicationContext, "The third Image Click", ToastLength.Short).Show(); };
// set LayoutParam
layoutParams = new WindowManagerLayoutParams();
if (Build.VERSION.SdkInt >= Build.VERSION_CODES.O)
{
layoutParams.Type = WindowManagerTypes.ApplicationOverlay;
}
else
{
layoutParams.Type = WindowManagerTypes.Phone;
}
layoutParams.Flags = WindowManagerFlags.NotTouchModal;
layoutParams.Flags = WindowManagerFlags.NotFocusable;
layoutParams.Width = 400;
layoutParams.Height = 100;
layoutParams.X = 300;
layoutParams.Y = 300;
windowManager.AddView(floatView, layoutParams);
}
private int x;
private int y;
public bool OnTouch(View v, MotionEvent e)
{
switch (e.Action)
{
case MotionEventActions.Down:
x = (int)e.RawX;
y = (int)e.RawY;
break;
case MotionEventActions.Move:
int nowX = (int) e.RawX;
int nowY = (int) e.RawY;
int movedX = nowX - x;
int movedY = nowY - y;
x = nowX;
y = nowY;
layoutParams.X = layoutParams.X+ movedX;
layoutParams.Y = layoutParams.Y + movedY;
windowManager.UpdateViewLayout(floatView, layoutParams);
break;
default:
break;
}
return false;
}
}
floatview.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="match_parent">
<ImageView
android:id="@+id/iv1"
android:src="@android:drawable/ic_media_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:id="@+id/iv2"
android:src="@android:drawable/star_on"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:id="@+id/iv3"
android:src="@android:drawable/ic_menu_more"
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
然后在您的 Activity 中启动 FloatingService :
button.Click += async delegate
{
if (!Settings.CanDrawOverlays(this))
{
StartActivityForResult(new Intent(Settings.ActionManageOverlayPermission, Android.Net.Uri.Parse("package:" + PackageName)), 0);
}
else
{
StartService(new Intent(this, typeof(FloatingService)));
}
}
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
if (requestCode == 0)
{
if (!Settings.CanDrawOverlays(this))
{
}
else
{
StartService(new Intent(this, typeof(FloatingService)));
}
}
}
并添加<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
您的Manifest.xml
.
效果如下:
推荐阅读
- go - 使用 goreleser 将工件发布到 gitlab 时操作超时
- azure-functions - 无法在 Azure 中的 java 函数部署中删除文件
- dolphindb - 如何将矩阵变成元组?
- haskell - DataKinds 提升类型的居民
- html - ActionButton 和 dateInput 不适用于闪亮的 html 模板
- mysql - 当我试图在 phpmyadmin 中导入这个 .sql 文件时,似乎无法弄清楚是什么导致了这个错误。(我使用的是 000webhost.com)
- asp.net - 基于 DatePicker 过滤 Web 窗体 GridView 不返回数据
- git - 在 git 远程存储库中推送时从文件中的 ñ 更改为 �
- javascript - 获取按钮单击后导航的 URL
- css - Cloudinary 最近的图像正在覆盖屏幕上显示的所有表单图像?