2016-07-25 8 views
0

На работе мы создали приложение, которое будет отслеживать маршруты, которые пользователь делает с работы, и у нас есть функция автоматической записи, но это не как мы хотели бы. Кажется, что автоматическая система отключается ОС через день или два бездействия (телефоны даже не двигаются за это время, они используются только для тестирования в основном).Автоматически запускать приложение через GPS-события на iOS и Android с Xamarin.Forms

В iOS мы используем CLRegions для создания пары областей вокруг текущего местоположения пользователя, существует 5 областей, созданных в точном местоположении пользователя с разными радиусами и 12, созданных в круге вокруг пользователя на расстоянии 10 метров (они имеют радиус 80 метров). Объекту CLLocationManager также предписывается начать мониторинг значительных изменений и посещений (хотя их еще нужно уволить даже один раз).

На Android мы используем Geofences через API LocationServices, и здесь у нас есть только 5 инкрементных радиусов вокруг текущего местоположения пользователя. Если пользователь закрывает приложение на Android или перезагружает свой телефон, он запустит фоновый сервис, который будет повторно инициализировать геообъекты и начать их контролировать.

Обе системы работают очень хорошо, когда я тестирую их, немного выходя на улицу, но кажется, что через день или два бездействия (ака выходные) они перестают работать. Я отлаживал это довольно долгое время, и хотя он стал лучше, он все еще не идеален.

Возможно ли иметь надежную систему автоматического запуска приложения в фоновом режиме при срабатывании геозонности/области независимо от того, как долго приложение отключено? Я знаю, что оба ОС выполняют фоновые задачи совсем по-другому, но я не совсем уверен в долгосрочных ограничениях использования GPS таким образом.

мы делаем приложение написано в Xamarin форм, но эти системы написаны на их родном проекте (все еще в C#, но полный доступ ко всей родной платформе)

ответ

0

вещь с Android услуг, является то, что OS убивает фоновый сервис, так как считается низким приоритетом, а затем перезапускается с интервалом времени. Это может произойти несколько раз через несколько дней, каждый раз увеличивая время до перезапуска службы (некоторые телефоны используют только установленное время, не увеличивая).

Мое предложение состоит в том, что если вы хотите всегда на службе, вам нужно сделать его в foreground service. Я бы привел несколько примеров кода о том, как это реализовать, но я не очень хорошо знаю Xamarin, поэтому я не хочу давать вам плохие примеры.

Другой подход заключается в использовании AlarmManager с PendingIntent, чтобы проверить, запущена ли служба и запустить ее, если нет. Просто имейте в виду, что если вы делаете это слишком часто, это может привести к заметному истощению батареи, но если вы не делаете этого достаточно часто, вы можете потенциально упустить события геозонности.

Надеюсь, что это поможет, и удачи!

UPDATE # 1

Вот примеры кода для обоих, имеющих службу на переднем плане и запуск AlarmManager.

переднего плана

Это правильно самый простой способ сохранить свое приложение в живых.

public class ForegroundService extends Service{ 
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId){ 
     Notification notification = new NotificationCompat.Builder(this) 
       .setSmallIcon(R.mipmap.icon) 
       .setContentTitle("TITLE") 
       .setContentText("This is an example notification!") 
       .build(); 
     startForeground(ID, notification); 
     //Do your stuff here 
    } 

    @Override 
    public void onDestroy(){ 
     super.onDestroy(); 
     stopForeground(true); 
     //If you have anything else you want done here... 
    } 
} 

AlarmManager

Это будет постоянно пытаться создать эту услугу в интервале вы установили (10 минут для этого примера). Однако здесь есть несколько подводных камней. Во-первых, из-за того, что Android 6.0 вводит Doze Mode, AlarmManager может не загореться, пока телефон спит, а это значит, что служба может быть мертва в течение некоторого времени. Во-вторых, это то, что это вызывает функцию onStartCommand несколько раз, поэтому для этого вам понадобится логика.

public class AlwaysOnService extends Service{ 
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId){ 

     AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE); 
     PendingIntent pi = PendingIntent.getService(this, requestCode, new Intent(this, AlwaysOnService.class), PendingIntent.FLAG_UPDATE_CURRENT); 
     am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + MIN_10_IN_MILLIS, pi); 
     //Do your stuff here 
     return START_STICKY; 
    } 

    @Override 
    public void onDestroy(){ 
     super.onDestroy(); 
     AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE); 
     PendingIntent pi = PendingIntent.getService(this, requestCode, new Intent(this, AlwaysOnService.class), PendingIntent.FLAG_NO_CREATE); 
     if(pi != null){ 
      am.cancel(pi); 
      pi.cancel(); 
     } 
     //If you have anything else you want done here... 
    } 
} 

Из этих двух, установив службу в качестве переднего плана службы, вероятно, проще всего, если вы на самом деле не может быть, что, то AlarmManager является маршрут принять.

+0

Благодарим за информацию, что я не был полностью осведомлен о том, что даже служба на фоне будет остановлена ​​системой через некоторое время на Android. Как вы думаете, есть ли способ обнаружить, когда намерение прекращено и действует на это? Ох, и вы можете легко дать образец Java, по большей части это другой синтаксис, а не на самом деле другой язык с Xamarin (хотя параметры манифеста определены в коде C#, а компилятор обрабатывает манифест XML) – zezioen

+0

Что касается обнаружения для остановки службы вам понадобится процесс проверки того, что, в свою очередь, может быть убито, что возвращает нас к квадрату. Я обновил свой ответ с помощью образцов кода для службы переднего плана, а диспетчер аварийных сообщений перезапустил службу периодически. Надеюсь, это сработает для вас! –