Android Key Handling (Framework) - android

There are some parts of the framework which are not quite clear to me yet. I am well known with the flow of an input event (Kernel -> Eventhub -> InputReader -> InputDispatcher -> ...).
Situation
(Requirements: Handle input keys without changing the Android Framework.)
I want to handle key events coming from a device (keyboard/gamepad/controller/...) but there are some requirements. For one, I don't want to change the Android framework. This means, I don't want to extends the WindowManagerPolicy and its functions like interceptKeyBeforeDispatching where the home-key is being handled. This would result in the key event being dispatched into the application layer which is fine. The downside is, I have another tricky requirement here.
Example: When I am playing Angry Birds and I press my GoToAlpha-button on my connected input device, the Alpha-application has to start. Angry Birds has no clue which button GoToAlpha is, will not handle/recognize it and there will be for example no intent broadcasted to start my Alpha-application.
Question
Is there a way to handle my (custom) key event after it is being dispatched, knowing that the application in the foreground can not handle the key?
My (failed) solutions
Create a service which will handle the key events. This is not possible because an application like Angry Birds will not bind to my service and the key event will not be caught inside my service. If I am wrong, please provide more information :).
Create an external library where I allow my application's activities to inherit from my own ActivityBase. All the key events and there default behavior can be handled here. Downside, existing applications will not support my custom key events because they don't use the library.
Extend the framework would be in my eyes the cleanest solution but that will result in not meeting my requirement.
Any help or useful information would be appreciated
Extra
If the first question could be solved on one way or another.. I want
to customize my Intent behind the GoToAlpha-button. This means.. By
default the Alpha-application will be started but after the user has
customized it, the Beta-application will be started from now on.. Any
thoughts?
Thanks

Thanks for the comment Victor.
Using the InputMethodService will not provide me with enough freedom and functionality to handle my problems.
My Solution / Compromise
Within the Android Framework, there is a PhoneWindowManager which is responsible for handling InputEvents. The WindowManagerService which is started by the SystemServer, is owner of this manager and creates an instance.
By creating my own custom WindowManager and let it inherit from Android's PhoneWindowManager, I don't lose any default functionality and this allows me to add my own implementation within this class. This results is adding a new file to the framework and changing only one line inside the Android Framework: The WindowManagerService will not create a PhoneWindowManager, but will create a CustomPhoneWindowManager (extends PhoneWindowManager).
If anyone sees a better solution or has any specific thoughts about my compromis, don't hesitate to comment. :)

I doubt that it's possible with public API's (Boy and Martijn pointed out security concerns).
Most like your best bets (if you don't want to customize Android) would be
a) Try to use InputMethodService (http://developer.android.com/reference/android/inputmethodservice/InputMethodService.html)
It doesn't give that kind of control which you wish, but it could be enough for some needs.
b) Try to go through whole stack (from Kernel to Application) and find some vulnerabilities to use.
This definitely will take a lot of time and doesn't guarantee to bring any fruits.

Related

Where does an event go when injecting it into /dev/input/eventx?

I think I have read all post related with my query, some of them helped but I still can´t find the correct approach.
Im trying to develope an app which has to inject touch events into the system. As I was reading if you dont have system signature you can´t use the "logic" way, so we have to manage it using /dev/input/eventX.
Said that, I also attach photo of how events go through the system:
http://imageshack.us/f/201/eventosenandroid.png/
So I want to be sure that I understand how system manage events.
What I suppose is: When you inject a touch event in /dev/input/eventX the sequence for the event will finish into the activity which is currently "in the screen"
I just need to be sure if I can assume that it works like that or not really.
Thanks in advance
You managed to get somewhere with that? If not, did you have a look here?
Android INJECT_EVENTS permission
http://developer.android.com/reference/android/Manifest.permission.html#INJECT_EVENTS

Android: Get Time Spent Per Activity

