Android AlarmManager.setExactAndAllowHileIDle()和WakefulBroadcastReceiver在一些新生产的低价设备中不起作用

Android AlarmManager.setExactAndAllowHileIDle()和WakefulBroadcastReceiver在一些新生产的低价设备中不起作用,android,alarmmanager,android-doze-and-standby,Android,Alarmmanager,Android Doze And Standby,我想这个问题在stackoverflow中被问了很多次,但是仍然有很多人在努力解决这个问题 在我的android应用程序中,我必须每半小时唤醒一次设备,以获取当前位置并将其发送到服务器。为此,我使用了AlarmManager和setExactAndAllowHileIDLE()方法和WakefulBroadcastReceiver。它在三星、LG(Nexus)、索尼、松下、联想、摩托罗拉、Micro max等几乎所有标准/流行设备上都能正常工作……但其他一些设备(主要是中国设备)不支持或无法使用

我想这个问题在stackoverflow中被问了很多次,但是仍然有很多人在努力解决这个问题


在我的android应用程序中,我必须每半小时唤醒一次设备,以获取当前位置并将其发送到服务器。为此,我使用了
AlarmManager
setExactAndAllowHileIDLE()
方法和
WakefulBroadcastReceiver
。它在三星、LG(Nexus)、索尼、松下、联想、摩托罗拉、Micro max等几乎所有标准/流行设备上都能正常工作……但其他一些设备(主要是中国设备)不支持或无法使用
setExactAndAllowHileidle()让设备从睡眠模式中唤醒。
。我已经在leeco letV(Android OS 6.1)设备上测试了它,该设备不允许alarm manager在特定的时间间隔内唤醒

我在下面提到的代码部分:

UserTrackingReceiverIntentService.java

public class UserTrackingReceiverIntentService extends IntentService {

    public static final String TAG = "UserTrackingReceiverIntentService";
    Context context;
    public UserTrackingReceiverIntentService() {
        super("UserTrackingReceiverIntentService");
    }

    @TargetApi(Build.VERSION_CODES.M)
    @Override
    protected void onHandleIntent(Intent intent) {
        this.context = this;

        if (!Util.isMyServiceRunning(LocationService.class, context)) {
            context.startService(new Intent(context, LocationService.class));
        }

        Calendar calendar = Calendar.getInstance();
        //********************************** SETTING NEXT ALARM *********************************************
            Intent intentWakeFullBroacastReceiver = new Intent(context, SimpleWakefulReceiver.class);
            PendingIntent sender = PendingIntent.getBroadcast(context, 1001, intentWakeFullBroacastReceiver, 0);
            AlarmManager alarmManager = (AlarmManager) context.getSystemService(context.ALARM_SERVICE);

        if (calendar.get(Calendar.MINUTE) >= 0 && calendar.get(Calendar.MINUTE) < 30) {
            calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY));
            calendar.set(Calendar.MINUTE, 30);
            calendar.set(Calendar.SECOND, 0);
        } else if (calendar.get(Calendar.MINUTE) >= 30) {
            if (calendar.get(Calendar.HOUR_OF_DAY) == 23) {
                calendar.set(Calendar.HOUR_OF_DAY, 0);
                calendar.add(Calendar.DAY_OF_MONTH, 1);
            } else {
                calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + 1);
            }
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
        } else {
            calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY));
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
        }

        //MARSHMALLOW OR ABOVE
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
                    calendar.getTimeInMillis(), sender);
        }
        //LOLLIPOP 21 OR ABOVE
        else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(calendar.getTimeInMillis(), sender);
            alarmManager.setAlarmClock(alarmClockInfo, sender);
        }
        //KITKAT 19 OR ABOVE
        else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            alarmManager.setExact(AlarmManager.RTC_WAKEUP,
                    calendar.getTimeInMillis(), sender);
        }
        //FOR BELOW KITKAT ALL DEVICES
        else {
            alarmManager.set(AlarmManager.RTC_WAKEUP,
                    calendar.getTimeInMillis(), sender);
        }


        Util.registerHeartbeatReceiver(context);
        SimpleWakefulReceiver.completeWakefulIntent(intent);
    }
}
由于我已从
leeco-letV
device like Settings>Battery>Align Wakeup>手动更改了一些设置,因此禁用了这两个选项。如果启用,电池可以忽略应用程序的强制唤醒

