I am trying to create the below posted method to check if a service is running or not. but getSystemService() is markd with red because it is not defined
and it needs a context. I used the following:
Application.getContext().getSystemService
but still getContext is not defined.
in the code i do the following:
if (ServicesUtils.isServiceRunning(NonStickyService.class.getSimpleName())) {
Log.i(TAG, "++++++++++ SERVICE IS RUNNING +++++++++");
} else {
Log.i(TAG, "++++++++++ SERVICE IS NOT RUNNING +++++++++");
}
please let me know which context i should use.
code1:
public class ServicesUtils {
private static String LOG_TAG = ServicesUtils.class.getName();
public static boolean isServiceRunning(String serviceClassName) {
final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
final List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);
for (ActivityManager.RunningServiceInfo runningServiceInfo : services) {
if (runningServiceInfo.service.getClassName().equals(serviceClassName)) {
return true;
}
}
return false;
}
}
code2:
public class App extends Application {
public static com.example.pc_amr.stickyvsnonstickyservice.App instance;
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static com.example.pc_amr.stickyvsnonstickyservice.App getInstance() {
return instance;
} // get the instance
}
Since getSystemService is the part of the Context. And your class has no relation to context. So you have to make an Object of the Context and then you can use context.getSystemService.And make sure to pass the value of context using a constructor to avoid NPE.
You can do something like this
public static boolean isServiceRunning(String serviceClassName,Context context) {
final ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
Try creating a static instance of your Application class:
public class App extends Application {
public static App instance;
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static App getInstance() { return instance; } // get the instance
}
Now if you need context you can simply use App.getInstance(). As we know Application class extends Context.
Remember to register App class
Related
To get context, I use:
Context context = InstrumentationRegistry.getInstrumentation().getContext();
But I didn't found any method like getApplicationContext();
Any leads would be appreciated
Try this way:
Your_Activity.this
Or you can create a public static method to get the Context:
public class App extends Application {
private static Application sApplication;
public static Application getApplication() {
return sApplication;
}
public static Context getContext() {
return getApplication().getApplicationContext();
}
#Override
public void onCreate() {
super.onCreate();
sApplication = this;
}
}
Or get it through a View, using Your_View.getContext()
Hope this help
I have a activity in which in onCreate method I have to check whether activity is in foreground or background .if activity is in foreground then I have to send request to to server and if app goes in background then I have to send that server request through Intent service.How can I do that.
Is there any way if app goes in background stop server request which is in foreground .
Try This for check your app is in foreground or not
public static boolean isAppInForeground(Context ctx) {
ActivityManager activityManager = (ActivityManager) ctx
.getApplicationContext().getSystemService(
Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> services = activityManager
.getRunningTasks(Integer.MAX_VALUE);
if (services == null) {
return false;
}
if (services.size() > 0
&& services.get(0).topActivity
.getPackageName()
.toString()
.equalsIgnoreCase(
ctx.getApplicationContext().getPackageName()
.toString())) {
return true;
}
return false;
}
Track visibility of your application by yourself using Activity.onPause, Activity.onResume methods.
Example Implement custom Application class :
public class MyApplication extends Application {
public static boolean isActivityVisible() {
return activityVisible;
}
public static void activityResumed() {
activityVisible = true;
}
public static void activityPaused() {
activityVisible = false;
}
private static boolean activityVisible;
}
Register your application class in AndroidManifest.xml
and then so something like this :
#Override
protected void onResume() {
super.onResume();
MyApplication.activityResumed();
}
#Override
protected void onPause() {
super.onPause();
MyApplication.activityPaused();
}
The best approach would be you should trigger your service in onStop() call of your activity, as the service gets start your logic in onStatCommand() will be execute and if you want your service should not be dependent on app lifecycle return START_STICKY with in onStatCommand().
Here is a solution using Application class.
public class AppSingleton extends Application implements Application.ActivityLifecycleCallbacks {
private WeakReference<Context> foregroundActivity;
#Override
public void onActivityResumed(Activity activity) {
foregroundActivity=new WeakReference<Context>(activity);
}
#Override
public void onActivityPaused(Activity activity) {
String class_name_activity=activity.getClass().getCanonicalName();
if (foregroundActivity != null &&
foregroundActivity.get().getClass().getCanonicalName().equals(class_name_activity)) {
foregroundActivity = null;
}
}
//............................
public boolean isOnForeground(#NonNull Context activity_cntxt) {
return isOnForeground(activity_cntxt.getClass().getCanonicalName());
}
public boolean isOnForeground(#NonNull String activity_canonical_name) {
if (foregroundActivity != null && foregroundActivity.get() != null) {
return foregroundActivity.get().getClass().getCanonicalName().equals(activity_canonical_name);
}
return false;
}
}
If you have a reference to the required Activity or using the canonical name of the Activity, you can find out whether it's in the foreground or not. This solution may not be foolproof. Therefore your comments are really welcome.
Check this library. It can ctrack current activity status.
I am trying to create a global variable where it can be accessed from any any where including Activity, Fragment and other custom classes.
public class Global extends Application {
private static Global sInstance;
private String mSharedInfoFileName; //can be any custom object
public static Global getInstance() { return sInstance; }
#Override
public void onCreate() {
super.onCreate();
sInstance = this;
initialize();
}
private void initialize() { mSharedInfoFileName = "globalInfo"; }
public String getFileName() { return mSharedInfoFileName; }
private Global() { }
}
and try to use it like this
public class MyFragment extends android.support.v4.app.Fragment {
String s = Global.getInstance().getFileName();
}
even after declaring it in class scope still gave same error
private static Global mGlobal = Global.getInstance();
which give me Attempt to invoice... .Global.getFileName()' on a null object reference. What am I missing?
Thank you
Change this method to static :
public static String getFileName() {
return mSharedInfoFileName;
}
and call it like below:
Global.getFileName();
The mSharedInfoFileName variable has to be static too :
private static String mSharedInfoFileName;
In my Android Application, I store the Launcher activity (called MainActivity) in a static variable inside the MainActivity class;
And I am using this static Activity reference to get the application resource, preference and others;
But sometimes, I found that the app is crashed because the object reference is null;
Is there any reason causing the object reference become NULL?
How to prevent this kind of NullPointerException?
My Codes:
MainActivity:
public class MainActivity extends Activity {
private static MainActivity sInstance = null;
public static MainActivity getInstance() {
return sInstance;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sInstance = this;
// other code
}
}
Helper.java:
public static int getColor(int resID) {
return MainActivity.getInstance().getColor(resID);
}
//For this type of issue, please use application class object. If you used Activity class then when //activity destroys then it will become null. So you got the null pointer exception.
public class MyApplication extends Application {
public static MyApplication myApplication = null;
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
myApplication = (MyApplication) getApplicationContext();
}
public static MyApplication getInstance() {
return myApplication;
}
}
//Your method looks like this
public static int getColor(int resID) {
return MyApplication.getInstance().getResources().getColor(resID);
}
Per the Android Documentation it states:
There is normally no need to subclass Application. In most situation,
static singletons can provide the same functionality in a more modular
way. If your singleton needs a global context (for example to register
broadcast receivers), the function to retrieve it can be given a
Context which internally uses Context.getApplicationContext() when
first constructing the singleton.
How do I go about creating a static singleton that has global context so that it survives the running activity changing in my app? Is it enough to have a static context which references the getApplicationContext()?
Another edit to the question (2016)
Lately (as of 2016 and onward) what I've been doing, and would be my suggestion for any developer, is:
Just use Dagger 2. Wherever you need a Context you do:
#Inject Context context;
and that's it. While at it, inject all the other stuff that would be a singleton.
Edited/improved answer (2014)
because this answer is getting kinda-of popular, I'll improve my own answer with example code of what I've been using lately (as of Jul/2014).
Start by having the application keeping a reference to itself.
public class App extends Application {
private static App instance;
public static App get() { return instance; }
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
}
then on any singleton that needs access to the context I lazy load the singles in a thread safe manner using double check synchronization as explained here https://stackoverflow.com/a/11165926/906362
private static SingletonDemo instance;
public static SingletonDemo get() {
if(instance == null) instance = getSync();
return instance;
}
private static synchronized SingletonDemo getSync() {
if(instance == null) instance = new SingletonDemo();
return instance;
}
private SingletonDemo(){
// here you can directly access the Application context calling
App.get();
}
Original answer
what the documentation is suggesting is to use a normal singleton pattern
public class SingletonDemo {
private static SingletonDemo instance = null;
private SingletonDemo() { }
public static SingletonDemo getInstance() {
if (instance == null) {
instance = new SingletonDemo ();
}
return instance;
}
}
and include inside it a method like this:
private Context context;
init(Context context){
this.context = context.getApplicationContext();
}
and remember to call this to initialise the singleton.
The difference between the Application approach and the Singleton approach and why the Singleton is better is on the documentation same functionality in a more modular way
I have such class in my application :
public class ApplicationContext {
private Context appContext;
private ApplicationContext(){}
public void init(Context context){
if(appContext == null){
appContext = context;
}
}
private Context getContext(){
return appContext;
}
public static Context get(){
return getInstance().getContext();
}
private static ApplicationContext instance;
public static ApplicationContext getInstance(){
return instance == null ?
(instance = new ApplicationContext()):
instance;
}
}
and then for example in Launch Activity initialize it :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//init
ApplicationContext.getInstance().init(getApplicationContext());
//use via ApplicationContext.get()
assert(getApplicationContext() == ApplicationContext.get());
}