Home button override in android - java

Im trying to understand the ways to override the home button functionality in Android.
Im doing a LockScreen App and the HOME button is unlocking the device.
I have been researching the last 3 days for a way to do it, and all the solutions I have found are not 100% effective (mostly due to the nature of HOME).
I have implemented solutions for all the solutions below in these three days but Im still not satisfied.
Problem:
I want to be able to override the HOME button functionality the same way as the WidgetLocker app in the AppStore.
WidgetLocker is not a home launcher and it still can override the HOME better than anyone.
Link to WidgetLocker App
Disclaimer
First of all, I know that this is a security measure in Android so that an App does not take full control of the device, and I agree with it.
The official way is to implement a home launcher and its my preferred of them all, unfortunately my boss is still not 100% convinced on the path I selected, until I exhaust all other possibilities.
It must be for 4.0+ version of android
Solutions
Implement as Home launcher, catch the HOME intent and take care of home button presses, this has the problem that the user must select the app as the default home launcher and may not understand why (another problem I know, but still)
Implement a Service with a SYSTEM_OVERLAY view that is launched every time the device is locked, being effectively on top of everything, unfortunately (or fortunately security wise) the home button presses are still being sent to the app below and the default home launcher is still called.
Implement an activity parallel to the one that implements the lock screen, that contains the HOME Intent that is activated/deactivated programatically on the my app options, effectively changing the main app to a homelauncher on demand, when this activity is called it launches the lockscreen activity.
Is there any other way to do this?
Thanks in advance.

Look in the following topic for a way to override the home button:
Overriding the functionality of Home Button
Personally though I would suggest going for the option where you implement your own home screen. We use a similair setup where I work. The app we want people to use is set as the default option when the home button is pressed. That way we can control where people can go to a large degree. This options can only be reset by resetting the application defaults of the app. This makes it non-permanent in case a fix to the device is needed.
For the latter implementation just install with the following lines in your manifest
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
Now the next time you press the home button a pop-up will ask you what you want to do.

Related

How to register app as an launcher after installation

I am building a custom launcher (home screen) for Android 4.0+. Now I face an issue which is that I need user to setup a few things before they can use it as a custom launcher. That means that after initial setup, I need to register my app as custom launcher through code instead of through the manifest file. How do I go about this? It's clearly possible since Yahoo Aviate can do just that.
I needed to register my app as a custom launcher through code instead of through AndroidManifest.xml file
That is not strictly possible. You have to have the MAIN/HOME <intent-filter> in the manifest.
You are welcome to have that activity be disabled initially, via android:enabled="false" on the <activity> element. Then, when you are ready for the home screen to be usable, use PackageManager and setComponentEnabledSetting() to make the activity be enabled, after which the user can choose to use it as their home screen.

Creating invisible mode with code/pattern for running specific Android App

I'm building an Android App that her purpose to be secret, I dont want the icon will exist in the apps menu.
The idea is that that only the user that installed the app could use it with a private code he configured after installation.
Can I hide my app from the list and run it?
What are my options starting this app by entering kind of code/pattern for that use? and is it possibile to connect to the user lock\unlock system after screen looks and let him set a uniqe code that after entering it he could enter to the app mode.
I'll be happy getting some code or any kind of tutorials
I've seen other apps use a private dialling code/fake phone number to trigger opening a hidden app.
You can register a listener for NEW_OUTGOING_CALL and check the EXTRA_PHONE_NUMBER that is passed with it to cancel the call and open your app if the number matches your private code. Otherwise ignore and let the call go through as normal.
This obviously has permissions for that are needed that may look suspicious to potential users.
As for removing your app from the launcher as other's suggested and as described in the linked Question you need to remove the <intent-filter> from your <activity>
<category android:name="android.intent.category.LAUNCHER" />

Home button brings back to my app