Firstly, I'm not looking for time spent on a given application. There is already "an app for that", com.android.settings/.UsageStats, and a good deal of supporting code in the AOSP frameworks/base/services/java/com/android/server/am/UsageStatsService.java, etc.
The code that I've examined so far does not seem to record elapsed time spent on particular <activity>s. I have thought to get this information two ways, but feel there must be something cleaner and simpler, that leverages more existing code. The ideas have been:
Instrument the base Activity class onPause() and onResume(), to hack in a timestamp, and log the info some place (probably a SQLite database.)
Instrument the Context class, to make note whenever startActivity() and friends are called.
So what do you think -- anything better than those options? Thank you in advance!
So what do you think -- anything better than those options?
Anything is better than #2, which requires custom firmware.
#1 is your only option within the SDK for API Level 13 on down AFAIK.
API Level 14 (a.k.a., Android 4.0) added in Application.ActivityLifecycleCallbacks, which you can register via registerActivityLifecycleCallbacks() called on your Application (e.g., getApplicationContext()). I haven't used these yet, but it would appear that you can arrange for a single listener to be notified of activities coming and going, avoiding forcing you to extend some common base Activity class with your desired logging.

Call Back button from service Android (system-wide)

I need to remap the Honeycomb "Back" button to a button in my app (service) but after hours of search I'm still nowhere. The functionality must be there system-wise like the back button in ButtonSaviour (see market)
Most solutions for emulating the Back button are based on calling finish(). Not sure if it will work in my case since I have to call finish() from whatever activity I find on the foreground. I do manage to get the foreground application with the code
ActivityManager am = (ActivityManager) getContext().getSystemService(getContext().ACTIVITY_SERVICE);
List<RunningTaskInfo> T = am.getRunningTasks(5);
System.out.println("top activity: "+T.get(0).topActivity);
but I'm not sure how I should send a finish() intent to that..
I also tried the solution posted here http://www.anddev.org/throwing-simulating_keystrokes_programatically-t717.html but I couldn't get around the IWindowManager (has it been removed in Honeycomb?). That solution, however, looks interesting because with that I could send KeyEvent.KEYCODE_BACK from anywhere, anytime.
Please let me know which is the best way to implement this functionality SYSTEM-WIDE, i.e. from a service rather than from a specific application of mine.
cheers
PS: The app is meant to run on my own rooted tablet rather than for distribution to others.
Why does people spam the thread with advises about designs and good practices when the question clearly states that this will not be used for the market?!
Replacing android nav bar is sometimes required in some applications, even if no more than for own pleasure (or programmer satisfaction).
try from java Runtime exec
input keyevent 4
4 means back
button savior most likely uses hidden api, I had encountered that somewere, but don't remember now. When I will find it, I will post back.
The reason you're not finding an answer to this is that this is a terribly hacky way to do things and it indicates that there is something majorly broken with the design of your app. You should not be able to "call the back button," that doesn't make any sense at all. In fact, you really shouldn't change the behavior of the back button at all, users get really upset when you do that. If you have a service, and you need to send messages to an Activity, then use a messenger. But you should certainly not (and certainly cannot) be changing the behavior of other apps from your service. (This would indicate a major security flaw in the system, and would let you hijack someone else's UI, doing potentially dangerous, or at least annoying, things.)
Will the activity be open when you want to simulate the back button? If so, you could set up a timer inside your activity that checks for an exit file every 5 seconds or so. Then, from your service, create the exit file when you want to simulate the back press. When the activity sees that the exit file was created, delete that file and call finish().
As others have suggested, though, doing things this way means that you might need to rethink the app's design. What exactly are you trying to achieve?

Android StartActivtyForResult() from a Service

