Android - getRunningservices(ActivityManager) deprecated - java

I want to know MyService.java is working or not?
I create this method:
private boolean isServiceAlive(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
it works fine but manager.getRunningServices() is deprecated from API 26. So have we another good solution(method) to get a list of the services that are currently running?

Despite it doesn't answer your question, I think you still can use this method for your own services:
For backwards compatibility, it will still return the caller's own services.
If you'd just like to remove the deprecation warning, use #SuppressWarnings("deprecation")

Welcome to Android O
Another Annoying bug of android Oreo, there is just Deprecated annotation and there is no other way to do this. but maybe in the past android developers decide to create alternative function.
For now as Document says continue to use getRunningServices and use #SuppressWarnings("deprecation") above of your function to get rid of warning.
As of Build.VERSION_CODES.O, this method is no longer available to third party applications. For backwards compatibility, it will still return the caller's own services.

Here's what you do. If the services you are using are within your own application, just make a singleton that has a boolean variable for started or stopped. When the service starts, make sure to update that variable.
public class SingletonServiceManager {
public static boolean isMyServiceRunning = false;
}
The above is literally all i use for a small singleton class, later, in some other class, where you want to know if the service is running...
if(SingletonServiceManager.isMyServiceRunning == true){
// do something
}
You just have to manage where and when this value is updated. For instance, set it to true when you start the service (inside the service). Then, update the boolean to false when you stop the service (from inside the service)

Related

Ensure Android app runs in a single process

We've recently started running into crashes in our Android app due to the app being open in multiple processes. Several different errors point towards that. For instance this error:
com.google.firebase.database.DatabaseException: Failed to gain
exclusive lock to Firebase Database's offline persistence. This
generally means you are using Firebase Database from multiple
processes in your app. Keep in mind that multi-process Android apps
execute the code in your Application class in all processes, so you
may need to avoid initializing FirebaseDatabase in your Application
class. If you are intentionally using Firebase Database from multiple
processes, you can only enable offline persistence (i.e. call
setPersistenceEnabled(true)) in one of them.
We are also seeing similar errors from SQLite and H2. This is a new issue and we have not explicitly allowed multiple processes to run. Nothing in our AndroidManifest.xml specifies a custom android:process attribute.
I suspect that some third party library is causing this. How do I identify the root cause of the multiple processes and how do I prevent it?
Another of our apps is connecting to this app via a ContentProvider. At first I thought that it having android:multiprocess="true" was the culprit but changing it to "false" did not help. I still suspect that the other app is somehow triggering the creation of a new process. This is how to the ContentProvider is defined:
<provider
android:name=".DegooContentProvider"
android:authorities="${applicationId}.DegooContentProvider"
android:exported="true"
android:protectionLevel="signature"
android:multiprocess="false">
</provider>
You can check in your applicaition class if there is foreign process. Here is an example:
public class MyApp extends Application {
#Override
public void onCreate() {
super.onCreate();
if (!isMainProcess()) {
// Do not call thread unsafe logic. Just return
return;
}
// Thread unsafe logic.
...
}
private boolean isMainProcess() {
int pid = android.os.Process.myPid();
ActivityManager manager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
String currentProcName = processInfo.processName;
if (processInfo.pid == pid) {
if (TextUtils.equals(currentProcName, BuildConfig.APPLICATION_ID)) {
return true;
}
}
}
return false;
}
}
Looks like you are calling the method setPersistenceEnabled() multiple times.
Ensure it is not. You can do this in a several ways.
The preferred method will be to place it only in the onCreate() method of the default Application class if you are extending one.
Another solution will be to place it in the static block of any class.
static {
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
}
Or you can even set a static boolean variable say, inFirebaseInstanceInitialized and call setPersistenceEnabled() only if it is not true already.

Unable to use the insert method in google app engine endpoints

