Создание приложения Xamarin с наложением поверх других приложений - PullRequest
0 голосов
/ 06 августа 2020

Я пытаюсь создать приложение xamarin android, которое должно иметь небольшое оверлейное окно, которое будет отображаться над другими приложениями.

К сожалению, я не нашел образец кода или документацию вообще.

Я пытаюсь достичь чего-то похожего на Apple Control Dot, Facebook chat-dot или наложение навигации карт Google.

У меня также есть простое приложение для записи макросов, установленное на моем телефоне, которое может делать это с учетом разрешения специальных возможностей "Рисовать поверх других приложений" включено. окно наложения образца

На скриншоте выше вы можете увидеть небольшой элемент управления записью справа. Контрольный оверлей можно перетаскивать по экрану, открываются настройки и т. Д. c.

Кто-нибудь знает, как это сделать?

С уважением,

Юлиан

1 Ответ

1 голос
/ 06 августа 2020

Вот простой пример, к которому вы можете обратиться.

Создайте FloatingService :

[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.

эффект, как показано ниже:

введите описание изображения здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...