I'm writting an app that its main goal is starts TuneIn player when my device is conected to AC. The first version used only broadcast receivers and it works well, except for the normal behavior of android OS discarding receivers once fired, because, i'm looking for something more permanent I'm trying to use a service to maintain the broadcast receiver active, but I'm getting some errors that I can't understand.
So in what way it's possible use broadcast receivers inside a service?
I'm putting one error Log, and part of my code.
Errors:
07-19 08:03:27.019: ERROR/AndroidRuntime(15785): FATAL EXCEPTION: main
java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.BATTERY_CHANGED flg=0x60000000 (has extras) } in com.upm.radioC.Servicio$1@407a0420
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:722)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3683)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:895)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:653)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: System services not available to Activities before onCreate()
at android.app.Activity.getSystemService(Activity.java:3536)
at com.upm.radioC.Tools.checkData(Tools.java:26)
at com.upm.radioC.Servicio$1.onReceive(Servicio.java:60)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:709)
Main Class
public class Inicio extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflador = getMenuInflater();
inflador.inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem opcion) {
TextView btn = (TextView) findViewById(R.id.txtEtiqueta);
Intent svc = new Intent(this, Servicio.class);
switch (opcion.getItemId()) {
case R.id.mnuRegistra:
startService(svc);
btn.setText("Monitoreo Iniciado");
break;
case R.id.mnuLibera:
stopService(svc);
btn.setText("Monitoreo Detenido");
break;
}
return super.onMenuItemSelected(featureId, opcion);
}
}
Service Class
public class Servicio extends Service {
private BroadcastReceiver receiver;
private IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
private Tools NetWork = new Tools(); //Custom Class for activate/deactivate GSM data
@Override
public IBinder onBind(Intent arg0) {
return null;}
@Override
public void onCreate() {
super.onCreate();}
@Override
public int onStartCommand(Intent i, int flags, int startID) {
_startService();
return START_STICKY; }
@Override
public void onDestroy() {
super.onDestroy();
_shutdownService(); }
private void _startService() {
receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
if (plugged == BatteryManager.BATTERY_PLUGGED_USB) {
Toast.makeText(getApplicationContext(), "Conectado a USB", Toast.LENGTH_LONG).show();
}else if (plugged == BatteryManager.BATTERY_PLUGGED_AC) {
if (!NetWork.checkData()) try {
NetWork.turnData(true);
} catch (Exception e) {
e.printStackTrace();
}
Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage("tunein.player");
startActivity(LaunchIntent);
Toast.makeText(getApplicationContext(), "Conectado a AC", Toast.LENGTH_LONG).show();
} else {
if (NetWork.checkData()) try {
NetWork.turnData(false);
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "Desconectado de las fuentes de poder", Toast.LENGTH_LONG).show();
}
}
};
registerReceiver(receiver, filter);
}
private void _shutdownService() {
unregisterReceiver(receiver);}
}
Thanks in advance!
Looks like it has got something to do with the context in which you are calling getSystemService
. Try passing the service context to the Tools
class, and then use that context for calling getSystemService
.
Create Tools
instance in onCreate
of Servicio
private Tools NetWork = null;
@Override
public void onCreate() {
super.onCreate();
Network = new Tools(this);
}
And then in your Tools
class store this incoming Context
in a private variable (say mContext
) and use that in the methods of that class.
boolean checkData() {
ConnectivityManager connManager = (ConnectivityManager) mContext.getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo mMobile = connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
return mMobile.isConnected();
}
EDIT:
For understanding Context, you can refer to below references