在后台运行Android应用程序时振动消失了

问题描述 投票:0回答:3

我创建了一个应用程序,当用户向某个方向倾斜手机时,它会向用户发出振动警报。运行应用程序时它工作正常,但是,当关闭窗口以在后台运行应用程序时,振动停止工作。如何在后台启用它?

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

我也有

<uses-permission android:name="android.permission.VIBRATE"/>
android android-vibration
3个回答
2
投票

有多种选择。其中之一正在使用前台服务。

前台服务是在后台运行的服务,并且比后台服务具有更高的优先级,这意味着当应用程序关闭时它不太可能被系统杀死。

这是示例代码片段:

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

1
投票

除了 @MarcM 答案之外,添加“startMyOwnForeground”,它应该适用于 Android 9+

在你的片段中:

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

0
投票

快速解决方案:只需粘贴以下代码

val vibratePattern = longArrayOf(0, 1000, 1000)
if (audioManager.ringerMode != AudioManager.RINGER_MODE_SILENT) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    val vibrationEffect = VibrationEffect.createWaveform(vibratePattern,0)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        vibrate(
            vibrationEffect,
   VibrationAttributes.createForUsage(VibrationAttributes.USAGE_RINGTONE)
        )
    } else {
        vibrate(
            vibrationEffect,
            AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE).build()
        )
    }
}

解释:

只有一个参数的振动函数仅适用于前台。

/**
 * Vibrate with a given effect.
 *
 * <p>The app should be in the foreground for the vibration to happen.</p>
 *
 * @param vibe {@link VibrationEffect} describing the vibration to be performed.
 */
@RequiresPermission(android.Manifest.permission.VIBRATE)
public void vibrate(VibrationEffect vibe) 

此功能也适用于后台

/**
 * Vibrate with a given effect.
 *
 * <p>The app should be in the foreground for the vibration to happen. Background apps should
 * specify a ringtone, notification or alarm usage in order to vibrate.</p>
 *
 * @param vibe       {@link VibrationEffect} describing the vibration to be performed.
 * @param attributes {@link VibrationAttributes} corresponding to the vibration. For example,
 *                   specify {@link VibrationAttributes#USAGE_ALARM} for alarm vibrations or
 *                   {@link VibrationAttributes#USAGE_RINGTONE} for vibrations associated with
 *                   incoming calls.
 */
@RequiresPermission(android.Manifest.permission.VIBRATE)
public void vibrate(@NonNull VibrationEffect vibe, @NonNull VibrationAttributes attributes)
© www.soinside.com 2019 - 2024. All rights reserved.