androidandroid-vibration

Vibration is gone when running Android app in background


I have created an app that gives the user vibration alerts when tilting the phone in a certain direction. It works fine when running the app, however, when closing the window to run the app in background, the vibration stops working. How can I enable it in background?

vibrator.vibrate(VibrationEffect.createWaveform(new long[] {0, 1000}, -1));

I also have

<uses-permission android:name="android.permission.VIBRATE"/>

Solution

  • In addition to @MarcM answer, add "startMyOwnForeground" and it should work with Android 9+

    In your fragment:

    getActivity().startService(new Intent(getActivity(), VibrationService.class));
    

    VibrationService.java

    import android.app.Notification;
    import android.app.NotificationChannel;
    import android.app.NotificationManager;
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.graphics.Color;
    import android.os.Build;
    import android.os.IBinder;
    import android.os.VibrationEffect;
    import android.os.Vibrator;
    
    import androidx.annotation.Nullable;
    import androidx.core.app.NotificationCompat;
        
    public class VibrationdService extends Service {
    
        private Vibrator vibrator;
    
        @Override
        public void onCreate() {
            super.onCreate();
            vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
                startMyOwnForeground();
            else
                startForeground(1, new Notification());
        }
    
        private void startMyOwnForeground(){
            String NOTIFICATION_CHANNEL_ID = "com.example.simpleapp";
            String channelName = "My Background Service";
            NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
            chan.setLightColor(Color.BLUE);
            chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
            NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            assert manager != null;
            manager.createNotificationChannel(chan);
    
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
            Notification notification = notificationBuilder.setOngoing(true)
                    .setSmallIcon(R.drawable.ic_vibration)
                    .setContentTitle("App is running in background")
                    .setPriority(NotificationManager.IMPORTANCE_MIN)
                    .setCategory(Notification.CATEGORY_SERVICE)
                    .build();
            startForeground(2, notification);
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            vibrator.vibrate(VibrationEffect.createWaveform(new long[] {0, 1000}, -1));
            return START_STICKY;
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            vibrator.cancel();
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        private Notification createNotification() {
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "default")
                    .setSmallIcon(R.drawable.ic_vibration)
                    .setContentTitle("Vibration Service")
                    .setContentText("Vibration is running")
                    .setPriority(NotificationCompat.PRIORITY_HIGH)
                    .setOngoing(true);
    
            return builder.build();
        }
    }