我的问题是:

  • 在这种设备中发生了什么?为什么他们不允许在特定的时间间隔内发出警报

  • 在一些设备中,如Gionee s plus报警延迟2-3分钟。。。为什么?

  • android.net.conn.CONNECTIVITY\u更改
    broad cast receiver以在网络连接更改时收听……当它在某些设备(如Gionee s plus)中不工作时,该怎么办

  • 对于不同的制造商,电池优化设置有很多变化……如果这是解决方案,可能会损害我们应用程序的后台服务


  • 嗨,我在Xiomi phone.leeco测试时遇到了同样的问题,我不太清楚Xiomi手机有自己的操作系统,即MIUI。当我们清除RAM时,清除所有应用程序执行部分应用程序在操作系统中注册。像Whatsapp和facebook等一些著名的应用程序

    我尝试过服务、报警管理器和调度程序,但没有成功

    他们提供了一些手动特定的方式来运行服务。我查过乐视,它使用的是Android操作系统

    MIUI 7.0解决方案=>安全性=>Autostart=>选择要在后台运行的应用=>重新启动 重新启动后,您的设备应该能够像其他android设备一样在后台运行应用程序服务

    根据我的说法,你可以尝试一下服务,然后检查它是否有效


    非常感谢,希望您能从中得到一些帮助。

    可能这些中国手机已经禁用了接收报警事件的应用程序wake,以节省电池寿命。我知道,一些中国制造商如果早些时候因为节约电池而关闭应用程序,就不会唤醒应用程序来接收推送通知。因此,在再次手动打开应用程序之前,操作系统不会唤醒它进行任何事件处理

    然而,这种行为是可以改变的。检查电源管理设置并进行相应更改,以允许定期或在需要时唤醒应用程序。我想可能是限制模式或类似的模式。

    我同意你的看法。 但我认为你应该尝试一下JobScheduler。 你会发现官方文件 我找到的最好的例子 我没有测试过。根据我的说法,你必须试试这个

    编辑

    如果您想在6.0或更高版本中以doze模式运行应用程序,则必须将应用程序列为白名单 退房


    Imtiyaz

    在我的android应用程序中,我必须每15分钟唤醒一次设备,以获取当前位置并将其发送到服务器。 我已经在小米米5s(安卓6.0.1)上进行了测试。当我关闭应用程序时,应用程序进入睡眠状态:(
    AlarmManager
    with
    setExactAndAllowHileId()
    不工作
    )\_(ツ)_/“

    是的,它在几乎所有标准/流行设备上都能正常工作,如三星、LG(Nexus 5X)、索尼、摩托罗拉、Pixel

    我的解决方案

    每种类型的组件元素的清单条目——
    ——都支持一个
    android:process
    属性,该属性可以指定该组件应在其中运行的进程

    您需要在您的
    AndroidManifest.xml

    像这样:

    ... 
    
    <receiver
        android:name="your.full.packagename.MyWakefulReceiver"
        android:process=":service"
        android:enabled="true"/>
    
    <service
        android:name="your.full.packagename.MyLocationService"
        android:process=":service"/>
    
    <service
        android:name="your.full.packagename.MySendService"
        android:process=":service"
        android:exported="false" />
    
    ...
    
    。。。
    ...
    
    我已经在小米米5s上测试了这个解决方案。它成功了


    我怎么看,小米固件似乎会在用户退出应用程序时终止主进程…

    你能看看我这里的问题吗?如果你能帮助我,例如在华为设备上,你必须启用AutoStart,否则就不可能发送广播。在华威Ascend Mate 7上,有一个电话管理器具有此选项在列出所有应用程序的位置自动启动。可能在您的一些测试设备上有类似的管理器。@我目前正在使用此库进行检查,希望它能有所帮助。!!让我们看看。我也开始怀疑这个问题是否可以通过以下方式解决…不在更高版本的android上使用Alarm manager,并开始在androi上使用JobSchedulerd M.@MKJParekh我研究过JobScheduler,它很酷,但我想每半小时叫醒一次设备,我读到你,我们不能在Android M和N中继续以Deze模式运行JobScheduler……然而,已经有这么多具有报警功能的设备,它们工作正常……但中国公司生产的一些新设备并不是一个好消息允许在特定的时间间隔内触发警报….设置ExactAndAllowHileidle()此方法在打瞌睡模式下工作非常好….但问题仅限于某些设备….感谢您的大力支持….我在Xiomi手机中找到了此设置,但我不知道乐视是否有相同的设置….乐视手机有这些设置吗?@himCr
    ... 
    
    <receiver
        android:name="your.full.packagename.MyWakefulReceiver"
        android:process=":service"
        android:enabled="true"/>
    
    <service
        android:name="your.full.packagename.MyLocationService"
        android:process=":service"/>
    
    <service
        android:name="your.full.packagename.MySendService"
        android:process=":service"
        android:exported="false" />
    
    ...