I have created a timer
that starts timing on a handleClick()
and continues timing throughout the app
. When I return to the firstActivity
I would like the timer
to stop
in the onResume()
. however whenever I return to the firstActivity
I get the following error below. How do I solve this?
Error
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean com.example.warrenedy.julyfinal.TimeTracker2.isTracking()' on a null object reference
Code Below
@Override
protected void onResume() {
super.onResume();
prepareActivityTextsAndButtons();
prepareTimingButtons();
mTimeTracker2.stopTracker();
Toast.makeText(this, "Onresume call", Toast.LENGTH_SHORT).show();
}
public void handleClick(View v) {
if (DBG) Log.d(LOG_TAG, "handleClick()..");
if (!mServiceBound) return;
switch (v.getId()) {
case R.id.button_activity_start_stop:
onActivityButtonClick(v);
break;
}
}
private void onActivityButtonClick(View v) {
if (DBG)
Log.d(LOG_TAG, "onMeditateButtonClick().. tracking " + mTimeTracker2.isTracking());
ToggleButton button = (ToggleButton) v;
if (mTimeTracker2.isTracking()) {
if (mCurrentTrackingActivity == null) return;
if (button == mButtonActivityTimers[mCurrentTrackingActivity.ordinal()]) {
mTimeTracker2.stopTracker();
Utils2.playStopAudio(getApplicationContext());
// button.setText(R.string.str_start);
mCurrentTime.setText(Utils2.secToString(0));
button.setChecked(false);
}
}
}
Code Continued
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (DBG) Log.d(LOG_TAG, "onCreate()..");
setContentView(R.layout.activity_meditation_tracker);
getSupportActionBar().hide();
mContext = getApplicationContext();
mSharedpreferences = getSharedPreferences(Utils.MyPREFERENCES, Context.MODE_PRIVATE);
exercise_star = sharedpreferences.getInt("exercise_star", 0);
meditation_star = sharedpreferences.getInt("meditation_star", 0);
study_star = sharedpreferences.getInt("study_star", 0);
isAlarmSet = sharedpreferences.getBoolean("isAlarmSet", false);
/* Retrieve a PendingIntent that will perform a broadcast */
mActivity = MeditationTrackerActivity.this;
mButtonSavePoints = (Button) findViewById(R.id.btn_save_points);
mButtonRestorePoints = (Button) findViewById(R.id.btn_restore_points);
btnHelpBut = (Button) findViewById(R.id.btnHelp);
ACTIVITY_NAMES = getResources().getStringArray(R.array.activity_names);
mCurrentTime = (TextView) findViewById(R.id.tv_current_time);
mCurrentTime.setText(Utils2.secToString(0));
if (!isAlarmSet) {
SharedPreferences.Editor ed = sharedpreferences.edit();
ed.putBoolean("isAlarmSet", true);
ed.commit();
startAlarmService();
}
isAuthenticated = sharedpreferences.getBoolean("isAuth", true);
if (Build.VERSION.SDK_INT < 23) {
if (!isAuthenticated) {
clientAuthenticationFromServer();
} else {
startService();
}
} else {
insertPermissionWrapper();
}
}
### StartAlarmService
public void startAlarmService() {
Intent alarmIntent = new Intent(MeditationTrackerActivity.this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(MeditationTrackerActivity.this, 0, alarmIntent, 0);
mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar firingCal = Calendar.getInstance();
Calendar currentCal = Calendar.getInstance();
firingCal.set(Calendar.HOUR_OF_DAY, 23); // At the hour you wanna fire
firingCal.set(Calendar.MINUTE, 45); // Particular minute
firingCal.set(Calendar.SECOND, 0); // particular second
long intendedTime = firingCal.getTimeInMillis();
long currentTime = currentCal.getTimeInMillis();
if (intendedTime >= currentTime) {
mAlarmManager.setRepeating(AlarmManager.RTC, intendedTime, AlarmManager.INTERVAL_DAY, pendingIntent);
} else {
firingCal.add(Calendar.DAY_OF_MONTH, 1);
intendedTime = firingCal.getTimeInMillis();
mAlarmManager.setRepeating(AlarmManager.RTC, intendedTime, AlarmManager.INTERVAL_DAY, pendingIntent);
}
Toast.makeText(this, "Main Alarm Set", Toast.LENGTH_SHORT).show();
}
### CancelAlarm
public void cancelAlarmService() {
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
manager.cancel(pendingIntent);
Toast.makeText(this, "Alarm Canceled", Toast.LENGTH_SHORT).show();
}
### StartService
private void startService() {
Intent serIntent = new Intent(this, TimeTrackingService2.class);
startService(serIntent);
bindService(serIntent, mServiceConnection, BIND_AUTO_CREATE);
}
### UpdateCurrentTime
private void updateCurrentTime() {
Date date = Calendar.getInstance().getTime();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
mCurrentTime.setText(sdf.format(date));
}
### ClientAuthenticationFromServer
private void clientAuthenticationFromServer() {
if (Utils2.getConnectivityStatus(mContext)) {
new Auth(mContext, mActivity).execute(Utils2.URL_VALIDATE_CLIENT);
} else {
Utils2.alertPopup(mContext, "You are not connected to internet.kindly connect with internet and try again.The internet is needed only first time for the authentication of client.After authentication no need of internet.", mActivity);
}
}
###Task Complete
@Override
public void onTaskComplete(boolean result) {
if (!result) {
Utils2.alertPopup(mContext, "You are not a valid client.Contact with the owner of the App.", mActivity);
return;
} else {
SharedPreferences.Editor ed = sharedpreferences.edit();
ed.putBoolean("isAuth", true);
ed.commit();
startService();
}
}
### OnStart
@Override
protected void onStart() {
super.onStart();
// updateCurrentTime();
// IntentFilter filter = new IntentFilter(Intent.ACTION_TIME_TICK);
// registerReceiver(mTimeTickReceiver, filter);
}
###OnStop
@Override
protected void onStop() {
super.onStop();
// unregisterReceiver(mTimeTickReceiver);
}
### onDestroy
@Override
protected void onDestroy() {
super.onDestroy();
if (mServiceBound) {
unbindService(mServiceConnection);
}
}
### onTimeButtonClick
private void onTimeButtonClick(View v) {
if (DBG) Log.d(LOG_TAG, "onClick() timebutton.. tracking" + mTimeTracker2.isTracking());
ToggleButton button = (ToggleButton) v;
if (DBG) Log.d(LOG_TAG, "onClick() timebutton.. checked ? " + button.isChecked());
if (mTimeTracker2.isTracking()) {
showStopToast();
Utils2.playStopAudio(getApplicationContext());
button.setChecked(false);
return;
} else {
Utils2.playStartAudio(getApplicationContext());
if (button.isChecked()) {
if (mCurrentCheckedButton != null) mCurrentCheckedButton.setChecked(false);
int time = (Integer) v.getTag();
mCountDownSecs = time;
mCurrentCheckedButton = button;
} else {
mCountDownSecs = 0;
mCurrentCheckedButton = null;
}
}
}
###ShowStopToast
private void showStopToast() {
Toast.makeText(this, "Please stop running activity..", Toast.LENGTH_SHORT).show();
}
### onTimerProgress
@Override
public void onTimerProgress(int sec, ACTIVITIES activity) {
if (mCurrentTrackingActivity == null) {
mCurrentTrackingActivity = activity;
}
mCurrentTime.setText(Utils2.secToString(sec));
if (activity == ACTIVITIES.STUDY) {
if (sec == 3600) {
mTimeTracker2.stopTracker();
}
}
}
### onTimerFinish
@Override
public void onTimerFinish(int end, ACTIVITIES activity) {
mCurrentTime.setText(Utils2.secToString(end));
mButtonActivityTimers[activity.ordinal()].setChecked(false);
mCurrentTrackingActivity = null;
Utils2.playStopAudio(getApplicationContext());
}
private void prepareActivityTextsAndButtons() {
for (int i = 0; i < ACTIVITY_COUNT; i++) {
View parent = findViewById(ACTIVITY_LAYOUT_IDS[i]);
mTextActivityNames[i] = (TextView) parent.findViewById(R.id.tv_activity_name);
mTextActivityNames[i].setText(ACTIVITY_NAMES[i]);
//mTextActivityTimers[i] = (TextView) parent.findViewById(R.id.tv_timer_progress);
mRatingBars[i] = (RatingBar) parent.findViewById(R.id.ratingBar);
mButtonActivityTimers[i] = (ToggleButton) parent.findViewById(R.id.button_activity_start_stop);
mButtonActivityTimers[i].setText(null);
mButtonActivityTimers[i].setTextOn(null);
mButtonActivityTimers[i].setTextOff(null);
mButtonActivityTimers[i].setTag(ACTIVITIES.values()[i]);
}
}
private void prepareTimingButtons() {
mTimingButtons = new ToggleButton[7];
mTimingButtons[0] = (ToggleButton) findViewById(R.id.button_timer_0);
addTextToTimingButtons(5, mTimingButtons[0]);
}
private void addTextToTimingButtons(int min, Button button) {
// button.setText(min + " " + getString(R.string.str_min));
button.setTag(min * 60);
}
public void onCustomTimeStarted(int secs) {
if (DBG) Log.d(LOG_TAG, "onCustomTimeStarted : secs " + secs);
if (mTimeTracker2.isTracking()) {
showStopToast();
} else {
int oneday = 24 * 3600;
if (secs > oneday) {
Toast.makeText(this, "Adjusted to 24 hrs", Toast.LENGTH_SHORT).show();
secs = oneday;
} else if (secs < 60) {
Toast.makeText(this, "Should be at least a minute.", Toast.LENGTH_SHORT).show();
return;
}
mTimingButtons[6].setChecked(true);
mTimingButtons[6].setTag(secs);
onTimeButtonClick(mTimingButtons[6]);
//mTimeTracker2.startTracker(secs, this);
//mButtonMeditate.setText(R.string.meditate_stop);
}
}
private boolean addPermission(List<String> permissionsList, String permission) {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(permission);
// Check for Rationale Option
if (!shouldShowRequestPermissionRationale(permission))
return false;
}
}
return true;
}
private void insertPermissionWrapper() {
List<String> permissionsNeeded = new ArrayList<String>();
final List<String> permissionsList = new ArrayList<String>();
if (!addPermission(permissionsList, Manifest.permission.READ_PHONE_STATE))
permissionsNeeded.add("READ_PHONE_STATE");
if (permissionsList.size() > 0) {
if (permissionsNeeded.size() > 0) {
// Need Rationale
String message = "You need to grant access to " + permissionsNeeded.get(0);
for (int i = 1; i < permissionsNeeded.size(); i++)
message = message + ", " + permissionsNeeded.get(i);
showMessageOKCancel(message,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= 23) {
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
}
}
});
return;
}
if (Build.VERSION.SDK_INT >= 23) {
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
}
return;
} else {
if (!isAuthenticated) {
clientAuthenticationFromServer();
} else {
startService();
}
}
// insertDummyContact();
}
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new android.app.AlertDialog.Builder(MeditationTrackerActivity.this)
.setMessage(message)
.setCancelable(false)
.setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.create()
.show();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: {
Map<String, Integer> perms = new HashMap<String, Integer>();
// Initial
perms.put(Manifest.permission.READ_PHONE_STATE, PackageManager.PERMISSION_GRANTED);
// Fill with results
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
// Check for ACCESS_FINE_LOCATION
if (perms.get(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED
) {
// All Permissions Granted
if (!isAuthenticated) {
clientAuthenticationFromServer();
} else {
startService();
}
} else {
// Permission Denied
Toast.makeText(MeditationTrackerActivity.this, "Some Permission is Denied", Toast.LENGTH_SHORT)
.show();
finish();
}
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
private void setBootReceiverEnabled(int componentEnabledState) {
ComponentName componentName = new ComponentName(this, DeviceBootReceiver.class);
PackageManager packageManager = getPackageManager();
packageManager.setComponentEnabledSetting(componentName,
componentEnabledState,
PackageManager.DONT_KILL_APP);
};
TimeTracker2.class
public class TimeTracker2 {
private static final int MSG_TRACKER_STOPPED = 1;
private static final int MSG_TRACKER_PROGRESS_UPDATE = 2;
private Context mContext;
private boolean mIsTrackingInProgress;
private TrackerServiceCallback mServiceCallback;
private TimerProgressCallback2 mProgressCallback;
private Timer mTimer = new Timer();
private TimerHandler mTimerHandler = new TimerHandler();
private TimerTask mIncrementTask, mDecrementTask;
private int mCounter;
private int mMaxCounter;
private MeditationTrackerActivity.ACTIVITIES mCurrentTrackingActivity;
private class IncrementTask extends TimerTask {
IncrementTask() {
mCounter = 0;
}
@Override
public void run() {
mCounter++;
mTimerHandler.sendEmptyMessage(MSG_TRACKER_PROGRESS_UPDATE);
}
}
private class DecrementTask extends TimerTask {
DecrementTask(int sec) {
mCounter = sec;
}
@Override
public void run() {
if (mCounter == 0) {
ToneGenerator toneGenerator = new ToneGenerator(AudioManager.STREAM_MUSIC, 100);
toneGenerator.startTone(ToneGenerator.TONE_CDMA_PIP, 500);
cancel();
mTimerHandler.sendEmptyMessage(MSG_TRACKER_STOPPED);
return;
}
mCounter --;
mTimerHandler.sendEmptyMessage(MSG_TRACKER_PROGRESS_UPDATE);
}
}
public interface TimerProgressCallback2 {
void onTimerProgress(int sec, MeditationTrackerActivity.ACTIVITIES activity);
void onTimerFinish(int end, MeditationTrackerActivity.ACTIVITIES activity);
}
public TimeTracker2(Context context, TrackerServiceCallback serviceCallback) {
mContext = context;
mServiceCallback = serviceCallback;
}
public void startTracker(int time_secs, TimerProgressCallback2 callback, MeditationTrackerActivity.ACTIVITIES activity) {
if (mIsTrackingInProgress) {
Log.i(LOG_TAG, "startTracker().. inProgress!!");
return;
}
mMaxCounter = time_secs;
mProgressCallback = callback;
mIsTrackingInProgress = true;
mServiceCallback.onTrackerStarted(true);
mDecrementTask = new DecrementTask(time_secs);
mTimer.scheduleAtFixedRate(mDecrementTask, 0, 1000);
mCurrentTrackingActivity = activity;
}
public void startTracker(TimerProgressCallback2 callback, MeditationTrackerActivity.ACTIVITIES activity) {
if (mIsTrackingInProgress) {
Log.i(LOG_TAG, "startTracker().. inProgress!!");
return;
}
mMaxCounter = 0;
mProgressCallback = callback;
mIsTrackingInProgress = true;
mServiceCallback.onTrackerStarted(true);
mIncrementTask = new IncrementTask();
mTimer.scheduleAtFixedRate(mIncrementTask, 0, 1000);
mCurrentTrackingActivity = activity;
}
public void setTimerProgressCallback(TimerProgressCallback2 callback) {
if (!mIsTrackingInProgress) return;
mProgressCallback = callback;
}
public void removeTimerProgressCallback() {
mProgressCallback = null;
}
public void stopTracker() {
if (!mIsTrackingInProgress) {
Log.i(LOG_TAG, "stopTracker().. Tracker NOT started!!");
return;
}
mIsTrackingInProgress = false;
mServiceCallback.onTrackerStarted(false);
if (mProgressCallback != null) mProgressCallback.onTimerFinish(mCounter, mCurrentTrackingActivity);
mProgressCallback = null;
if (mIncrementTask != null) mIncrementTask.cancel();
if (mDecrementTask != null) mDecrementTask.cancel();
updateDb();
mCurrentTrackingActivity = null;
}
public boolean isTracking() {
return mIsTrackingInProgress;
}
public MeditationTrackerActivity.ACTIVITIES getCurrentTrackingActivity() {
return mCurrentTrackingActivity;
}
private class TimerHandler extends Handler {
@Override
public void handleMessage(Message msg) {
if (DBG) Log.d(LOG_TAG, "handleMessage()..");
switch (msg.what) {
case MSG_TRACKER_PROGRESS_UPDATE:
if (mProgressCallback != null) mProgressCallback.onTimerProgress(mCounter, mCurrentTrackingActivity);
break;
case MSG_TRACKER_STOPPED:
default:
stopTracker();
break;
}
}
}
private void updateDb() {
final int secs = mMaxCounter > 0 ? mMaxCounter - mCounter : mCounter;
final MeditationTrackerActivity.ACTIVITIES activity = mCurrentTrackingActivity;
AsyncTask.execute(new Runnable() {
@Override
public void run() {
TrackerDb3.insertOrUpdateMeditation(mContext, secs, activity);
}
});
}
}