在Android 10下每10分钟获取一次GPS-最佳做法?

问题描述

我设法使某些代码能够每10分钟获取一次gps数据,但是我 不确定我是否做对了。我正在寻求建议。

我们有一个在过去5年中一直在使用的应用程序,最初在Samsung S6上运行,现在 从S7到S20FE

我们需要每10分钟收集一次GPS,加速度计和磁力计读数 农艺师电话。

这些读数被缓存到手机上的MysqL表中,并通过网络api发送 (如果用户已连接到网络)到总部。

通过运行在办公室服务器上的算法对它们进行实时处理,以检测是否 电话用户是“活跃”还是“死亡”。 这是基于不断变化的GPS,运动,不断变化的罗盘方位和大量(某种AI)处理的结果。

结果显示在WH&S监视屏幕上,并发出各种警报作为时钟 从2小时(从生命的最后迹象开始)开始倒数到零。

用户是在偏远地区操作机器的农业研究技术人员 在澳大利亚拥有。

发出警报(向经理发送短信,自动电话)时,监视屏幕会显示 我们有足够的信息来告诉他们电池是否没电,或不在网络区域内,或者 看起来是一个真实的事件。

最近,我设法让客户为我分配了15小时的预算,以处理所有不推荐使用的预算 编码并用现代的属性方法替换。

每个新版的Android似乎都使我的工作越来越困难-我想描述一下 我正在做些什么以获取有关我是否要以正确的方式或是否要这样做的反馈 有更好的方法

我确定肯定会有很多其他开发人员正在经历同样的事情 过程。

我最大的问题是:

public class GoogleLocationAlarmReceiver extends WakefulbroadcastReceiver

现在不推荐使用WakefulbroadcastReceiver。

匆忙阅读开发人员文档后,我将AlarmManager替换为 JobScheduler。

最短时间为9分钟,最长时间为10分钟,我看到了相当规律的捕获 GPS在9到14分钟之间的任何时间-我可以忍受,并且电池电量消耗超过20% 12个小时。

但是,这是在三星S7上。

当我在Android 10设备上尝试此操作时,我发现GPS每两小时只能通过一次。 仔细阅读“打ze”的工作原理后,我发现它关闭了JobScheduler。

没有任何调整应用程序电源管理器设置(即将我的应用程序列入白名单)的情况。

然后我意识到不推荐使用AlarmManager本身,而仅推荐使用WakefulbroadcastReceiver类。

所以我改为:

public class GoogleLocationAlarmReceiver extends broadcastReceiver

并在我的代码中引发并释放了自己的唤醒锁。

我还必须在有通知的情况下在前台运行任何被调用的服务。

除了其他一些出牙问题,我还发现这在使用15%电池的S20上坚如磐石 超过12小时。

我们尚未将此版本发布给现场工作人员,所以我不知道还有什么地方会出错。

因此,请查看我的代码,并告诉我这是好是坏做法: 这些代码都不是我自己的-这是我从其他帖子中收集到的代码的拼凑而成。

这是我的gradle设置的一部分:

