Broadcast receiver invoke when another applications a particular activity is opened - android

I wand a Broadcast receiver invoke when another applications a particular activity is opened in android. For example When Navigation page in Map application that installed in android phone, When opened and showing the Navigation, I want to show a Toast that display "Currently showing Navigation". So how can I achieve that?

This below code will help you to identify windo change event
public class AccessibilityEventService
extends AccessibilityService {
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED)
Log.i("op",event.getPackageName());
}
}
but it has to enabled by users from Accessibility under settings.
or You can check current top activity in a time gap using following code
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
// get the info from the currently running task
List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1);
Log.d("topActivity", "CURRENT Activity ::"
+ taskInfo.get(0).topActivity.getClassName());
ComponentName componentInfo = taskInfo.get(0).topActivity;
componentInfo.getPackageName();

As my understood that you need to show a toast on onRecieve Fuunction
Toast.makeText(context,"your text",2000).show();
//context is input parameter from onRecieve function

Related

android studio get Activity object from service

i have an app with service that works completely background, but sometimes i need to change the content in the foreground activity , for now let's say i want to show Toast.
first i am checking if the app is opened as foreground
public boolean isForeground(String myPackage) {
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> runningTaskInfo = manager.getRunningTasks(1);
ComponentName componentInfo = runningTaskInfo.get(0).topActivity;
return componentInfo.getPackageName().equals(myPackage);
}
then i want to know what is the running activity
String PKG_Name = componentInfo.getPackageName();
this will give me the name , but what i want is to is get the object Activity ,to do something like this:
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
}
});
how can i do it? if not possible, is there's a way to is to send a signal or a message to the service to tell the it?
For that you have two options, if you are fine showing just a Toast and not interact with other elements, you can implement a broadcast reciever and make your custom intent with custom action,
Intent int= new Intent(); int.setAction("Your custom string here");
and then post a toast in your braodcast reciever,
OR
you can use a custom handler to interact with all the objects in foreground and activity, here's some study material for it,
https://developer.android.com/training/multiple-threads/communicate-ui

Detect current foreground Activity and reload it

My Problem:
In MainActivity I start to download some data from the Internet via XML Parser. This data is displayed on every Screen of my App. It is like a Database.
While downloading and saving data, the user of the App can navigate through the hole app. If downloading and saving data is finished, I want to detect and reload the current foreground Activity. I need to do this, to display the new data.
I can detect the current Activity with the ActivityManager and can start it with the ComponentName with the method "startActivity(Intent.makeMainActivity(componentName)". But then the old activity is also there when I navigate back with the ActionBar-BackButton.
I do this in the AsyncTasks onPostExecute-Method after downloading Data.
Any Ideas how to do it?
protected void onPostExecute(MainActivity.UrlParams result) {
Toast.makeText(result.contextMain, "Daten wurden erfolgreich aktualisiert!", Toast.LENGTH_LONG).show();
//Aktualisiert aktive Activity damit die neuen Daten angezeigt werden!
ActivityManager am = (ActivityManager) result.contextMain.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
Log.d("topActivity", "CURRENT Activity ::" + taskInfo.get(0).topActivity.getClassName());
ComponentName componentInfo = taskInfo.get(0).topActivity;
componentInfo.getPackageName();
Intent intent = Intent.makeMainActivity(componentInfo);
result.contextMain.startActivity(intent);
//myApp.getCurrentActivity().set
}
Download your data is service, not in AsyncTask
Register some BroadcastReceiver in your MainActivity in onStart(), and unregister it in onStop(). Refresh your view in this receiver
When data are downloaded, make a broadcast to call activity, that data are ready.
Disadvantage of this method is that you should save your data somewhere. You can of course pass data in the intent, but only if data are small

How to find whether activity is last activity in stack

