按下电源按钮后振动器不振动?

Vibrator does not vibrate after power button is pressed?

我有一个调用振动器的服务。

[Service]
public class MyService : Service
{
    System.Threading.Timer timer;

    public MyService()
    {
    }

    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {

        timer = new System.Threading.Timer( getCurrentPendingObjects, null, 100, Timeout.Infinite );

        return StartCommandResult.Sticky;
    }

    public override bool OnUnbind( Intent intent )
    {
        return base.OnUnbind( intent );
    }

    public override IBinder OnBind(Intent intent)
    {           
        binder = new MyServiceBinder( this );

        return binder;
    }   

    private void getCurrentPendingObjects( Object state )
    {
        Vibrator vibrator = (Vibrator)context.GetSystemService( Context.VibratorService );

        long [] vibrationPatern = new long[ ] { 100, 170 };
         vibrator.Vibrate( vibrationPatern, 1 );
    }
}

一切正常,直到我按下电源按钮导致屏幕关闭,设备进入睡眠模式。 服务好像继续工作,但是震动器停止震动了。

嗯,你制作的应用似乎很有趣...:P

我认为要保留服务 运行 您需要一个 WakeLock https://developer.xamarin.com/api/type/Android.OS.PowerManager+WakeLock/

A wake lock is a mechanism to indicate that your application needs to have the device stay on.

Any application using a WakeLock must request the android.permission.WAKE_LOCK permission in an element of the application's manifest. Obtain a wake lock by calling PowerManager.NewWakeLock(WakeLockFlags,String).

Call PowerManager+WakeLock.Acquire to acquire the wake lock and force the device to stay on at the level that was requested when the wake lock was created.

Call PowerManager+WakeLock.Release when you are done and don't need the lock anymore. It is very important to do this as soon as possible to avoid running down the device's battery excessively.

您或许可以这样做:

[Service]
public class MyService : Service
{
    System.Threading.Timer timer;
    
    private PowerManager _powerManager;
    private PowerManager.WakeLock _wakeLock;

    public MyService()
    {
    }

    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {
         _powerManager = (PowerManager) GetSystemService(PowerService);
        _wakeLock = _powerManager.NewWakeLock(WakeLockFlags. Partial, "Vibrator");
        _wakeLock.Acquire();

        timer = new System.Threading.Timer( getCurrentPendingObjects, null, 100, Timeout.Infinite );

        return StartCommandResult.Sticky;
    }

    public override bool OnUnbind( Intent intent )
    {
         if (_wakeLock.IsHeld)
            _wakeLock.Release();
        return base.OnUnbind( intent );
    }

    public override IBinder OnBind(Intent intent)
    {           
        binder = new MyServiceBinder( this );

        return binder;
    }   

    private void getCurrentPendingObjects( Object state )
    {
        Vibrator vibrator = (Vibrator)context.GetSystemService( Context.VibratorService );

        long [] vibrationPatern = new long[ ] { 100, 170 };
         vibrator.Vibrate( vibrationPatern, 1 );
    }
}

此外,您还需要在清单中获得此权限

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

完成后释放它:

if (_wakeLock.IsHeld)
      _wakeLock.Release();

Wake locks 将使系统保持活动状态,例如:

PowerManager powerManager = (PowerManager)Application.Context.GetSystemService(Application.PowerService);
Android.OS.PowerManager.WakeLock wakeLock = powerManager.NewWakeLock(WakeLockFlags.Partial, "Whosebug");
wakeLock.Acquire();

注意:完成后请解锁,因为这会降低电池寿命:

wakeLock.Release();

注意:清单所需权限

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

Android 文档:https://developer.android.com/reference/android/os/PowerManager.html

如果您使用 BroadcastReceiver,您可以连接到 Screen Off Action。我可以在我的设备上按如下方式启动服务。

public class MyReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        if (intent.Action.Equals(Intent.ActionScreenOff))
        {
             Application.Context.StartService(new Intent(Application.Context, typeof(MyService)));
        }
    }
}

只需注册接收器:

IntentFilter filter = new IntentFilter(Intent.ActionScreenOff);
RegisterReceiver(new MyReceiver(), filter);