101

I am struggling with this error:

08-08 11:42:53.179: E/AndroidRuntime(20288): Caused by: java.lang.InstantiationException: can't instantiate class com.example.localnotificationtest.ReminderService; no empty constructor

I don't understand why this error occurs.

I am trying to appear notification at specific time and after searching for a time i found this old stackoverflow question. I tried everything but my code gives error.

Please help me to solve this problem.

Here is my MainActivity code:

public class MainActivity extends Activity {
    int mHour, mMinute;
    ReminderService reminderService;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        reminderService = new ReminderService("ReminderService");

        TimePickerDialog dialog = new TimePickerDialog(this, mTimeSetListener, mHour, mMinute, false);
        dialog.show();
    }

    TimePickerDialog.OnTimeSetListener mTimeSetListener =  new OnTimeSetListener() {

        @Override
        public void onTimeSet(TimePicker v, int hourOfDay, int minute) {
            mHour = hourOfDay;
            mMinute = minute;

            AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
            Calendar c = Calendar.getInstance();
            c.set(Calendar.YEAR, Calendar.YEAR);
            c.set(Calendar.MONTH, Calendar.MONTH);
            c.set(Calendar.DAY_OF_MONTH, Calendar.DAY_OF_MONTH);
            c.set(Calendar.HOUR_OF_DAY, mHour);
            c.set(Calendar.MINUTE, mMinute);
            c.set(Calendar.SECOND, 0);

            long timeInMills = c.getTimeInMillis();

            Intent intent = new Intent(MainActivity.this, ReminderService.class);
            PendingIntent pendingIntent = PendingIntent.getService(MainActivity.this, 0, intent, 0);
            alarmManager.set(AlarmManager.RTC, timeInMills, pendingIntent);
        }
    };

}

and here is my ReminderService code:

public class ReminderService extends IntentService {

    public ReminderService(String name) {
        super(name);
        // TODO Auto-generated constructor stub
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        Intent notificationIntent = new Intent(this, MainActivity.class);
        PendingIntent contentIntent = PendingIntent.getActivity(this, 1, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);

        NotificationManager nm = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);

        Notification.Builder builder = new Notification.Builder(this);

        builder.setContentIntent(contentIntent)
            .setSmallIcon(R.drawable.ic_launcher)
            .setTicker("Local Notification Ticker")
            .setWhen(System.currentTimeMillis())
            .setAutoCancel(true)
            .setContentTitle("Local Notification")
            .setContentText("This is content text.");
         Notification n = builder.getNotification();

         nm.notify(1, n);
    }

}

and here is my manifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.localnotificationtest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="11"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"  android:label="@string/app_name"  android:theme="@style/AppTheme" >
        <activity android:name=".MainActivity"  android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="ReminderService"></service>
    </application>

</manifest>

I don't know where I am going wrong. Am I missing some code?

Community
  • 1
  • 1
Pari
  • 1,705
  • 4
  • 18
  • 19

4 Answers4

225

You need to add an empty constructor to your class i.e. one that takes no arguments:

public ReminderService() {
    super("ReminderService");
}

Explanation from the documentation:

The name is used to name the worker thread.

NOTE: this is only applicable to intent service.

Avinash R
  • 3,101
  • 1
  • 27
  • 47
chiuki
  • 14,580
  • 4
  • 40
  • 38
44

If you have your Service declared as an Inner Class / Nested Class, you also need to make the class static

Without that you´ll get the error even if your constructor is correct

Explanation

The reason for that is, you can only instantiate inner classes in the context of the outer class, so you would need to create an instance of the outer class first.

Declaring your inner class static makes it independent from its outer class

Marian Klühspies
  • 15,824
  • 16
  • 93
  • 136
  • Where is this documented? – Ciro Santilli OurBigBook.com Feb 13 '16 at 10:14
  • I don´t know if it is documented anywhere, but if you want to instantiate inner non static classes, the outer class must be instantiated first. Now if you start a service, the instance is created by the system, which won´t know that it has to make an instance from the outer class first, so it will crash. But the error is really misleading in that case. take a look at http://stackoverflow.com/questions/70324/java-inner-class-and-static-nested-class – Marian Klühspies Feb 13 '16 at 14:25
32

Declare a default no-argument constructor for IntentService

public class ReminderService extends IntentService {
    public ReminderService() {
      super("ReminderService");
    }
}
Pratik Butani
  • 60,504
  • 58
  • 273
  • 437
ρяσѕρєя K
  • 132,198
  • 53
  • 198
  • 213
7

You need to add the default no-argument constructor to your ReminderService class. This is only implicitly added if you don't write a constructor of your own (which you have). See here: http://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html

Pratik Butani
  • 60,504
  • 58
  • 273
  • 437
JamesB
  • 7,774
  • 2
  • 22
  • 21