I currently have a functioning timer using a textview (if there is a similar/more efficient way to make a timer I'd love to know).
What I want to do is make the phone vibrate at specific intervals throughout the timer.
Example:
The timer starts at 10 minutes, and after 7 seconds it vibrates, then after 5 seconds, it vibrates then again after 7 seconds, and so on until the timer completes, where it will finish with a very long vibration.
Here is the code I have so far:
public class RelaxActivity extends AppCompatActivity {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return super.onCreateOptionsMenu(menu);
}
// declare variables for buttons and timer
private static final long START_TIME_IN_MILLIS = 600000;
private TextView mTextViewCountDown;
private Button mButtonStartPause;
private Button mButtonReset;
private CountDownTimer mCountDownTimer;
private boolean mTimerRunning;
private long mTimerLeftInMillis = START_TIME_IN_MILLIS;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_relax);
mTextViewCountDown = findViewById(R.id.text_view_countdown);
mButtonStartPause = findViewById(R.id.button_start_stop);
mButtonReset = findViewById(R.id.button_reset);
mButtonStartPause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mTimerRunning) {
pauseTimer();
} else {
startTimer();
}
}
});
mButtonReset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
resetTimer();
}
});
updateCountDownText();
}
// start timer
private void startTimer(){
mCountDownTimer = new CountDownTimer(mTimerLeftInMillis, 1000) {
@Override
public void onTick(long millisUntilFinished) {
mTimerLeftInMillis = millisUntilFinished;
updateCountDownText();
}
@Override
public void onFinish() {
mTimerRunning = false;
mButtonStartPause.setText("Start");
mButtonStartPause.setVisibility(View.INVISIBLE);
mButtonReset.setVisibility(View.VISIBLE);
}
}.start();
mTimerRunning = true;
mButtonStartPause.setText("Pause");
mButtonReset.setVisibility(View.INVISIBLE);
}
// cancel timer, change text of button to start, and make reset button visible
private void pauseTimer(){
mCountDownTimer.cancel();
mTimerRunning = false;
mButtonStartPause.setText("Start");
mButtonReset.setVisibility(View.VISIBLE);
}
// reset timer method
private void resetTimer(){
mTimerLeftInMillis = START_TIME_IN_MILLIS;
updateCountDownText();
mButtonReset.setVisibility(View.INVISIBLE);
mButtonStartPause.setVisibility(View.VISIBLE);
}
// do math for countdown text from milliseconds to minutes and then seconds
private void updateCountDownText(){
int minutes = (int) (mTimerLeftInMillis / 1000) / 60;
int seconds = (int) (mTimerLeftInMillis / 1000) % 60;
// convert minutes and seconds variables into time string
String timeLeftFormatted = String.format(Locale.getDefault(),"%02d:%02d", minutes, seconds);
mTextViewCountDown.setText(timeLeftFormatted);
}
// menu
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch(item.getItemId()) {
case R.id.mnuMain:
startActivity(new Intent(getApplicationContext(), MainMenuActivity.class));
return true;
case R.id.mnuExit:
finish();
default:
return super.onOptionsItemSelected(item);
}
}
}
Import Vibrator and VibrationEffect:
import android.os.Vibrator;
import android.os.VibrationEffect;
Declare these two variables at the class level:
private int secondCounter;
private Vibrator vibrator;
Initialize in onCreate
:
secondCounter = 0;
vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
Increment secondCounter
in your onTick
method and check the count:
public void onTick(long millisUntilFinished) {
mTimerLeftInMillis = millisUntilFinished;
updateCountDownText();
// check the seconds that have passed
if (secondCounter == 7 || secondCounter == 12) {
// 500 is milliseconds of vibration, modify as needed
vibrator.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
// reset second counter
if (secondCounter == 12) {
secondCounter = -1;
}
}
// increment secondCounter
secondCounter++;
}
My logic for keeping track of the seconds might be off (didn't double check it), but you get the idea.
For the vibration on when the timer is complete, just add another vibrator.vibrate
call in the timer's onFinish
method.
Also, be sure to add the vibration permission in your app's manifest file.