I am implementing push notification and so far it works fine. I manage to get push notification and when I click on that able to start activity.
But I don't want to notify user about notification if app is already running. This how I am planning to do this...but not sure is this correct way
Intent actIntent = new Intent(this, MainActivity.class);
actIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, actIntent, 0);
if (!isActivityRunning())
mNotificationManager.notify(0, notification);
public boolean isActivityRunning(Context ctx) {
ActivityManager activityManager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
for (RunningTaskInfo task : tasks) {
if (ctx.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName()))
return true;
}
return false;
}
isActivityRunning function will basically checks whether MainActivity is running or not. If it is in running state then won't show notification and will pass information to activity itself to update UI. If activity is not running on click of notification MainActivity will open.
Is this right way of achieving this?
Using the activity manager doesn't exactly work as expected. The activity manager keeps a track of all the running apps on the phone. It doesn't really tell you whether the app is in foreground or background. To check whether the activity is running, set a boolean value in the onResume and onPause method of the activity.
Example:
public void onResume()
{
super.onResume();
isActivityRunning = true;
}
public void onPause()
{
super.onPause();
isActivityRunning = false;
}
You can then use the isActivityRunning to see if you want to throw the notification or not.
Also see this: Checking if an Android application is running in the background
I use this code to know if app is running:
private boolean isActivityRunning() {
if (MainActivity.getInstance() != null) {
return true;
} else {
return false;
}
}
And in MainActivity
public static MainActivity getInstance() {
return mInstance;
}
in onCreate I assign mInstance:
mInstance = this;
in onDestroy:
mInstance = null;
I use checking of mInstance because I use it in different activities for checking or for using some methods from MainActivity, so for me no need to create new boolean var.
Related
In the app having background service running, periodical it will trigger some event that app needs to show an activity.
The issue is if that activity is already on top how to not open another one.
The following snippet whenever the event is triggered, the showAlertActivity() will try to open the activity (it is not just a alert).
Any way to check if there is one has been opened? Thanks!
public void showAlertActivity(String title, String msg……) {
// this does not work, throws a exception
//“ava.lang.SecurityException: Permission Denial: getTasks() from pid=24139, uid=10048 requires android.permission.GET_TASKS”
ActivityManager mngr = (ActivityManager) mContext.getSystemService( Activity.ACTIVITY_SERVICE );
List<ActivityManager.RunningTaskInfo> taskList = mngr.getRunningTasks(10);
for (ActivityManager.RunningTaskInfo info: taskList) {
Log.d(“+++ info.numActivities:" + info.numActivities +", info.topActivity.getClassName():"+info.topActivity.getClassName()+", info.baseActivity:"+info.baseActivity.getClassName());
}
Intent intent = new Intent(mContext, TheAlertActivity.class);
dialogIntent.putExtra(Constants.LAYOUT_RESOURCE_ID, R.layout.alert_form);
dialogIntent.putExtra(Constants.TILTLE, title);
dialogIntent.putExtra(Constants.TEXT, msg);
……
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
Add something along the lines of this to your Activity you want to check and isOpen will tell you if it is currently on top.
public static boolean isOpen = false;
private static int countOpen = 0;
public void onStart() {
super.onStart();
countOpen++;
isOpen = countOpen > 0;
}
public void onStop() {
super.onStop();
countOpen--;
isOpen = countOpen > 0;
}
The count is added to secure the boolean being correct even if you open the activity for some reason in front of itself and the system sometimes calling the new activities onStart() before the old activities onStop().
I created a boolean to check if a service is running, if it is running I want it to show linearlayoutA and if it is not running I want it to show another linearlayoutB.
The problem is this, it shows the right linear layout when I start the activity, if the service is running it shows linearlayoutA if its not running it shows linearlayoutB but when I start the service in the activity it shows linearlayoutB and does not change to A even when the service as stopped until I close the application and open it. method for checking
public boolean isRunning(Class<? extends Service> serviceClass) {
final Intent intent = new Intent(TimerActivity.this, serviceClass);
return (PendingIntent.getService(TimerActivity.this, CODE, intent, PendingIntent.FLAG_NO_CREATE) != null);
}
This is how I call it in onCreate of the activity
if(isRunning(TimerLocationService.class)){
setWaitScreen(true);
}else{
setWaitScreen(false);
}
try this.
private Boolean isServiceRunning(String serviceName) {
ActivityManager activityManager = (ActivityManager) getSystemService(Activity.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo runningServiceInfo : activityManager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceName.equals(runningServiceInfo.service.getClassName())) {
return true;
}
}
return false;
}
I hope this is helpful for you.
I am working in application that needs make a synchronization every night. I use Alarm Manager that calls a BroadcastReceiver at the hour that I want. The problem is that I cant make a synchronization if the application is running in foreground to avoid losing data. So I need to know in Broadcast Receiver if the app is running in foreground to cancel this synchronization.
I tried solutions that I found in StackOverflow:
Checking if an Android application is running in the background
But this parameter is always false in BroadcastReceiver, but true in activites.
Can anyone tell me which is the problem? What am I doing bad?
Really thanks!
Try this way hope this works for you
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (isAppForground(context)) {
// App is in Foreground
} else {
// App is in Background
}
}
public boolean isAppForground(Context mContext) {
ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> tasks = am.getRunningTasks(1);
if (!tasks.isEmpty()) {
ComponentName topActivity = tasks.get(0).topActivity;
if (!topActivity.getPackageName().equals(mContext.getPackageName())) {
return false;
}
}
return true;
}
}
Add this permission
<uses-permission android:name="android.permission.GET_TASKS" />
What do you mean by "the application is running in foreground"?
If you mean there is an Activity currently displayed on the screen, then the easiest way would be to make a base Activity class that sets a global boolean in your `Application' class.
Custom Application class:
public class MyApp extends Application
{
public boolean isInForeground = false;
}
Custom base Activity class:
abstract public class ABaseActivity extends Activity
{
#Override
protected void onResume()
{
super.onResume();
((MyApp)getApplication()).isInForeground = true;
}
#Override
protected void onPause()
{
super.onPause();
((MyApp)getApplication()).isInForeground = false;
}
}
I assume you are not synchronising from your BroadcastReceiver - you should instead be launching a Service to do the synchronisation. Otherwise the system might kill your app - you must not be doing any long-running tasks in a BroadcastReceiver.
So before you launch your sync service, check the application boolean to see if your app is "in foreground". Alternatively, move the check inside the sync service, which has the advantage of making the BroadcastReceiver even simpler (I am always in favour of trying to make the receivers have as little logic as possible).
This method has the advantages that it is simple to use, understand, and requires no extra permissions.
in case you don't want to do anything if app in foreground you could simply turn off the receiver on your activity onStart method:
ComponentName receiver = new ComponentName(context, MyReceiver.class);
context.getPackageManager().setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
and you could turn it on onStop method:
ComponentName receiver = new ComponentName(context, MyReceiver.class);
context.getPackageManager().setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
and if receiver is turned off, no alarms will come to it, and your code will not be executed
That method tells you whether any of your activities in your app are currently in the foreground. If you check your MyApplication.isActivityVisible() method from the broadcast receiver, then that should work fine. If its returning false, then maybes no activities are showing.
I'm developing a service that need to run foreground, and users can toggle it on/off through an activity. So basically, the activity MAY be killed, but the service is safe as long as it is not stopped by user.
However, I'm getting this trouble: how to turn off the service if it is on? That mean, if my activity was killed, then restarted, so I get no reference of the started service intent to call stopService.
Below is my current code. It works fine if the user call deactivate after the service is started by the same activity. The button status is always correct, but when my activity is restarted by the OS, this.serviceIntent is null.
protected boolean isServiceRunning() {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (SynchronizationService.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
#Override
protected void onResume() {
super.onResume();
this.togglingByCode = true;
this.butActivate.setChecked(this.isServiceRunning());
this.togglingByCode = false;
}
public void onActivateButtonClick(final boolean pIsChecked) {
if (this.togglingByCode) { return; }
if (pIsChecked) {
this.saveSettings();
this.serviceIntent = new Intent(this, SynchronizationService.class);
this.serviceIntent.putExtra(KEY_WEBSERVICE, this.txtWebService.getText().toString());
this.serviceIntent.putExtra(KEY_PASSWORD, this.txtPassword.getText().toString());
this.serviceIntent.putExtra(KEY_INTERVAL, Integer.parseInt(this.txtRefreshInterval.getText().toString()));
this.serviceIntent.putExtra(KEY_TIMEOUT, this.preferences.getInt(KEY_TIMEOUT, DEFAULT_TIMEOUT));
this.serviceIntent.putExtra(KEY_RETRY, this.preferences.getInt(KEY_RETRY, DEFAULT_RETRY));
this.startService(this.serviceIntent);
} else {
this.stopService(this.serviceIntent);
this.serviceIntent = null;
}
}
Please tell me how to stop the service correctly. Thank you.
P.s: I know a trick that make serviceIntent static, but I don't feel safe about it. If there is no any other way, then I will use it.
Simply initialize your serviceIntent in the activity's onCreate... You can start your service, kill your activity, reopen it and stop the service with the same serviceIntent.
I have an app, which contains two activities and a service and a reciever, service is used to get the location updates all the time, i will start the service in the reciever for the first time, my requirement is, i need to stop the service when my application is in foreground (running), and i need to start the service when i application is stopped. among two activities initActivity is the first activity that get launched when application starts, and the homegridActivity id the second activity, i am giving the option in homegridactivity to exit from the application. below is the code where i am starting the service and stoping the service.
class initActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.app);
System.out.println("VANDROID service status inside oncreate of init" );
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if ("com.vaayoo.android.service.VLocationFetchService".equals(service.service.getClassName())) {
Intent intent = new Intent( VUiHelper.getInstance().getApplicationContext(), VLocationFetchService.class);
boolean result = ((Vandroid)VUiHelper.getInstance().getApplicationContext()).stopService(intent);
System.out.println("VANDROID service status" + result);
manager = null;
}
}
}
}
//second Activity
Class HomeGridActivity extends Activity
{
protected void onDestroy() {
super.onDestroy();
System.out.println("Homegrid activity onDestroy called");
VUiHelper.getInstance().clearControlCache();
ActivityManager manager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if ("com.vaayoo.android.service.VLocationFetchService".equals(service.service.getClassName())) {
Intent intent = new Intent( VUiHelper.getInstance().getApplicationContext(), VLocationFetchService.class);
ComponentName compname =((Vandroid) VUiHelper.getInstance().getApplicationContext()).startService(intent);
System.out.println("COMPONENT NAME" + compname.toString() );
manager = null;
}
}
}
}
I am stoping the service in oncreate on the initactivity and starting the same service in ondestroy of homegridActivity, the problem i am facing is, this is working only for the first time, if i close and launch the app multiple times, service is not stoping and starting, i found that, the service is running all the time. i have made that service as start_sticky so that is should not be killed by android runtime at any point of time, i should have full control on that service to stop and start. not able to find out why it is not working all the time, why it is working only for the first time. what i am doing wrong ? how to troubleshoot this? is it because of making service as start_sticky?
This method is return true or false means.when service is ruuning than reture true otherwise false. so you can use this method when r you use just like this.
private boolean isMyServiceRunning() {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager
.getRunningServices(Integer.MAX_VALUE)) {
if ("packagename".equals(service.service
.getClassName())) {
return true;
}
}
return false;
}
and check like that.
if (isMyServiceRunning()) {
stopService(new Intent(A.this, MusicService.class));
}