- Refactoring Your Code
- Implementing Strict Mode
- Understanding the Activity Lifecycle
- Making an Android Device Vibrate
- Saving User Preferences
- Summary
Making an Android Device Vibrate
Sometimes a device’s screen may not be visible (for example, if it’s in someone’s pocket), so you need to indicate that time has passed in a nonvisual way. Making the device vibrate is a good way to do this.
Let’s set up the code to vibrate once every 5 minutes, twice every 15 minutes, and three times every hour while the timer is running.
Add a property called vibrate of type Vibrator to the TimerActivity class:
protected
Vibratorvibrate
;Add a property called lastSeconds of type long. This is needed because the run method is called several times a second, and you want the device to vibrate only once.
protected long
lastSeconds
;In the onStart method, set up the vibrate property by calling getSystemService. Not all devices can vibrate (and most tablets can’t), so you need to check and log when a device doesn’t support the feature:
vibrate
= (Vibrator) getSystemService(VIBRATOR_SERVICE
);if
(vibrate
==null
) { Log.w(CLASS_NAME
,"No vibration service exists."
); }Add a new method called vibrateCheck, which should look like Listing 4.7. This method uses a similar approach as setTimeDisplay’s to work out the time difference, but you need only calculate the current minutes and seconds.
To vibrate the device, you call the vibrate method, passing it an array of numbers. The numbers represent a vibration pattern, with the first number being the number of milliseconds to wait before starting. This is followed by how long it should vibrate and how long it should pause between each vibration.
Listing 4.7 Method for Vibrating a Number of Times at Regular Intervals
protected
void
vibrateCheck() {long
timeNow = System.currentTimeMillis();long
diff = timeNow -startedAt
;long
seconds = diff / 1000;long
minutes = seconds / 60; Log.d(CLASS_NAME
,"vibrateCheck"
); seconds = seconds % 60; minutes = minutes % 60;if
(vibrate
!=null
&& seconds == 0 && seconds !=lastSeconds
) {long
[] once = { 0, 100 };long
[] twice = { 0, 100, 400, 100 };long
[] thrice = { 0, 100, 400, 100, 400, 100 };// every hour
if
(minutes == 0) { Log.i(CLASS_NAME
,"Vibrate 3 times"
);vibrate
.vibrate(thrice, -1); }// every 15 minutes
else
if
(minutes % 15 == 0) { Log.i(CLASS_NAME
,"Vibrate 2 time"
);vibrate
.vibrate(twice, -1); }// every 5 minutes
else
if
(minutes % 5 == 0) { Log.i(CLASS_NAME
,"Vibrate once"
);vibrate
.vibrate(once, -1); } }lastSeconds
= seconds; }Once the minutes and seconds have been calculated, the code needs to check whether it is on one of the three vibration boundaries. If it is, it should vibrate the required number of times. Note the check seconds != lastSeconds. This makes sure you don’t vibrate more than once per second, because this method could be called multiple times in a single second.
Inside the run method, add a check (before the handler check and postDelayed call) to see whether the timer is running and, if it is, to call the vibrateCheck method:
if
(timerRunning
) { vibrateCheck(); }- Debug the application in the emulator, and see that vibrateCheck is being called in the LogCat view.
Debug the application via USB debugging. An error will occur. Correct this error by adding the vibrate permission to the Android manifest file just after <uses-sdk>:
<uses-permission
android:name
="android.permission.VIBRATE
"/>