0

I am really new to Android Studio (and relatively new to Java too), and I am trying to create an app that will allow the user to input a time and have a timer start counting down when that time occurs. After looking into it, it seems like using an intent is the best way to go, but I am having some issues understanding how to use it. Right now, I have the following code in my main activity file (called Countdown):

public class Countdown extends AppCompatActivity {
EditText mHours;
EditText mMinutes;
TextView mDisplay;
public static long finalTime = 0;
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
Context context;

@Override
public void onCreate(Bundle savedInstanceState) {


    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_countdown);
    mHours = (EditText) findViewById(R.id.text1);
    mMinutes = (EditText) findViewById(R.id.text2);
    mDisplay = (TextView) findViewById(R.id.display);
    Button button = (Button) findViewById(R.id.button1);

    button.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(System.currentTimeMillis());
            calendar.set(Calendar.HOUR_OF_DAY, 11);
            calendar.set(Calendar.MINUTE, 22);
            Intent intent = new Intent(context, Countdown.class);
            alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

            alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
            alarmMgr.set(AlarmManager.RTC, calendar.getTimeInMillis(), alarmIntent);

            final long hourInput = Long.parseLong(mHours.getText().toString());
            final long minuteInput = Long.parseLong(mMinutes.getText().toString());
            finalTime = (hourInput * 3600000) + (minuteInput *  60000);



    }
} );}}

And in my receiver file I have:

public class CountdownStarter {
TextView mDisplay;
public void onRecieve() {

    final CountDownTimer aCounter = new CountDownTimer(Countdown.finalTime, 1000) {

        public void onTick(long millisUntilFinished) {
            mDisplay.setText("Seconds remaining: " + millisUntilFinished / 1000);
        }

        public void onFinish() {
            mDisplay.setText("Finished");
        }
    };
    aCounter.start();
}
}

Right now, running the debugger I get this message:

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.example.android.timerexample, PID: 32276
              java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
                  at android.content.ComponentName.<init>(ComponentName.java:128)
                  at android.content.Intent.<init>(Intent.java:5283)
                  at com.example.android.timerexample.Countdown$1.onClick(Countdown.java:42)
                  at android.view.View.performClick(View.java:5702)
                  at android.widget.TextView.performClick(TextView.java:10888)
                  at android.view.View$PerformClick.run(View.java:22533)
                  at android.os.Handler.handleCallback(Handler.java:739)
                  at android.os.Handler.dispatchMessage(Handler.java:95)
                  at android.os.Looper.loop(Looper.java:158)
                  at android.app.ActivityThread.main(ActivityThread.java:7229)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

I was trying to look into it but I just don't understand why I am getting the NullPointerException or how to fix it - I am definitely doing some stuff wrong here but I can't figure out what the next step is. Any assistance would be very helpful!

Stidgeon
  • 2,673
  • 8
  • 20
  • 28
Tessa
  • 9
  • 1

2 Answers2

1

There is no initiation of context in the code snippet and as already mentioned, you don't need a context object in a activity class.

You can replace this code

Intent intent = new Intent(context, Countdown.class);
alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

with

Intent intent = new Intent(this, Countdown.class);
alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Alex
  • 779
  • 7
  • 15
0

An Activity is a Context, therefore Context context is not necessary and you can use Countdown.this instead of using a context variable here.

Intent intent = new Intent(context, Countdown.class); // here
alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0); // and here

Or you need to actually assign context

private Context;

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_countdown);
    context = this; // Here
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • While you are right, I'm not sure someone fairly new to Java will immediately understand the issue. Let me try:) As already commented, the context variable is null, and using it causes ("throws") a NullPointerException. Now, there are two options, either assign the context variable before using it, as in the second code block in this answer. Or, instead of passing the context variable in `new Intent(...)`, use Countdown.this, which is a reference to the instance of the surrounding class, which is a superclass of AppCompatActivity, which is a superclass of Context. – Micha Jan 22 '17 at 20:20
  • 1
    @Micha Feel free to answer on your own. I don't need to know these things – OneCricketeer Jan 22 '17 at 20:24