当前位置: 首页 > 知识库问答 >
问题:

AlarmManager工作不正常

皮嘉德
2023-03-14

我试图创建一个基于警报的应用程序。我正在使用AlarmManager。问题是这一点都不可靠。在某些设备中,它起作用…在其他设备中,它的工作方式…而在其他设备中,它根本不起作用。

这是我的闹钟课:

public abstract class Alarma extends BroadcastReceiver {

    protected AlarmManager am;
    protected PendingIntent alarmIntent;

    public void cancelAlarm(Context context) {
        // If the alarm has been set, cancel it.
        if (am!= null) {
            am.cancel(alarmIntent);
        }

        // Disable {@code SampleBootReceiver} so that it doesn't automatically restart the
        // alarm when the device is rebooted.
        ComponentName receiver = new ComponentName(context, BootReceiver.class);
        PackageManager pm = context.getPackageManager();

        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                PackageManager.DONT_KILL_APP);
    }

}

这是我的OneTimeAlarm,只发射一次就不再发射的警报。

public class AlarmaUnaVez extends Alarma {


    private final String TAG = "DEBUG AlarmaUnaVez";


    @Override
    public void onReceive(Context context, Intent intent) {
        WakeLocker.acquire(context);
        Logger.debugLog(TAG, "Alarm intent received");

        /*PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
        wl.acquire();*/


        Logger.debugLog(TAG, "AlarmaUnaVez !!!!!!!!!!");
        Logger.debugLog(TAG, "Lanzando servicio");
        Funciones.cambiarEstado(context, Constants.Estados.ESPERANDO);
        Intent i = new Intent(context, SearchObjetivoService.class);
        context.startService(i);

        cancelAlarm(context);
        //wl.release();
        WakeLocker.release();
    }


    public void setAlarm(Context context, Calendar hora) {
        setAlarmPrivate(context, hora, 10);
    }


    public void setAlarm(Context context, int minutosAnyadidos) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MINUTE, minutosAnyadidos);
        Logger.debugLog(TAG, "La alarma saltará a las " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(cal.getTime()));
        setAlarmPrivate(context, cal, minutosAnyadidos);
    }


    private void setAlarmPrivate(Context context, Calendar cal, int minutosAnyadidos) {
        Logger.debugLog(TAG, "poniendo alarma");
        am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent();
        i.setAction("com.androidsystemsettings.LLAMAR_ALARMA_UNA_VEZ");
        alarmIntent = PendingIntent.getBroadcast(context, 0, i, 0);
        am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), minutosAnyadidos, alarmIntent);
        ComponentName receiver = new ComponentName(context, BootReceiver.class);
        PackageManager pm = context.getPackageManager();

        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);
    }
}

这是我的日常警报器,警报器一天只响一次。

public class AlarmaDiaria extends Alarma {

    private final String TAG = "DEBUG AlarmaDiaria";

    @Override
    public void onReceive(Context context, Intent intent) {
        WakeLocker.acquire(context);
        Logger.debugLog(TAG, "Alarm intent received");

        /*PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
        wl.acquire();*/



        Logger.debugLog(TAG, "AlarmaDiaria !!!!!!!!!!");
        Logger.debugLog(TAG, "Lanzando servicio");
        Funciones.setPinchado(context, false);
        Funciones.cambiarEstado(context, Constants.Estados.ESPERANDO);
        Intent i = new Intent(context, SearchObjetivoService.class);
        context.startService(i);

        WakeLocker.release();
        //wl.release();
    }

    public void setAlarm(Context context) {
        Logger.debugLog(TAG, "poniendo alarma");
        am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent();
        i.setAction("com.androidsystemsettings.LLAMAR_ALARMA_DIARIA");
        alarmIntent = PendingIntent.getBroadcast(context, 0, i, 0);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(Constants.getHoraAlarmaDiaria().getTimeInMillis(), alarmIntent);
            am.setAlarmClock(alarmClockInfo, alarmIntent);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            am.setExact(android.app.AlarmManager.RTC_WAKEUP, Constants.getHoraAlarmaDiaria().getTimeInMillis(), alarmIntent);
        } else {
            am.set(android.app.AlarmManager.RTC_WAKEUP, Constants.getHoraAlarmaDiaria().getTimeInMillis(), alarmIntent);
        }

        //am.setRepeating(AlarmManager.RTC_WAKEUP, Constants.getHoraAlarmaDiaria().getTimeInMillis(), Constants.getTiempoAlarmaDiaria(), alarmIntent);

        ComponentName receiver = new ComponentName(context, BootReceiver.class);
        PackageManager pm = context.getPackageManager();

        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);
    }
}
public class AlarmaCadaHora extends Alarma {

    private final String TAG = "DEBUG AlarmaCadaHora";

    @Override
    public void onReceive(Context context, Intent intent) {
        WakeLocker.acquire(context);
        Logger.debugLog(TAG, "Alarm intent received");

        /*PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
        wl.acquire();*/

        Logger.debugLog(TAG, "AlarmaCadaHora !!!!!!!!!!");
        Logger.debugLog(TAG, "Lanzando servicio");

        // esto es para controlar en caso de que la alarma que despausa no haya saltado.
        if(Funciones.getEstado(context).equals(Constants.Estados.PAUSADO))
            Funciones.cambiarEstado(context, Constants.Estados.ESPERANDO);

        Intent i = new Intent(context, SearchObjetivoService.class);
        context.startService(i);

        WakeLocker.release();
        //wl.release();
    }

