安卓锁定设备通知没有声音

6
我开发了一个应用程序,启动一个自定义服务并触发一个倒计时器。该服务在计时器开始和结束时运行通知。在测试过程中,我遇到了关于通知和锁屏的问题。以下是我所做的测试描述:
1)如果我运行应用程序并不让手机关闭或锁定,服务会正确播放通知声音,就好像主应用程序(活动)没有被覆盖一样。在这两种情况下,服务都能完美地触发通知。
2)如果我锁定手机并且在锁定之前应用程序在前台,服务会正确播放通知声音。
3)这就是我的问题:如果我锁定手机并且在锁定之前应用程序不在前台,则通知不会发出声音,但是服务看起来在运行,因为当我按下手机上的“开”按钮时,屏幕立即打开,它会在锁定屏幕上播放通知(声音和图标),就在我解锁手机之前。
我的服务代码取消了先前的通知,以下是在计时器结束后运行通知的代码:
private void notificacion_fin() {
    NotificationManager notificationManager = 
            (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    notificationManager.cancel(0);
    Notification not = new Notification();
    // Ponemos la nueva notificacion de que hemos acabado
    SharedPreferences preferences = this.getSharedPreferences("com.fsp.mypref", 0);
    String not_sound = preferences.getString("notification_tone","");
    not.audioStreamType = AudioManager.STREAM_NOTIFICATION;
    not.sound = Uri.parse(not_sound);
    if (tipo_cronometro == 1) {
        not.icon = R.drawable.ic_stat_notify_time;
        not.tickerText = "Task has finished";
    } else {
        not.icon = R.drawable.ic_stat_notify_complete;
        not.tickerText = "Type 2 task has finished";
    }
    not.when = System.currentTimeMillis();
    not.defaults |= Notification.DEFAULT_VIBRATE;
    not.vibrate = new long[] {300,300,300,300,300};
    not.flags |= Notification.FLAG_AUTO_CANCEL;
    Intent notificationIntent = new Intent(this, MyActivity.class);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
    not.setLatestEventInfo(this, "My app", not.tickerText, contentIntent);
    notificationManager.notify(0, not); 
    notificacion = true;
}

我怀疑我的问题可能与上下文有关, 可能吗?有人知道发生了什么吗? 为什么我的第三个测试不能正确运行?
欢迎任何帮助。
提前致谢。

P.S.:当我说通知声音时,我的意思是声音+图标。


你能描述一下你是如何解决这个问题的吗?我也遇到了同样的问题...你能发一下你的正确代码吗? - user3233280
1个回答

2

每当您锁定屏幕(通常在一两分钟内),手机会进入睡眠模式。您有三个选项,其中两个是更好的。

  1. 在服务上使用startForeground。这样,它将处于前台。但它仍然受到睡眠模式的影响。
  2. 使用WAKE_LOCK - 这是我最喜欢的选项,但它需要在应用程序中获得额外的权限,这通常是普通用户不理解的。
  3. 使用Alarm Manager设置闹钟 - 由于播放通知几乎不需要处理时间,这可能是最好的方法,然后当闹钟触发时,您会发送广播,这将导致BroadcastReceiver播放通知音。

如果您需要一个可视化倒计时器,则也要运行该服务,但不依赖于WAKE_LOCK使服务保持唤醒状态。服务还可以被销毁,如果用户拥有一部糟糕的手机或尝试使用占用太多RAM的应用程序-我的手机可能会杀掉它,因为我的手机很烂。

我喜欢使用锁屏,但Alarm Manager可能是最好的方法。

Context将保持不变,无论手机是醒着还是睡着。上下文基于运行的进程/类/代码块。如果上下文引起问题,我希望它能抛出异常并强制关闭。


我正在研究wake_lock,这对我来说似乎更容易。如果我这样做,我必须在我的通知、例程的第一行之前放置wakeLock.acquire(),并在最后一行放置wakeLock.release()吗?还是我必须采取不同的方法?此外,wakeLock.acquire()会打开屏幕,还是只有在屏幕先前打开以允许不关闭时才会运行?对于我的目的,四个标志中哪一个是最好的?谢谢。 - Tibor
您需要一个可以在屏幕开启或关闭时获取的部分唤醒锁,它只会让 CPU 保持唤醒状态。您将在服务创建时获取该锁,并在服务的 ondestroy 中释放它。 - Reed
保持CPU的唤醒状态会消耗很多电池,因此最好使用闹钟来实现。 - dsandler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接