I am making a car launcher application, which contains shortcuts to other apps, when i'm in another app i'd like to press the home button and go back to my launcher
So basically i need to override the home button outside of my app,the override has to work only when my app is opened in the background so when i close my app the home button will work as usual taking you to your default launcher
Can i implement something like this or i'm asking too much?
There is no way to intercept the home button on Android, unless you make your app the home screen. This is for security reasons, so that malicious apps cannot take over your device by overriding all the buttons that can exit. The home button is the one sure shot way to be able to leave any app.
In short, no it's not possible, and even if it were, it is a serious disruption in what a user expects out of an app's behavior.
If you go the route of making your app act be a replacement home screen you'll have to include in the install instructions for the users to set your app as the default launcher.
Then the home button would take them to your app. In order to get it to switch back to the default launcher when they are not in "car" mode would be a bit tricky but you could prolly achieve it with some sort of fork activity that checks if car mode is enabled if so go to your car mode launcher if not go to the default launcher (it gets trickier if the user already has a different 3rd party launcher) So essentially your app will always be the home screen app no matter if car mode is enabled or not, but if it is not then you manually start the "normal" home screen.

How to prevent Android application from loading multiple times?

This must be an easy one but I'm not having much luck searching for an answer.
Apologies if this is a regular question.
If I navigate away from my app I cannot return to it. Starting the app again will load a second instance of it rather than returning to it. If I leave an audio loop running in my app, It's hard to get back in and turn it off.
On startup I'd like the app to destroy any previous instance of itself left running.
I'd also like to try having the app shut itself down when I navigate away (I know it's not the right way to do things but I'd like to try this for my own personal use of the app). Or have the "back" button destroy the app.
Thanks.
Add this to your activity definition in manifest...
android:launchMode = "singleInstance"
How to prevent the activity from loading twice on pressing the button
I have answered such a question,you can declare android:launchMode="singleTask" attribute for your MainActivity in the AndroidManifest.xml file, so that the OS won't create a new instance if there is one running in the background.

Retaining android app state using alwaysRetainTaskState and lauchMode

In my Android app, I have a main activity that serves as an entry point to my application, which is configured in my manifest file like this :
<activity android:name=".Main"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:alwaysRetainTaskState="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
So for a particular use case, lets say a user starts up the app from the home screen by clicking the icon inside the application launcher. After starting the app, the user navigates from the Main activity to activity A and then finally to activity B. At this point, the user decides to check their facebook, so they click the home button to put my app in the background, and launches the facebook app.
After checking their facebook, the user wants to return to my app, so they press the home key, and launch the application from the application launcher (just like they did the first time it was launched).
When a user returns to my app, I want the app to return to the last activity the user was at when the app was put into the background, which in this case is activity B. In the manifest file, I have set alwaysRetainTaskState=true to make sure the OS doesn't kill my app's activities.
Now to my question: how do I get the behavior I described above? Whenever I click my app's icon, it always starts at the Main activity, no matter what. I think this is because of the category.LAUNCHER attribute. I have tried android:launchMode=singleTask, but it hasn't made a difference; it always starts at Main.
If someone could clarify intent filters, launch modes, and tasks, that would be great!
FYI singleTask is not what you want, since it starts a new task:
http://developer.android.com/guide/topics/manifest/activity-element.html#lmode
How are you launching Activity B? Any non-standard launch modes or Intent flags?
For anyone coming here with similar problems, I found something strange that might be what you are seeing... maybe.
Say I have an app with activities A -> B -> C etc. I was having issues with my app always "resuming" to A if it was launched from the app list aka launcher. Resuming from the "resents" screen (long home press) would exhibit correct resume behaviour though (resume to B or C as expected). My manifest was nothing special, I have alwaysRetainTaskState="true" set in my root activity, and launch mode is default (standard).
I was loading the apk onto my phone via a website. After downloading and installing, I would press "Open" to launch the app right away. For some reason (after uninstalling the app) I tired downloading again, installing, but then I pressed the "Done" button instead. Then Launching the app from the launcher/"all apps" list has the same resume behaviour as resuming from recents - in other words my problems were being caused somehow because of the installation process when clicking "Open" instead of "Done".
I verified this "solution" on API10 (2.3.5) and API15 (4.0.4)
I solved this by adding the screenless DispatcherActivity and making it the default one (by using the very same intent filter). In its onCreate method you create and call the Intent based on some reasonable default (your Main activity for example) OR based on some saved token that identifies which Activity should be started. That token is saved/refreshed in onStop method of any Activity you want to call on restart. You can save this token to Preferences.
The rational here is that last activity that was visible will execute onStop method when interrupted.
Word of caution here: I did implement this pattern and it worked reasonably well. However it seems not play too well with history and finally I just gave up and yanked this code out. Nobody complained so far.

Categories