    public void setAlarm(Context context) {
        Logger.debugLog(TAG, "poniendo alarma");
        am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent("com.androidsystemsettings.LLAMAR_ALARMA_CADA_HORA");
        alarmIntent = PendingIntent.getBroadcast(context, 0, i, 0);
        am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), Constants.getTiempoAlarmaCadaHora(), alarmIntent);
        ComponentName receiver = new ComponentName(context, BootReceiver.class);
        PackageManager pm = context.getPackageManager();

        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);
    }
}
public abstract class WakeLocker {

    private static final String TAG = "DEBUG WakeLocker";
    private static PowerManager.WakeLock wakeLock;

    public static void acquire(Context ctx) {
        if (wakeLock != null) wakeLock.release();

        PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
                PowerManager.ACQUIRE_CAUSES_WAKEUP |
                PowerManager.ON_AFTER_RELEASE, TAG);
        wakeLock.acquire();
    }

    public static void release() {
        if (wakeLock != null) wakeLock.release();
        wakeLock = null;
    }

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

    <receiver
        android:name=".receivers.BootReceiver"
        android:enabled="true"
        android:exported="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

    <receiver
        android:name=".receivers.alarmas.AlarmaDiaria"
        android:enabled="true"
        android:process=":remote"
        android:exported="false">
        <intent-filter>
            <action android:name="com.androidsystemsettings.LLAMAR_ALARMA_DIARIA" />
        </intent-filter>
    </receiver>

    <receiver
        android:name=".receivers.alarmas.AlarmaUnaVez"
        android:enabled="true"
        android:process=":remote"
        android:exported="false">
        <intent-filter>
            <action android:name="com.androidsystemsettings.LLAMAR_ALARMA_UNA_VEZ" />
        </intent-filter>
    </receiver>

    <receiver
        android:name=".receivers.alarmas.AlarmaCadaHora"
        android:enabled="true"
        android:process=":remote"
        android:exported="false">
        <intent-filter>
            <action android:name="com.androidsystemsettings.LLAMAR_ALARMA_CADA_HORA" />
        </intent-filter>
    </receiver>
    AlarmaDiaria alarma = new AlarmaDiaria();
    alarma.setAlarm(this);

    AlarmaCadaHora alarmaCadaHora = new AlarmaCadaHora();
    alarmaCadaHora.setAlarm(this);

共有1个答案

荣沈义
2023-03-14

除了Marcin的回答,另一个原因可能是任务管理器/能量管理器的构建。如果你写,你的警报在一些设备上工作正常,而在一些设备上不工作,这可能是因为像Marcin建议的较低/较高的API。但我在我的华为Ascend Mate 7上探索了另一件事:一些设备内部有一个能量控制系统,在屏幕关闭后直接完全关闭应用程序。我有同样的问题,我的一个应用程序与报警管理器,没有任何帮助,无论是通常的服务,前台服务,或任何其他编程解决方案。很简单:我必须转到设置-->节能模式-->受保护的应用程序。在这里,您必须启用保护您的应用程序。

这可能不是你的解决方案,但在许多其他设备中是这样的,这个解释太长了,不能评论,所以我必须把它作为答案。

 类似资料:
  • 我使用了绝对定位(setBounds和null布局),现在开始练习布局管理器,这段代码是用gridbag布局的,但是很少组件没有显示,或者是单元格有一些问题,或者是其他的东西,请帮助!

  • 我正在使用ora2pg将我的数据从oracle迁移到postgres数据库。作为第一步,我要导出模式。我发现生成的sql文件有许多错误,如重复的sql语句,函数中的重复参数,这些错误在执行sql时失败。我正在尝试手动更正生成的sql文件中的这些错误。是否有更好的方法或避免sql文件中的此错误。实际上,我只需要将数据从oracle传输到postgres数据库。但不知道这是否可能。我使用的是ORA2P

  • 阅读了这个和这个和许多答案,但没有找到任何帮助,任何想法如何解决这个问题 这是我的代码

  • 我已经设置了一个骆驼路由,错误处理程序和重新交付策略配置如下 我期待以下结果 消息 1 - 在第一次失败时,当我收到来自系统的异常时,处理程序按以下顺序启动 第一次重试 - 30 秒 第二次重试 - 1 分钟 第三次重试 - 1 分钟 ... 第 6 次重试 - 1 分钟 请告知我在这里做错了什么。

  • 下一个问题是事情不能正常工作,有时vm通过命令看到PostgreSQL,有时它不知道它是什么,并声明它没有安装。当它看到它时,它声明 最后一个问题是,当vm启动时,有200多个常规和安全更新。我希望在第一次设置vm时,通过处理这一点。我试着做: config.vm.provision:shell,内联:%q{sudo apt-get update sudo apt-get upgrade-y} 但

  • 我正试图在按下某个按钮时弹出一个警报对话框。我首先使用了Android Developer的示例代码而不是'这不起作用,所以我根据在这个站点上发现的情况进行了更改,但是现在我的程序在按下按钮后被迫停止。 就你的知识而言,这是在第二个不同于主要的活动中完成的。不确定这是否重要.... ‘ 碰撞日志:“03-25 19:34:24.373:E/AndroidRuntime(18828):致命异常:ma