{
    compileSdkVersion 29
    buildToolsversion "29.0.0-rc2"

    defaultConfig
            {
                applicationId "au.com.redacted.ktr.ktr"
                minSdkVersion 26
                targetSdkVersion 29
                versionCode 176
                versionName "176"
            }

以下是主要活动的OnResume中的一些代码,可将GPS读数踢为 应用程序启动后:

private void startGoogleLocationAlarmManager()
{
    Context context = getBaseContext();
    alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    GoogleLocationIntent = new Intent(context,GoogleLocationAlarmReceiver.class);
    pendingIntent = PendingIntent.getbroadcast(context,GoogleLocationIntent,0);

    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.add(Calendar.SECOND,2);

    AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(
            calendar.getTimeInMillis(),pendingIntent);
    alarmManager.setAlarmClock(alarmClockInfo,pendingIntent);
}

这是GoogleLocationAlarmReceiver中的一些代码

public class GoogleLocationAlarmReceiver extends broadcastReceiver
{
    private Context thisContext;
    public PowerManager.WakeLock wakeLock;

    @Override
    public void onReceive(Context context,Intent intent)
    {
        thisContext = context;
        //
        // brute force get a wakelock to make sure we complete everything here before app goes to sleep
        //
        PowerManager powerManager = (PowerManager)   thisContext.getSystemService(POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"galR:MyWakelockTag");
        wakeLock.acquire();
        listofTasksTodo();
    }

    public void listofTasksTodo()
    {
        //
        // reset alarm for 10 minutes time
        //
        thisContext.startForegroundService(new Intent(thisContext,AlarmClockSetForegroundService.class));
        //
        // getting ready to start service "GoogleLocationServiceV2"
        // This is the first of a number of services that we need to run,one after the other.
        // but for this code snippet I will only show the GPS code being run 
        //
        Intent service = new Intent(thisContext,GoogleLocationServiceV2.class);
        LocalbroadcastManager.getInstance(thisContext).registerReceiver(
                LocalNetworkMessageReceiverLocations,new IntentFilter("NetworkActivityCompletedLocations"));
        //
        // Now kick off the GoogleLocationServiceV2 service
        //

        thisContext.startForegroundService(service);

    }

    
    private broadcastReceiver LocalNetworkMessageReceiverLocations = new broadcastReceiver()
    {
        // 
        // this receiver is called after gps data has been collected and sent to 
        // server via web api
        //
        // There is a hell of a lot of code that I am not showing here
        //
    @Override
        public void onReceive(Context context,Intent intent)
        {
            boolean boolSuccess = intent.getBooleanExtra("boolSuccess",true);
            String strReturnedFrom = intent.getStringExtra("strReturnedFrom");
            Log.i(TAG,"broadcast Receiver-" + strReturnedFrom ) ;

                    LocalbroadcastManager.getInstance(context).unregisterReceiver(LocalNetworkMessageReceiverLocations);
                    //
                    // just finished "SendLocationsToServer" which was called by GoogleLocationServiceV2
                    //


            if (wakeLock.isHeld())wakeLock.release();
    }

这是AlarmClockSetForegroundService的代码

public class AlarmClockSetForegroundService extends Service {

    private static final String LOG_TAG = "FG:AlarmClockService";
    private Context thisContext;


    private LocalBinder mBinder = new LocalBinder();

    public class LocalBinder extends Binder {
        public AlarmClockSetForegroundService getService() {
            return null;
        }
    }

    @Override
    public int onStartCommand(Intent intent,int flags,int startId) {
        thisContext = this;
        Intent notificationIntent = new Intent(this,MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,notificationIntent,0);

        Notification notification =
                new NotificationCompat.Builder(this,GoTrial.CHANNEL_ID)
                        .setContentTitle("GoTrial Services")
                        .setContentText("Logging GPS")
                        .setSmallIcon(R.drawable.ic_android)
                        .setContentIntent(pendingIntent)
                        .setSound(null)
                        .build();
        startForeground(1337,notification);
        SetNextAlarm();

        return START_STICKY_COMPATIBILITY;
    }


    @Override
    public IBinder onBind(Intent arg0) {
        return mBinder;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        thisContext = this;
        Intent notificationIntent = new Intent(this,notification);
        SetNextAlarm();
    }

    public void onDestroy() {
        //stopSampling();
    }
    public void SetNextAlarm()
    {
        AlarmManager alarmManager = (AlarmManager) thisContext.getSystemService(Context.ALARM_SERVICE);
        Intent GoogleLocationIntent = new Intent(thisContext,GoogleLocationAlarmReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getbroadcast(thisContext,0);

        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.add(Calendar.SECOND,600);
        AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(
                calendar.getTimeInMillis(),pendingIntent);
        alarmManager.setAlarmClock(alarmClockInfo,pendingIntent);

    }

}

我不会显示GoogleLocationServiceV2的代码,因为它又长又混乱,并且会 已记录的内容-例如检查位置服务是否可用并已打开等。 如果有人想看,我会发贴。 基本上,它会非常短暂地开启定位服务并获得一个GPS,然后将其写入“缓存”, 并尝试发送它。 它不要求每隔一定时间重复GPS,因为我们很久以前发现它已被杀死 通过电源管理。

所以-请-有关此代码的鲁棒性的任何建议

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)