I am opening a link in my app and once back is pressed I want to show HomePage to retain user for some more time. I have been trying to acheive this but unable to do so. I get homeLauncher activity as my top as well as baseActivity.
DeepLink Tap > Open desired Activity > user presses back button > Check if its last activity but not homeActivity > If yes, Navigate user to homeActivity.
Tried following code:
#Override
public void onBackPressed() {
ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE );
List<ActivityManager.RunningTaskInfo> taskList = mngr.getRunningTasks(10);
if(taskList.get(0).numActivities == 1 && taskList.get(0).topActivity.getClassName().equals(this.getClass().getName())){
//// This is last activity
}
else{
//// There are more activities in stack
}
super.onBackPressed();
}
I have also tried isTaskRoot but result is same. It doesn't give right answer.Please help
Use isTaskRoot() method. (From a h9kdroid comment - here)
#Override
public void onBackPressed() {
ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE );
List<ActivityManager.RunningTaskInfo> taskList = mngr.getRunningTasks(10);
if(isTaskRoot()){
//// This is last activity
} else{
//// There are more activities in stack
}
super.onBackPressed();
}
You could simply use the ActivityManager it keeps track of which activity is and is not here is a piece of code I stumbled on that I use always:
ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE );
List<ActivityManager.RunningTaskInfo> taskList = mngr.getRunningTasks(10);
if(taskList.get(0).numActivities == 1 &&
taskList.get(0).topActivity.getClassName().equals(this.getClass().getName())) {
Log.i(TAG, "This is last activity in the stack");
}
Quoting From ActivityManager.RunningTaskInfo
Information you can retrieve about a particular task that is currently
"running" in the system. Note that a running task does not mean the
given task actually has a process it is actively running in; it simply
means that the user has gone to it and never closed it, but currently
the system may have killed its process and is only holding on to its
last state in order to restart it when the user returns.
String getLastOpenClass ;// Global
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
componentInfo.getPackageName();
getLastOpenClass=taskInfo.get(0).topActivity.getClassName();
if(getLastOpenClass.equals("Your_Class_Name"))
{
}else{
}
Give permission
<uses-permission android:name="android.permission.GET_TASKS" />
The ActivityManager keeps a record of the runnings task and the topmost task .
ActivityManager mngr = (ActivityManager) getSystemService( ACTIVITY_SERVICE );
List<ActivityManager.RunningTaskInfo> taskList = mngr.getRunningTasks(10);
if(taskList.get(0).numActivities == 1 && taskList.get(0).topActivity.getClassName().equals(this.getClass().getName()))
{
Log.i(TAG, "This is Last activity in the stack");
}
Courtesy How to check if an activity is the last one in the activity stack for an application?
Please Check How can I get the current foreground activity package name
http://developer.android.com/intl/es/reference/android/app/ActivityManager.html#getRunningTasks%28int%29
Please note that the below solution will only work on API14+.
Create a custom application class;
public class App extends Application {
private int created;
#Override
public void onCreate() {
registerActivityLifecycleCallbacks(new Callbacks());
}
public int getCreated() {
return created;
}
private class Callbacks implements ActivityLifecycleCallbacks {
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
created++;
}
#Override
public void onActivityDestroyed(Activity activity) {
created--;
}
}
}
Register it in your AndroidManifest.xml in the application element;
<application name=".App"/>
And in your activity opened through a deep link use the following piece of code;
#Override
public void onBackPressed() {
if (((App) getApplicationContext()).getCreated() == 1) {
// start your home activity
}
super.onBackPressed();
}
I wrote this off the top of my head so I haven't had a chance to test it, but theoretically it should work.
Specify parent activity for desired Activity, like :
<activity
android:name=".DesiredActivity"
android:parentActivityName="com.packagename.HomePage" >
<!-- The meta-data element is needed for versions lower than 4.1 -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.packagename.HomePage" />
</activity>
With the parent activity declared, you can use the NavUtils APIs to
synthesize a new back stack by identifying which activity is the
appropriate parent for each activity.
override onBackPressed as :
#Override
public void onBackPressed() {
Intent intent = NavUtils.getParentActivityIntent(this);
startActivity(intent);
super.onBackPressed();
}
Android developer's site has a very good resource for same problem. Please refer to link http://developer.android.com/training/implementing-navigation/temporal.html#SynthesizeBackStack

how to check the top activity from android app in background service

In my app i want to check whethere any other app launches or not from my app.So i am currently usimg Activitymanager to find the top activity like this
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1);
Log.d("topActivity", "CURRENT Activity ::"
+ taskInfo.get(0).topActivity.getClassName());
ComponentName componentInfo = taskInfo.get(0).topActivity;
componentInfo.getPackageName();
But i want to run this code in background service.So that i can detect When other app launches through this.So is there any idea to do this.Plz help me.thanks
By using service you can achieve this..
public void checkActivity() {
handler = new Handler();
activityRunnable = new ActivityRunnable();
handler.postDelayed(activityRunnable, 500);
}
private class ActivityRunnable implements Runnable {
#Override
public void run() {
ActivityManager manager = (ActivityManager) getApplicationContext()
.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> runningTasks = manager.getRunningTasks(1);
if (runningTasks != null && runningTasks.size() > 0) {
ComponentName topActivity = runningTasks.get(0).topActivity;
// Here you can get the TopActivity for every 500ms
if(!topActivity.getPackageName().equals(getPackageName())){
// Other Application is opened
}
handler.postDelayed(this, 500);
}
}
}
Call the checkActivity() in onCreate of service and dont forgot to remove the handler.removeCallbacks(activityRunnable); callbacks in onDestroy
start the service in LauncherActivity onCreate and stop the service in LauncherActivity onDestroy
Note: Dont forgot to add the permission in your manifest
<uses-permission android:name="android.permission.GET_TASKS" />
You should use Service for this. Then only you can achieve the background process..Please Go through about Services http://developer.android.com/guide/components/services.html and you can see this also http://www.vogella.com/articles/AndroidServices/article.html both URLs will help you
instead of service Use receiver to receive the launch event
and there you can implement this code.
The approach you are taking is wrong and prone to have your app rejected from the Google Play Store (plus it may stop working).
Check this thread to see possible ways to detect wether your app went to the background or not.

repeatedly checking whether the application is in foreground or background

I want to detect when the app comes from back ground to foreground every time.
I'm geting the state using the following code
topActivity.getPackageName().equals(context.getPackageName())
But I need to execute the code repeatedly so that I could detect every time when my app comes to foreground
It's your app. Activity always knows if it is visible or not. So make every your activity tell someone it's state. You don't need to poll app state. Check this answer.
Try this :
public static String isApplicationSentToBackground(final Context context) {
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
if (topActivity.getPackageName().equals(context.getPackageName())) {
return "true";
}
}
return "false";
}
Hope this helps.

Categories

Resources