Reputation: 389
I have a broadcast receiver inside a Service. The service should start an alarm manager and the broadcast receiver should receive the alarm. The service is started by a another broadcast receiver after device restart. but my code gives following exception and app crashes. How can I fix this?
06-28 17:26:20.983 6924-6924/com.example.krishan.timertest E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.krishan.timertest, PID: 6924
java.lang.RuntimeException: Unable to instantiate receiver com.example.krishan.timertest.MyService$AlarmReceiver: java.lang.InstantiationException: class com.example.krishan.timertest.MyService$AlarmReceiver has no zero argument constructor
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2992)
at android.app.ActivityThread.access$1800(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1507)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5910)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
Caused by: java.lang.InstantiationException: class com.example.krishan.timertest.MyService$AlarmReceiver has no zero argument constructor
at java.lang.Class.newInstance(Class.java:1681)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2987)
at android.app.ActivityThread.access$1800(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1507)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5910)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
Caused by: java.lang.NoSuchMethodException: <init> []
at java.lang.Class.getConstructor(Class.java:531)
at java.lang.Class.getDeclaredConstructor(Class.java:510)
at java.lang.Class.newInstance(Class.java:1679)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2987)
at android.app.ActivityThread.access$1800(ActivityThread.java:177)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1507)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5910)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
My service
public class MyService extends Service {
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("timer test", "*********************" + " Service Started " + "*********************");
startAlert();
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
public void startAlert() {
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), (60 * 1000), pendingIntent);
Toast.makeText(this, "Alarm set in 60 seconds", Toast.LENGTH_LONG).show();
}
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("Timer Test", "*********************" + " Alarm" + "*********************");
}
}
}
My broadcast receiver triggered when boot completed
public class BootReceiver extends BroadcastReceiver {
private Intent ServiceIntent;
@Override
public void onReceive(Context context, Intent intent) {
ServiceIntent = new Intent(context, MyService.class);
context.startService(ServiceIntent);
Toast.makeText(context, "Boot Receiver", Toast.LENGTH_LONG).show();
Intent intentx = new Intent(context, MainActivity.class);
intentx.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intentx);
}
}
My Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.krishan.timertest">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".MyService"
android:enabled="true"
android:exported="true"></service>
<receiver android:name=".BootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" >
</action>
</intent-filter>
</receiver>
<receiver android:name=".MyService$AlarmReceiver"></receiver>
</application>
</manifest>
This works properly if I declared the broadcast receiver as a separate class. But I want to declare it inside the service.
Upvotes: 2
Views: 1503
Reputation: 587
I did something similar,register the batteryBroadcast and the ScreenOn/ScreenOf Broadcast too, check the code:
public class turnOnScreenService extends Service {
private BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String strAction = intent.getAction();
if (strAction.equals(Intent.ACTION_SCREEN_OFF)) {
//do stuff
} else if (strAction.equals(Intent.ACTION_SCREEN_ON)) {
//do more stuff
}
}
};
private BroadcastReceiver mBatteryStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)) {
// more stuff
} else {
// more stuff
}
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
IntentFilter screenStateFilter = new IntentFilter();
screenStateFilter.addAction(Intent.ACTION_SCREEN_ON);
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(mScreenStateReceiver, screenStateFilter);
IntentFilter ifilter = new IntentFilter();
ifilter.addAction(Intent.ACTION_POWER_CONNECTED);
ifilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
registerReceiver(mBatteryStateReceiver, ifilter);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
unregisterReceiver(mScreenStateReceiver);
unregisterReceiver(mBatteryStateReceiver);
}
}
Upvotes: 2