Home > Mobile >  Vibration is gone when running Android app in background
Vibration is gone when running Android app in background

Time:01-13

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"/>

CodePudding user response:

There are several options. One of them is using a a foreground service.

A foreground service is a service that runs in the background and is given higher priority than a background service, which means it is less likely to be killed by the system when the app is closed.

This is a sample code snippet:

public class VibrationForegroundService extends Service {

    private Vibrator vibrator;

    @Override
    public void onCreate() {
        super.onCreate();
        vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        startForeground(1, createNotification());
        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_launcher)
                .setContentTitle("Vibration Service")
                .setContentText("Vibration is running")
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setOngoing(true);

        return builder.build();
    }
}

CodePudding user response:

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();
    }
}
  • Related