First I'm sorry for my english that is not so good :).
I am facing a problem to develop my app.
That is a general architecture scheme of my solution.
http://i.stack.imgur.com/ooTmE.png
To be quick, the app has to decode code bare but with two possible ways:
using exernal device (The constructor provides a sdk containing an android Service to communicate with the device),
use the camera of the mobile using the library Zxing which is possible to manage it with intent.
The goal of my own service is to manage some business code and make transparent the choice of the tool for the user.
I believed that was a good solution but I wanted to implement it and I had different problems.
My main trouble is that I cannot execute StartActivityForResult inside the service.
Do somebody have any suggestions for my problem whether a change in the architecture or a solution for the main problem?
#Laurent' : You have totaly right my service acts as an API adapter.
I will try to make the expected behaviour more clear.
I have an app that needs to recognize (real) objects which have QR codes on their top. This recognition action will be done several times by the user during the life of the app.
The user chooses to launch the recognition by clicking on a button (or otherwise but he knows that the recogntion will start). So no notification is needed.
The thing is he doesn't choose the way to do the recogniton. It is why, as you said, I implement an adapter.
The adapter chooses between :
Camera mobile or external device. The first is an activity coming from the Zxing library. The second one is a service that manages the external device. This service provides an interface to get back result.
One more thing, I need that my whole implementation (adapter and co) can be re-used by other apps that will also need to do recognition.
So my thought was to implement a service as an adapter to answer my two conditions (make transparent the choice for the user - and make the recognition available for other apps).
I hope you understand my problematic.
Given your architecture, your MyOwnService must act as an API adapter : it should provide a unified scanning API and address each external service specificities transparently.
Your expected behaviour is not clear enough to provide a solution that suits your needs but here are a few remarks that can be of some help.
Passive scanning:
Even if there are some workarounds : no activity should be launched from a service (not directly). Never. Bad. Services are background stuff, the most they will be permitted is to hint users with Notifications (this is point 2 of Justin excellent answer).
As a consequence there's nothing as a 'popup Activities' (and that's good!). If you need to continuously scan for barcodes, even when your activity is not run, then the only way to warn users is by using status bar notification.
Active scanning:
Inside your own activity you can bind to your wrapper service and make it start scanning for codebars. When it finds one it has to message your activity. Your Activity message handler has complete access to the UI to inform the user of your findings.
You selected Active Scanning in your edit, your problem is therefore to find a way for your service to actively notify your main application (the one that started the active scanning) that a new item has been scanned successfully.
You do NOT do this by starting a new activity (remember: this is bad) but you can bind to a service and/or use Messages between the wrapper service and the application.
I advice you take the time to read (and more time to comprehend) this android developer article on BoundServices and especially the part about Messengers.
A full example of Two Way Messaging between a Service and an Activity can be found in the following android examples : Service & Activity
Warning: designing robust, full blown AIDL-based services is a tough job.
Two ways you could solve this problem.
1) Have MyOwnService do a callback into MainActivity telling it to launch your ScanActivity.
- This is a better approach if MyOwnService's task is only going to be running while MainActivity is running and if the user would expect the ScanActivity to come up automatically.
2) Have MyOwnService create a notification that will let the user access the ScanActivity.
- This is a better approach if MyOwnService's task might be running longer than the life span of MainActivity. That way, you can let the user know, unobstrusively, that they might want to access the ScanActivity.
So finally I changed my architecture.
I make the choice to delete myOwnService and to create an intermediate activity that will be my API Adaptater.
This activity will have a dialog.theme to look like a dialog box indicating that a recognition is under execution.
If the recognition uses the external device this activity will stay at the foreground otherwise the camera activity will start (Being managed by the intermediate activity).
Thank to that I can manage my result from the intermediate activity and do not have an android strange architecture, keeping my business code for the recognition outside my main app.
Service was not the good choice.
Thanks a lot for you help and your time.

movement of phone causes unexpected result in code

I am developing an android app which makes no reference to the sensor aspect of the phone. At a certain pint the program sends an sms and then sleeps for five minutes. If I move the phone during this sleep period a dialog box displayed earlier reappears. I realise this is rather vague without code at this stage but to start with is this something to be expected. I am wondering if one of the broadcast listeners is being triggered by the movement but even if this is so I cant make the connection with the dialog box. Any pointers will be much appreciated.
Fist off, I would take care of the orientation change possibility by forcing the app into an orientation by using the option in the manifest file.
Second, I would look at what other apps are on the device that might have an affect on this functionality. Assuming by your question, your app uses BroadcastReceivers. If this is the case, provided your business logic permits, use explicit intents ( new Intent(this, )) in place of implicit intents and receivers. If this is not possible because of business logic, then perhaps using permissions to protect against accidental implicit intent receive triggers. Ref: http://developer.android.com/guide/topics/manifest/permission-element.html (its a good starting place anyways).
Without more info on your specific business logic or source code I can't go much deeper into the problem, but my first suggestion would probably give the simplest result. Just remember to set this attribute for each activity that this problem affects.
Steve.

Categories

Resources