Home > Articles > Programming > Java

  • Print
  • + Share This
This chapter is from the book

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.

  1. Add a property called vibrate of type Vibrator to the TimerActivity class:

    protected Vibrator vibrate;
  2. 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;
  3. 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.");
    }
    
  4. 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.

  5. 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();
    }
  6. Debug the application in the emulator, and see that vibrateCheck is being called in the LogCat view.
  7. 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" />
  • + Share This
  • 🔖 Save To Your Account