Reputation: 19
I want to detect if a particular gesture was made in some other screen (Not when the app's UI is open).
I have seen it in some phones, you make a 'C' kind of gesture and the camera will open. Is there something like this in Android Studio?
Upvotes: 0
Views: 1825
Reputation: 151
You can do that using Service that is running on background.
As you know, there is some applications which are using this skill such as Facebook messenger.
You can handle touch event in setOnTouchListener callback implementation of FloatingService.kt.
Please refer my source code.
[FloatingService.kt]
package com.antasis9.android.playground
import android.app.Service
import android.content.Context
import android.content.Intent
import android.graphics.PixelFormat
import android.os.IBinder
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.Button
class FloatingService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d("FloatingService", "FloatingService.onStartCommand()");
val layout = LayoutInflater.from(this).inflate(R.layout.activity_floating, null)
layout.setOnTouchListener { v, event ->
// HANDLE TOUCH EVENT HERE!
Log.d("FloatingService", "v: $v, event: $event")
false
}
val layoutParams = WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
)
(getSystemService(Context.WINDOW_SERVICE) as WindowManager).addView(layout, layoutParams)
return super.onStartCommand(intent, flags, startId)
}
override fun onBind(intent: Intent): IBinder? {
return null
}
}
[activity_floating.xml]
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent">
</android.support.constraint.ConstraintLayout>
[MainActivity.java]
I used activity to start FloatingService but you can start this service with other ways.
package com.antasis9.android.playground;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), FloatingService.class);
startService(intent);
}
});
findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), FloatingService.class);
stopService(intent);
}
});
}
}
[AndroidManifest.xml]
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.antasis9.android.playground">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".FloatingService"
android:enabled="true"
android:exported="false"></service>
</application>
</manifest>
[This is last step]
You should turn on 'display over other apps' option.
You can find this option 'Settings' -> 'Apps' -> Select {your app name}
Upvotes: 1