android reading user input in a service - java

I want to write an android app that would be a background service that would listen for either a specific gesture or key press in the and then trigger an action. Is it even possible to do such a thing with a service? If so could someone guide me the right direction. I have search high and low can could seem to find an answer.

not hard to read where they touch, but the touches in this way provide only location, not time, not on ups or downs.
in your service
#Override
public void onDestroy() {
super.onDestroy();
if (layout != null) {
((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(layout);
layout = null;
}
}
#Override
public void onCreate() {
super.onCreate();
layout = new RelativeLayout(this);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params.setTitle("test");
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(layout, params);
}
and for your touch handler, it will have to be as
public boolean gestureHandler(MotionEvent event, boolean eat) {
if(event.getAction() == MotionEvent.ACTION_OUTSIDE)

Doing this (except on top of apps that cooperate by sending you their input) would be a huge security hole of the kind that the android architecture is designed to prohibit. To do it you would need to modify the platform and have the watching done by something running with access to the raw touch and button input, possibly as part of the driver for that.
In other words you can with difficulty do it on your own rooted phone or on devices you manufacture, but it's not usable for most people.

Related

Black Screen Android Applications

I see a black screen between switching activities in my android app. To my knowledge Black is the default plot color for Android, so this is the placeholder until the app completes it's layout operation. There are a number of things that can cause an app to have a delay:
1. Performing a network call(s).
2. Loading data from disk.
3. Garbage collection from other tasks.
4. Restoring a complex drawing.
I have seen this question and links it had and I have tried various techniques to optimize the application such as multi threading etc. I KNOW now that my issue is with network calls and that there is a delay in the functions when there are latency issues i.e. when there is slow internet the function that I use to "check for internet" and "fetch and parse data" work slowly as it is dependent on the internet speed. Changing the application flow and activity life cycle is not possible as they are strictly set as per the functional requirements. Is there a way to solve or a workaround to this issue that can be done? These are snippets of code that I have implemented in my splash screen and there are similar codes inside other activities. This is a code that checks for internet connection in the onCreate.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
chkStatus(this);
}
public boolean chkStatus(Context context) {
final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
final android.net.NetworkInfo wifi = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
final android.net.NetworkInfo mobile = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (wifi.isConnectedOrConnecting() && isOnline()) {
Log.e("connectedto", "Wifi");
session.StoreMode("online");
return true;
} else if (mobile.isConnectedOrConnecting() && isOnline()) {
Log.e("connectedto", "Mobile 3G");
session.StoreMode("online");
return true;
} else {
session.StoreMode("offline");
Log.e("connectedto", "No Network ");
return false;
}
}
public Boolean isOnline() {
try {
Process p1 = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");
int returnVal = p1.waitFor();
boolean reachable = (returnVal == 0);
return reachable;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
You are not setting the contentView in your onCreateMethod:
Add this line after
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
Hope this helps.
I found what was happening. Somehow the function "isOnline" was being called before the splash screen. So when ever there was low internet network speed, the function was stuck and there was a black screen before the splash screen as the time of the splash screen got over before ack of the ping came back.So I removed the function from the splash screen and put it inside other activities.

Sending Scroll event to another application

I think is question is bit crazy, I basically want to send scroll event from my app to another app ( eg chrome ). So basically if chrome is opened and when user press vol up or down button, my background activity listen for that button event and if its a up event then it will scroll chrome opened webpage up or down. I am not sure is that possible because I was reading through some doc's from google and its all saying we need root permission to sent event from one app to another. I don't have any code yet. So any one know this is possible with android api ?
Thanks
I cannot answer in the context of chrome. However, You can essentially serialize what you need and send it via the intent system to another application.
As an example, in your first application, you receive the touch event
boolean onTouch(MotionEvent event){
if(event.getActionMasked() == MotionEvent.ACTION_UP){
Intent startOtherApplication = new Intent();
startOtherApplication.putExtra("ACTION_UP_X",event.getX());
startOtherApplication.putExtra("ACTION_UP_Y",event.getY());
startOtherApplication.setComponent(new ComponentName("com.your.other.application", "com.your.other.application.ActivityYouWantToHandleTouch"));
startActivity(intent);
}
}
You would then extract the intent in the Activity (ActivityYouWantToHandleTouch) in your other Application.
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
Intent fetchedIntent = getIntent();
boolean hasUpAction = false;
int x = 0;
int y = 0;
if(fetchedIntent != null){
hasUpAction = (fetchedIntent.getExtra("ACTION_UP_X")!=null);
x = fetchedIntent.getExtra("ACTION_UP_X");
y = fetchedIntent.getExtra("ACTION_UP_Y");
}
}

How to disable key-tap sound in android?

I want to enable/disable key-tap sound in android version higher then 4.2. There are any way to change default setting through programming.
Thanx in advance.
You can mute the sound when your app starts and unmute when it finishes using AudioManager
#override
public void onResume(){
super.onResume();
// this mute the Sound
AudioManager mgr = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
mgr.setStreamMute(AudioManager.STREAM_SYSTEM, true);
}
#override
public void onPause(){
super.onPause();
AudioManager mgr = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
mgr.setStreamMute(AudioManager.STREAM_SYSTEM, false);
}
You can do this in two ways 1) In XML by setting tag android:soundEffectsEnabled true or false 2) In Activity by pragmatically setSoundEffectsEnabled(true/false).
Yes, there is a way. There is an attribute and a method if you want to enable/disable.
android:soundEffectsEnabled
Boolean that controls whether a view should have sound effects enabled for events such as clicking and touching.
Here you go.
No need for audio manager or muting for sound stream of system.

Android track all gestures / touchs even the app running in background [duplicate]

I'm wondering how apps like SwipePad and Wave Launcher are able to detect touch gestures/events simply through a service. These apps are able to detect a touch gestures even though it is not in their own Activity. I've looked all over the Internet and haven't found how they can do that.
My main question is how a service can listen in on touch guestures/events just as a regular Activity may receive MotionEvents even though it may not be in the original Activity or context. I'm essentially trying a build an app that will recongize a particular touch gesture from a user regardless which Activity is on top and do something when that gesture is recongized. The touch recongition will be a thread running in the background as a service.
I had this same problem and I've finally figured it out! Thanks to this post: Creating a system overlay window (always on top). You need to use an alert window instead of an overlay (and this also means you can use it in Andoid ICS):
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL|WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
Then just attach a GestureListener in this manner:
GestureDetector gestureDetector = new GestureDetector(this, new AwesomeGestureListener());
View.OnTouchListener gestureListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
};
overlayView.setOnTouchListener(gestureListener);
Yay!
Interesting question. I don't know how they did that and I found google group posts which tell me that there is no global touch listener. But I have an idea anyways...
I found this post where someone succeeds to display a popupwindow from a service. If I would make that popup transparent and fullscreen, I'm sure I could capture the touches since I'm allowed to set a touch interceptor.
Edit: Please report results when you try that, would be interesting to know if this works...
I tested every possible solution but nothing worked some didn't fired touch event which did they frozed the screen .
So I did some reverse engineering and now posting solution which works
WindowManager.LayoutParams params = new android.view.WindowManager.LayoutParams(0, 0, 0, 0, 2003, 0x40028, -3);
View mView = new View(this);
mView.setOnTouchListener(this);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(mView, params);
I tested this on API 21 and a nexus 5 and I was able to log, from a service, when a touch event was fired by the system. However, the data inside the MotionEvent object, for example coordinates, returns 0.0 when OUTSIDE of what seems to be my app's package.
Two sources
integration,
permission
I'm curious as to why the event.getX(), event.getY() and event.getPressure() return 0.0 when not in an activity of the app where the service lives.
Edit
This solution does not prevent other listeners from receiving the touch event capured by the service because of
public boolean onTouch(View v, MotionEvent e){
Log.d(LOG_TAG, "Touch event captured");
return false;
By returning false, it allows other listeners to receive the event.
Edit2
Apparently, the input dispatcher in the OS will set the coordinates and pressure to 0 if the current activity and the listener do not share an UID, here is source
I've searched through many SO threads, but for security reasons, I don't think this is possible for all packages on the system. It certainly is for your own app though.
WindowManager
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
Floating / Overlay layout
floatyView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate
(R.layout.floating_view, null);
floatyView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.d(TAG, "event.x " + event.getX());
Log.d(TAG, "event.y " + event.getY());
if (event.getAction() == MotionEvent.ACTION_UP) {
v.performClick();
}
return false;
}
});
Layout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#android:color/transparent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

Make flashlight app work when the application is closed

I have this code that allows me to press a button to turn on my phones flashlight. What would be the best way to keep the light on, while the application is closed? I heard asynctask is good, but I read that it's meant for a background task that will communicate with the UI. What kind of "thread" should I use for this type of "application".
My onClickListener code:
button.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
//If Flag is set to true
if (isFlashOn) {
Log.i("info", "torch is turned off!");
//Set the flashmode to off
p.setFlashMode(Parameters.FLASH_MODE_OFF);
//Pass the parameter ti camera object
camera.setParameters(p);
//Set flag to false
isFlashOn = false;
//Set the button text to Torcn-ON
button.setText("Torch-ON");
}
//If Flag is set to false
else {
Log.i("info", "torch is turned on!");
//Set the flashmode to on
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
//Pass the parameter ti camera object
camera.setParameters(p);
//Set flag to true
isFlashOn = true;
//Set the button text to Torcn-OFF
button.setText("Torch-OFF");
}
}});
}
Sounds that you need a service
A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use

Categories

Resources