I have an network app which uses a service to connect to other peers. When you close the application using "Recent apps" it will just close the process and not the service which is actually not bad for I want to be in this way. But it makes a little trouble next time user opens the app. It crashes so user has to again close the up using "Recent Apps" and then try to use the app again. The problem is definitely the running service because if I stop the service before I run it next time. It works just fine !
Actually it is strange for me because I don't start another service at the startup. I start it when user taps on a button. Anyway If it is possible the best way is to being able to use the running service, else, I just want to stop the service on start of my application.
i am new to android and I'm stuck at this point :(
Thanks for help
A service skeleton:
public class MyService extends Service {
public static final String TAG = "MyServiceTag";
...
}
This is part of the starting activity:
processStartService(MyService.TAG);
private void processStartService(final String tag) {
Intent intent = new Intent(getApplicationContext(), MyService.class);
intent.addCategory(tag);
startService(intent);
}
This is part of the stopping activity:
processStopService(MyService.TAG);
private void processStopService(final String tag) {
Intent intent = new Intent(getApplicationContext(), MyService.class);
intent.addCategory(tag);
stopService(intent);
}
Use one static object which indicate whether service is running or not.
otherwise second option I found How to check if a service is running on Android?,
if(startService(someIntent) != null) {
Toast.makeText(getBaseContext(), 'Service is already running',Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(getBaseContext(), 'There is no service running, starting service..', Toast.LENGTH_SHORT).show();
}
Related
I have a problem with registering a broadcastReceiver between my Activity and my Service which is defined in another process in my manifest.
I've tried some other tips like using handlers or ContentProvider
for communicating but it did't work as I expected, In fact I want to get the data continuously.
Here is my code in my Service:
Intent locationIntent = new Intent("LocationIntent");
locationIntent.setAction("updatedLocations");
locationIntent.setClass(getApplicationContext(), MapBoxActivity.class);
locationIntent.putExtra("list",updatedList);
sendBroadcast(locationIntent);
and I register it in OnCreate of my Activity:
updatedLocationBroadcast = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Timber.tag("localB").d("registered!");
if (intent != null && intent.getAction() != null && intent.getAction().equals("updatedLocations")) {
sawLocationsList = (HashMap<Integer, MarkerItem>)intent.getSerializableExtra("list");
Timber.tag("sawL").d("updated" + sawLocationsList.toString());
}
}
};
registerReceiver(updatedLocationBroadcast , new IntentFilter("updatedLocations"));
As I expected, I wanted to see my broadcastReceiver registers and my Timber logs localB registered! which is defined in my receiver but it doesn't work.
So, What's the best way to communicate between Activity and Service defined in another process and getting data continuously???
Note : my service gets data from server but the server is not realTime so I check the data by requesting periodically to server using handlers.
but it doesn't work
That is because you over-specified your Intent. Replace:
Intent locationIntent = new Intent("LocationIntent");
locationIntent.setAction("updatedLocations");
locationIntent.setClass(getApplicationContext(), MapBoxActivity.class);
locationIntent.putExtra("list",updatedList);
sendBroadcast(locationIntent);
with:
Intent locationIntent = new Intent("updatedLocations");
locationIntent.putExtra("list",updatedList);
sendBroadcast(locationIntent);
Note, though, that any app will be able to listen to this broadcast. Consider using setPackage() on the Intent to restrict the delivery to your own app.
What's the best way to communicate between Activity and Service defined in another process and getting data continuously?
If I were forced into this process separation, I would consider a Messenger.
my service gets data from server but the server is not realTime so I check the data by requesting periodically to server using handlers.
That hasn't been a recommended pattern in years. Please use WorkManager. Or, use JobScheduler, if you are not in position to adopt WorkManager (since it is part of AndroidX). In either of those approaches, you could get rid of the second process and greatly simplify your communications.
I am having an app that has to get the location of where I am in many activities. I found this very helpful complete piece of code here. Its how to Get Current Location Using Background Service. I implemented it in my code. The first time it worked ok. The next, when it reached this if
if (mPref.getString("service", "").matches("")) {
medit.putString("service", "service").commit();
Intent intent = new Intent(getApplicationContext(), GoogleService.class);
startService(intent);
} else {
Toast.makeText(getApplicationContext(), "Service is already running", Toast.LENGTH_SHORT).show();
}
I get the message that service is already running. Why this happens? I have closed and reopened the app, why the service still running? Help pls, its very important, thank you
If you use SharedPreferences to persist the info about your Service then the info survives the app restart and so your if condition is always false (when you do mPref.commit() you save the key pair to the file).
My Android application starts a local foreground service (in the same process as my activity). The service have to stay alive, even if the system destroys the activity due low memory.
Next time a user starts the app, I need to check whether the service is running or not.
I tried to store state in public static boolean Started = false; flag in service class (I know that it is bad practice).
My activity starts in the process where service is running. I thought, that static constructor is called ones. So, I would be able to check this flag in activity. However, static data is reinitialized to defaults.
Could any one give me a cue about this behavior?
here is just an example how I restart the service when apps come forground
public void storeLastLocation() {
if (!isStoreLocationActive){
Log.d("IQ MA", "storeLastLocation() called");
String access_token = Configs.access_token;
Intent intent = new Intent(MainActivity.this, StoreLocationService.class);
intent.putExtra("access_token", access_token);
stopService(intent);
startService(intent);
isStoreLocationActive = true;
}
}
then store boolean on service is running
I noted that when I close my app definitively, the method runInBackGround of the class MultiplyTask stops working. It works when the activity is in the phase STOP or PAUSE, but when I close my app, the method finishes ( it's a loop created with a cycle while(true) {...} ).
How can for example Whatsapp send notifications though it's closed? I want to create a similar thing. Thanks!
When the app is closed, all code will stop running. If you are looking to execute while the app is open and continue executing code while the app is closed, you will want to look into using a Service.
Take a thorough look at the Service documentation and it will hopefully be what you are looking for.
Services are also killed when your app is closed, but using the START_STICKY return value you can make sure your service is restarted upon termination.
EDIT WITH MORE INFORMATION:
<service
android:name="MyService" />
Add the above to your AndroidManifest.xml
public class MyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// This is where you would place your code that you want in the background
// Putting your while loop here will make sure it runs when the app is closed
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
//TODO for communication return IBinder implementation
return null;
}
}
Create a new class with the above code.
Intent i= new Intent(context, MyService.class);
startService(i);
Call this code from your launcher Activity to start the service when the app is launched.
Hope this helps!
Asynctask is ideal for short operation which are needed to be performed in the background. Usually Asyntask is implemented as sub class of activity which is destroyed when app is close. Also It communicates with the UI thread at some points ... so It needs the activity to be in memory... For long running operation, Service is better. Some Apps notify user even when they are not running. In fact they have one or more services running in background. You can see those in your phone setting->apps menu.
Study this for more information about services.
I just recently added the capability of my app to check for updates on our local server (this app is not published in the Google Play store. It's going to be used internally and there is no internet connection where it will be used. Don't ask. That's how it is :) ). I keep track of updates by checking a certain table in SQL Server and if my app's version is lower than what is indicated in this table, I download the new APK from an internal website (LAN only) then install the APK. I also have another application in the device that listens for PACKAGE_ADDED broadcasts. I can capture the broadcast successfully.
The problem is, after installation, the broadcast receiver starts the app by calling the following.
public class PackageInstalledBroadcastReceiver extends BroadcastReceiver {
private final String MY_PACKAGE_NAME = "com.company.packagename";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)) {
String packageName = intent.getData().getSchemeSpecificPart();
if (packageName.equalsIgnoreCase(MY_PACKAGE_NAME)) {
Intent i = new Intent();
i.setClassName(MY_PACKAGE_NAME, MY_PACKAGE_NAME + ".LoginActivity");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
}
}
But it takes a long time for the app to start. The user might think that nothing is happening, so he/she can start the app manually by clicking the app's icon. If the user clicks the app's icon, the app starts immediately. After a while, the activity that the broadcast receiver started is also opened. So now, I end up with two instances of my app in the same activity (LoginActivity). I can say that this is the case, because if I press the Back key on the device from the LoginActivity, I still end up in another LoginActivity and if I press the Back key again, I end up on the device's desktop.
You have two problem in your question:
The fist, why your BroadcastReceiver take a long time to start your activity.
It have not enough information for stoving this.
The second your want to make your activity have a single instance.
Android provide a way to do that:
Step one: Visit your application androidmanifest file
Step two: Find your activity declaration.
Step there: Add the following property android:launchMode = "singleInstance"
The reference here:
P/s: If you could provide my some more information of your fist problem. Please create a new question. Hope you resolve it.