I'm building an android app that access a server. I'm using a full google solution. The backend is in GAE and I'm using endpoints to expose my API, I'm also using GCM. I use the auto generate tools that are offered by android studio to get my classes.
In my app module I have a class called offer, this is where I put data to be sent to the server, I have also an AsyncTask class that allows to make the api call.
In my backend module I have the exposed API and I also I have a class offer from which the API is generated by android studio and app engine sdk.
Now my problem is I made an attempt, but it resulted in failure, its like the classes in app and backend are not compatible. Whereas they are the same, in fact the one in backend is a simple copy from the one in app, the difference is the "objectify" annotation that I added. Below are pieces from my code and screenshots of my project structure.
public class InsertOfferAsyncTask extends AsyncTask <Offer, Void, Boolean>{
private static OfferApi offer_service;
private Context context;
public InsertOfferAsyncTask(Context context) {
this.context = context;
}
protected Boolean doInBackground(Offer... offer) {
if (offer_service == null) {
OfferApi.Builder builder = new OfferApi.Builder(AndroidHttp.newCompatibleTransport(), new AndroidJsonFactory(), null)
.setRootUrl("https://flawless-snow-95011.appspot.com/_ah/api/");
offer_service = builder.build();
}
try {
offer_service.insert(offer[0]); //this where I make the actual API call, I know I shouldn't use Object, it was an attempt to make it work
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
This is a part from where I call the AsyncTask, which is the code above.
Log.i("offer", offer.getUsr_id());
Log.i("offer_id", String.valueOf(offer.getId()));
Log.i("offer_date", offer.getPost());
new InsertOfferAsyncTask(getActivity().getBaseContext()).execute(offer);
getActivity().finish();
All the code above is taken from my app module, the following is the endpoint code that code generated, I am posting only the part I make a call to.
#ApiMethod(
name = "insert",
path = "offer",
httpMethod = ApiMethod.HttpMethod.POST)
public Offer insert(Offer offer) {
ofy().save().entity(offer).now();
logger.info("Created Offer with ID: " + offer.getId());
return ofy().load().entity(offer).now();
}
What I need now is how I can use what I have to send my data to the server. I know that I can connect to the server, I tested.
This is the error message, that i get when I try to build.
Error:(233, 73) error: no suitable method found for execute(.model.Offer)
method AsyncTask.execute(Runnable) is not applicable
(actual argument .model.Offer cannot be converted to Runnable by method invocation conversion)
method AsyncTask.execute(backend.model.offerApi.model.Offer...) is not applicable
(argument type app.model.Offer does not conform to vararg element type backend.model.offerApi.model.Offer)
Any help?? should I use JSON (I doubt, the job is done by the auto-generated classes, as it is shown in the builder)
Could it be that you are using two different "Offer" objects
app.model.Offer and backend.model.offerApi.model.Offer?
The type backend.model.offerApi.model.Offer appears to be the one generated for your Endpoints API, you need to use that type everywhere on the client (android) side.
I believe that you should create a separate project that contains all classes that are shared between the android app and your api.

Scope issues with Rhino [duplicate]

I'm trying to ensure that my Rhino scripts (running under Java 6) are strict so that if a script developer misspells an expression I want an exception to be thrown. Currently what happens is the expression simply evaluates to "undefined".
Now according to Mozilla org https://developer.mozilla.org/en/New_in_Rhino_1.6R6 there are features to enable strict checking in the context. I cannot find a working example of this.
What I did so far was write a class to extend ContextFactory and then override the hasFeature method.
public class ScriptContextFactory extends ContextFactory {
protected boolean hasFeature(Context context, int featureIndex) {
switch (featureIndex) {
case Context.FEATURE_STRICT_EVAL:
return true;
case Context.FEATURE_STRICT_VARS:
return true;
}
return super.hasFeature(context, featureIndex);
}
}
Then in the Main I set mine to the default.
ContextFactory.initGlobal(new ScriptContextFactory());
and I get an illegal state exception. :(
Any ideas or samples on how this works?
TIA
If you are doing Context.enter() before calling initGlobal() try reversing the order.

Android: how to intercept when a Service runs for the first time

Hi and thanks for your help.
I have the following situation.
I have an AlarmManager that fires off a Service every 1 minute.
I have to execute a specific method in that Service only when the Service is started for the first time. not when it starts the subsequent times.
I do not think shared preferences is a solutions, because they are persisted if the phone is switched off.
Please how do I solve this ??
Thank you for any suggestion!!!
Try inheriting form the App and store in it..
public class YourApp extends Application {
private static boolean mFirstRun = false;
public static boolean getFirstRun() { return mFirstRun; }
public static void clearFirstRun() { mFirstRun = false; }
from your service:
if (YourApp.getFirstRun())
{
clearFirstRun();
// run first time code
}
You can call it in onCreate(). See here in the official documentation. It says:
Called by the system when the service is first created. Do not call this method directly.
For your reference you can see the question When does Application's onCreate() method get called? and If android restarts a Service is onCreate called again?

When should I use unbindService(), and how should I use it properly to unbind from a remote service that is using an AIDL interface?

I'm writing a simple music player, and I've created a playback service which implements an AIDL interface to bind with the clients, one a simple track browser and the other an even simpler player activity. The service controls the MediaPlayer object while the two activities use ServiceConnections to obtain connections to the service.
This is included in the onStart() methods of both activities:
#Override
public void onStart()
{
super.onStart();
Intent i = new Intent(this, PureService.class);
startService(i);
bindService(i, mConnection, 0);
}
I did this so that the service would not immediately stop upon unbinding. Of course, that hasn't actually been a problem because my activity refuses to unbind from the service at all. Anytime my application gets to unbindService in either of these activities, unbindService throws IllegalArgumentException every time, without exception (hehe).
In the onStop methods:
#Override
public void onStop()
{
super.onStop();
if (mBound) {
try {
unbindService(mConnection);
} catch (java.lang.IllegalArgumentException e)
{
//Print to log or make toast that it failed
}
}
mBound = false;
}
What I'm wondering is this:
Should I be calling unbindService() in the onStop() method? Or at all?
Am I calling it correctly?
Is there anything peculiar about the way I'm starting/binding the service that I should know about?
Am I doing something utterly, completely wrong? I'm new to android programming so that's certainly not out of the question.
Thanks in advance.
EDIT: Here are the ServiceConnection overrides
public void onServiceConnected(ComponentName className, IBinder service) {
mBound = true;
mService = IPureService.Stub.asInterface(service);
}
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
There's some additional code in the player activity, but it's unrelated to the binding itself.
First, unless you actually need to make calls to this service across processes (that is, from other .apks, or you are using android:process to split up your own .apk into multiple processes for some reason), then I really recommend just dropping the use of aidl. It is more complexity for no gain. The "Local Service Sample" in the Service documentation shows how to do this: http://developer.android.com/reference/android/app/Service.html
Second, doing a bind at the same time as a start is a strong indication of some basic flaw in the design. Starting a service and binding to a service are semantically very different, so will be done at different places based on those different semantics. That is, if both are even done at all... in fact it is an unusual situation where you are using both start and bind with the same service.
In the class implementation of a service for doing music playback, it would use start when it is actively performing playback (so its process doesn't get killed by the system when the user is no longer actively interacting with the application's UI). Starting the service when the user has enters the UI is likely to cause pain because now the start/stopped state of the service is not clearly defined -- it could be started either because it is doing playback or because the user happens to have gone into the app's UI, and now when is the right time to stop it? This is going to be troublesome.
Now as far as when to unbind -- you just need to make sure you always match an unbindService() with a previous bindService(). From your snippets of code it looks like you are doing this, but there are strange things in it like mBound never being set. In fact if you are consistently binding in onStart() and unbinding in onStop(), you should never need to have an mBound to decide whether to unbind, because onStop() is always called after onStart().
So with the code you give here, it doesn't look like there is a problem. If you are getting exceptions, though, there clearly is so it may be elsewhere in your app. To help narrow the problem down, you can use this flag when you call bindService() to get additional information in the log when the failure happens: http://developer.android.com/reference/android/content/Context.html#BIND_DEBUG_UNBIND
A couple of points:
Return START_STICKY in onStartCommand if you want your Service to live longer than the bound Activities.
unbindService() in onStop is fine: this is where I call it in multiple apps and I've never seen that particular error. I expect you have some other issue with your ServiceConnection: show the code for your mConnection object and we can probably figure out what's wrong with it.
I had this weird error as well. Then I tried doing the bind to the service in onResume() instead of in onStart() in the Activity, and voila, no more exceptions! I am still a bit clueless as to why this works. If someone could explain, I'd be one happy coder. :)

Categories

Resources