Reputation: 6093
When the user hits an icon in my app, I want the app first to check if the device is connected to the internet and then do something depending on the result it receives (for know it's just popping up a dialog, informing whether the device is connected or not). So I wrote this code:
public class MainActivity extends Activity {
// SOME CONSTANTS WILL BE DEFINED HERE
AlertDialog.Builder builder = new AlertDialog.Builder(this);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.icoMyIcon).setOnClickListener(listener);
}
private OnClickListener listener = new OnClickListener() {
public void onClick(View v) {
if (isNetworkConnected()) {
builder.setMessage("Internet connected!").setCancelable(false)
.setPositiveButton("OK", null);
builder.create().show();
} else {
builder.setMessage("Internet isn\'t connected!")
.setCancelable(false)
.setPositiveButton("OK", null);
builder.create().show();
}
}
};
// Check if the device is connected to the Internet
private boolean isNetworkConnected() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni == null) {
// There are no active networks.
return false;
} else
return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
When I'm trying to run this App on the emulator it keeps crushing and I'm getting this Error messages in LogCat:
07-24 22:59:45.034: E/AndroidRuntime(894): FATAL EXCEPTION: main
07-24 22:59:45.034: E/AndroidRuntime(894): java.lang.RuntimeException: Unable to
instantiate activity ComponentInfo{com.my.app/com.my.app.MainActivity}:
java.lang.IllegalStateException: System services not available to Activities before onCreate()
07-24 22:59:45.034: E/AndroidRuntime(894): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2585)
07-24 22:59:45.034: E/AndroidRuntime(894): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
07-24 22:59:45.034: E/AndroidRuntime(894): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
07-24 22:59:45.034: E/AndroidRuntime(894): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
07-24 22:59:45.034: E/AndroidRuntime(894): at android.os.Handler.dispatchMessage(Handler.java:99)
07-24 22:59:45.034: E/AndroidRuntime(894): at android.os.Looper.loop(Looper.java:123)
07-24 22:59:45.034: E/AndroidRuntime(894): at android.app.ActivityThread.main(ActivityThread.java:4627)
07-24 22:59:45.034: E/AndroidRuntime(894): at java.lang.reflect.Method.invokeNative(Native Method)
07-24 22:59:45.034: E/AndroidRuntime(894): at java.lang.reflect.Method.invoke(Method.java:521)
07-24 22:59:45.034: E/AndroidRuntime(894): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
07-24 22:59:45.034: E/AndroidRuntime(894): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
07-24 22:59:45.034: E/AndroidRuntime(894): at dalvik.system.NativeStart.main(Native Method)
07-24 22:59:45.034: E/AndroidRuntime(894): Caused by: java.lang.IllegalStateException: System services not available to Activities before onCreate()
07-24 22:59:45.034: E/AndroidRuntime(894): at android.app.Activity.getSystemService(Activity.java:3526)
07-24 22:59:45.034: E/AndroidRuntime(894): at com.android.internal.app.AlertController$AlertParams.<init>(AlertController.java:743)
07-24 22:59:45.034: E/AndroidRuntime(894): at android.app.AlertDialog$Builder.<init>(AlertDialog.java:273)
07-24 22:59:45.034: E/AndroidRuntime(894): at com.my.app.MainActivity.<init>(MainActivity.java:24)
07-24 22:59:45.034: E/AndroidRuntime(894): at java.lang.Class.newInstanceImpl(Native Method)
07-24 22:59:45.034: E/AndroidRuntime(894): at java.lang.Class.newInstance(Class.java:1429)
07-24 22:59:45.034: E/AndroidRuntime(894): at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
07-24 22:59:45.034: E/AndroidRuntime(894): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2577)
07-24 22:59:45.034: E/AndroidRuntime(894): ... 11 more
Why is it happening and how do I fix it? I'm a novice at this, so... please be gentle! :)
Upvotes: 21
Views: 55113
Reputation: 3351
Correct answer is
AlertDialog.Builder builder = new AlertDialog.Builder(this);
which is already mentioned by jeet and reason is you have initialized AlertDialog
before any lifecycle method of activity executed with Activity context that is logically not correct.
And solution to your problem is:
private OnClickListener listener = new OnClickListener() {
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
if (isNetworkConnected()) {
builder.setMessage("Internet connected!").setCancelable(false)
.setPositiveButton("OK", null);
builder.create().show();
} else {
builder.setMessage("Internet isn\'t connected!")
.setCancelable(false)
.setPositiveButton("OK", null);
builder.create().show();
}
}
};
Initialize alert dialog when it need to visible.
Reason behind posting answer to this old thread is the accepted answer and Jeet's answer did not solve the issue even if you move your onclick listener out of onCreate()
still issue will be same.
Today I came across same issue with kotlin where if internet not available then show error dialog and my silly mistake was
instead of passing context as "this" I passed it as MainActivity()
Correct R.string.error.errorDialog(this) //
Wrong R.string.error.errorDialog(MainActivity())
Upvotes: 1
Reputation: 13813
in my case, I got error message : “System services not available to Activities before onCreate()”
when I initialize class property using context like below
class MainActivity : AppCompatActivity() {
// this line below
private val notificationManager: NotificationManagerCompat = NotificationManagerCompat.from(this)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
Upvotes: 0
Reputation: 925
To call system services we have to use running activity. That means we need executed onCreate
method that inherited to the super
. So to identify that we have to use the current application context to call system service.
use
ConnectivityManager cm = (ConnectivityManager) getBaseContext().getSystemService(Context.CONNECTIVITY_SERVICE);
or if we have context
object that reference to Context
, we can use it as below
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Upvotes: 2
Reputation: 307
Also, if there's an inner class, say class MyAdapter extends ArrayAdapter<myModel>
or similar, it helps NOT to instantiate it - (MyAdapter = new mAdapter<mModel>()
) before the activity's onCreate()
.
Upvotes: 0
Reputation: 1917
add the following permission to AndroidManifest.xml file.
i think you forget to add this permission.
android.permission.ACCESS_NETWORK_STATE
it will help you.
Upvotes: 0
Reputation: 2517
The problem is that you define "listener" as a global variable. Since it's given in the error message: System services not available to Activities before onCreate().
Your onCreate method should be like this:
private OnClickListener listener = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listener = new OnClickListener() {
public void onClick(View v) {
if (isNetworkConnected()) {
builder.setMessage("Internet connected!").setCancelable(false)
.setPositiveButton("OK", null);
builder.create().show();
} else {
builder.setMessage("Internet isn\'t connected!")
.setCancelable(false)
.setPositiveButton("OK", null);
builder.create().show();
}
}
};
findViewById(R.id.icoMyIcon).setOnClickListener(listener);
}
Upvotes: 0
Reputation: 7905
I think it's because your instantiating an onClick listener before on create is called. Try instantiating the onClick listener inside the onCreate()
method.
This may or may not be the case with the AlertDialog
too, but I'm not entirely sure.
Technically I believe it is the following line that causes the problem:
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
However, because this is being called within the isNetworkConnected()
method which in turn is called within your onClick method, moving the instantiation of the onClick fixes the problem.
The clue is in the exception System services not available to Activities before onCreate()
Upvotes: 19
Reputation: 29199
Error is due to create this object creation.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
you should do this after onCreate has been invoked.
Upvotes: 10