I have one app that runs as a service and broadcast receiver with root and device administrator access. I need that app to be able to control the UI for any other app that may be running. For example, I might want to hide the system nav bar or override the home button while other apps are running in the foreground. It is to sandbox the user.
Can anyone suggest how I might do such a thing? Hiding the nav bar in your own app is easy, and of course overriding buttons is no big deal, but I need for one app to be able to do it for other apps.
I'm considering if the UI Automator could help.
My apps (the sandboxer and the other apps that will be running) are mine and they will all have root access. I will also be able to build my own custom version of the Android OS on each device if I need to.
-Thanks
Ok this needs to be done in a two step process,
Create a broadcast from your service
Register a broadcast receiver in your UI application to listen to the broadcasts
In your service do this
Intent intent = new Intent();
intent.setAction(BROADCAST_ACTION);
sendBroadcast(Intent);
In your mainActivity, use
registerReceiver(<receiver instance>, BROADCAST_ACTION)
in the onStart or onCreate method.
This will setup your mainActivity to listen to the broadcasts, next you need to define your broadcast receiver which is the in the above register call.
BroadcastReceiver receiver;
receiver = new BroadcastReceiver() {
public void onReceive(Context c, Intent i) {
//Modify the UI, in this case hide the dialog box.
}
}
Related
What is the most frequently triggered android intent action that my app could have a BroadcastReceiver listening for without a service running in order to receive it?
Background
I have a foreground service that needs to run roughly whenever the user is present at the phone. When the screen gets turned off I shut down the service so Doze mode can be achieved (and yes, foreground running services block Doze mode even though documentation doesn't clearly state so).
The problem comes when trying to turn the service back on.
I've already looked into SCREEN_ON and USER_PRESENT but both appear to require a running background service in order to be received which negates what i am trying to achieve.
So my thought is, I wonder if there's a action triggered frequently enough when the user is present that I could listen for that instead of SCREEN_ON/USER_PRESENT?
I've found that the best way to do this is to register a BroadcastReceiver on the "android.intent.action.USER_PRESENT" action.
To distinguish between cases where the user has turned on his screen when it wasn't locked to when he actually unlocked it use the KeyguardManager to check the security settings.
add this in activity
registerReceiver(new PhoneUnlockedReceiver(), new IntentFilter("android.intent.action.USER_PRESENT"));
and use this :
public class PhoneUnlockedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
KeyguardManager keyguardManager = (KeyguardManager)context.getSystemService(Context.KEYGUARD_SERVICE);
if (keyguardManager.isKeyguardSecure()) {
//do stuff here
}
}
}
Happy coding!!
I am developing an app and this app needs to give a clear indication to the user when some event happens.
Only thing I could do until now is giving a notification in the notification area. But, I need to give a more visible notification, similar to the behavior when phone is ringing in an incoming call.
As I can understand, the reason why android is only allowing apps to give a notification is to prevent apps from disturbing the user. But, this app I am developing plays a vital role in the job of the user, so I don't think it is inappropriate to give a such strong notification.
I know it should be doable since apps like Viber can start an activity similar to a incoming phone call, even when the device is sleeping.
Does anyone know how to get this done?
Register a broadcast receiver, and add a custom action to it say CustomAction.Instead of showing notification, throw a broadcast and add CustomAction via intent filter.
Now in the onReceive method of broadcast listener, check
if(intent.getAction.equals("CustomAction"))Intent i = new Intent(context, YourActivity);
context.startActivity(i);
Sorry for not a formatted answer, I'm driving, will update it later for more clarification.
Update
Register broadcast receiver in a sticky service. So that service can be started automatically if killed and register broadcast register again.
Don't forget to unregister broadcast receiver in onDestroy() method of service and also in YourActivity when you purpose is resolved.
Just adding a sticky service (which does nothing) fixed the issue. Adding the service prevented the process getting killed when user exits the app and removes it from recent app list.
Because of the service, the app process is running even when a no UI is visible. In this state, if an activity is shown from the GCM service, it gets shown.
You can trigger a broascast as Vinay mentioned. If it still does not work, try using wake-locks. These wake-locks help in waking the device when it is in sleep mode. It will act like force wake and after calling wake-locks, you can perform your actions.
Hope it helped..
Thanks.
Is there a way to receive broadcasts(like sms notification) in stopped application?
Actually it works simply in lower than Android 3.1.
EDIT 1:
Thanks to #Squonk for comment.
So my questions is, is it REALLY impossible? you can check PlanB app in market which does this things.
EDIT 2:
this is my broadcast receiver. The onReceive function is never called(when application is stopped).
public class SmsReciever extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
Log.e("kpav", "kpav");
String url = "http://www.google.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(32);
i.setData(Uri.parse(url));
arg0.startActivity(i);
}
}
For Android v3.1 onwards, any app which has been manually started at least once by the user, will receive broadcasts that it has registered in the manifest even after a reboot.
BUT...the user must have manually started that app - it's not possible for an app to be installed and have it automatically receive broadcasts otherwise.
Also, if the user manually uses 'Force Stop' from the Settings on a device, it will no longer receive broadcasts until the user manually starts the app again.
So basically, in answer to your question...
Is there a way to receive broadcasts(like sms notification) in stopped application?
...the answer is no except under the circumstances I describe above.
You can inlcude Stopped Packages to receive broadcasts by simply adding the following flag to the broadcasting intent.
intent.addFlags(32);
Where as 32 refers to Intent.FLAG_INCLUDE_STOPPED_PACKAGES which is available from API level 12.
I have a app which is a single activity app , it listens to many broadcast event , my question is that how can I ensure that I receive all the fired intent which i have added for my app even when my app is not in foreground and running in background ??
is there a certain method where
I should add my intent filter and
do the registerReciever ? I'm sure
it won't work if I keep it in
"Oncreate"
any ideas or help ??
It sounds like you want to be using a BroadcastReceiver to pick up the events when you are in the 'background'. This will pick up events which are actually broadcast without having to launch a UI.
You can set up the BroadcastReceiver and its intent filters in the manifest for your application, this way you dont have to rely on any java code being run to register the receivers.
I have an application that listens for screen off, and user present intents. Since you cant register to receive screen off intents from the manifest, I am registering them in a service.
Do I really need to have a whole service to ensure that I always get notified of when the screen shuts off, and the user unlocks the phone? Seems really wasteful :-(
The code I use in my service:
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "Service created.");
// register receiver that handles user unlock and screen off logic
IntentFilter filter = new IntentFilter(Intent.ACTION_USER_PRESENT);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenReceiver();
registerReceiver(mReceiver, filter);
}
You can use a broadcast receiver class. A broadcast receiver can be a stand alone part of an application.
Action_User_Present can be registered in the manifest file.
Please consider what you are broadly trying to do, and a different way to do it.
Yes, the only way to monitor the events is to be actively registered. This is very intentional, because they are a very tempting thing for applications to think they want to be told about, and ending up with a bunch of apps having to be launched each time the user turns their screen on or off would end up with a really bad user experience.
Given that, I can tell you right now that there is no way you can guarantee that you will see these events, besides using a service that is always running and has used startForeground() to prevent itself from being killed. Obviously, this is not something you want to do unless your app is doing something the user very deliberately cares about having running for them when they decide it should be.
So... what are you trying to accomplish?
Since you cant register to receive screen off intents from the manifest
Are you sure about that? The documentation does not describe that limitation, whereas it does for ACTION_BATTERY_CHANGED, ACTION_CONFIGURATION_CHANGED, and ACTION_TIME_TICK.
Please use a manifest-registered BroadcastReceiver if at all possible.
This is some core android code.
mUserPresentIntent = new Intent(Intent.ACTION_USER_PRESENT);
mUserPresentIntent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
| Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
and
mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
We should register filter programmatically when core send with "FLAG_RECEIVER_REGISTERED_ONLY" Flag.