Как отправить местоположение устройства на сервер при необходимости
Я разрабатываю приложение, в котором мне нужен текущий lat и long устройства. Временной интервал для получения lat / long будет решаться сервером. Сервер отправляет уведомление, когда требуется выбрать lat / lang. Когда устройство получает уведомление с сервера, в то же время устройство отправляет свое местоположение на сервер.
Некоторые условия:
-
Я хочу lat / long, даже если у устройства нет gps
- Запрашивать пароль перед удалением приложения
- Служба зависает в WaitForExit после вызова командного файла
- Использование Process.Start () для запуска процесса как другого пользователя из службы Windows
- Получение контекста приложения
- Слушатель Android Location в службе не работает, пока я не активирую WiFi / мобильную сеть
-
если пользователь не коснулся или не щелкнул уведомление, то также хочу получить lat / long, т.е. даже если устройство находится в спящем режиме.
-
Также я не хочу запускать фоновый сервис в течение всего дня, поскольку он потребляет аккумулятор устройства.
- Ошибка ссылки на службу: не удалось сгенерировать код для ссылки на службу
- Приложение Spring Boot как услуга
- Как SID отличается от имени службы в Oracle tnsnames.ora
- Должен ли ServiceStack быть служебным слоем в приложении MVC или должен ли он вызвать сервисный уровень?
- Что такое нелексические времена жизни?
- Как программно заставить обнаружение услуг с низким энергопотреблением Bluetooth на Android без использования кеша
- Использование Alarmmanager для запуска службы в определенное время
- Как автоматически перезапустить службу, даже если пользователь закроет ее?
Я бы определенно предложил использовать Google Cloud Messaging
здесь. Это имеет то преимущество, что, как только устройство запускает ваше приложение, вы можете сделать его зарегистрированным на GCM
и вы можете отправить им сообщение, которое заставит их зарегистрировать свои координаты в вашей базе данных.
Такой подход потребует, чтобы вы реализовали некоторый сервер (например, веб-сервер с PHP) и заставили пользователей общаться с ним, поэтому stream будет:
-
Ваш сервер отправляет широковещательное сообщение всем зарегистрированным устройствам, сообщающим им, что они должны зарегистрироваться в службе
GCM
. -
Устройства получают сообщение, и вы внедряете
BroadcastReceiver
чтобы получить как широту, так и долготу и отправить его на ваш удаленный сервер, скажемhttp://www.mysuperserver.com/getlonglat.php
, через запросPOST
. -
Ваш сервер принимает оба параметра, и вы их сохраняете или делаете все, что вам нужно.
Если вы хотите следовать этому подходу, выполните следующие действия:
-
Перейдите на страницу https://console.developers.google.com . С вашей учетной записью Google зарегистрируйте новый проект. Это предоставит вам ключ API и идентификатор отправителя.
-
Вам нужно будет сделать регистрацию устройства против вашего проекта в
GCM
. Вы можете добиться этого, импортировавGoogle Play Services
в свой проект, и после этого сделайте что-нибудь похожее на это:GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context); final String regid = gcm.register("YOUR_SENDER_ID");
-
В это время сервер
GCM
уже знает, что этот пользователь зарегистрировался в вашем проекте и дал емуregid
. -
Следующим шагом будет информирование вашего собственного удаленного сервера, что пользователь сделал это, и сохранить где-то
regid
что он был дан, поэтому вы можете позже отправлять им сообщения. Поэтому на стороне клиента сделайте запросHTTP POST
против вашего сервера, отправляющего этотregid
и обработайте его примерно так:$regid = $_POST['regid']; if (($regId) && ($ipAddr)) sql_query("INSERT INTO gcm_subscribers(regid) VALUES($regid')");
-
После этого вы знаете, кто уже зарегистрировался в вашей базе данных. Вы можете
SELECT
всех пользователей и отправить им сигнал, чтобы отправить обратно свои координаты. В следующем примере параметрами будут, во-первых, массив идентификаторов регистрации и, во-вторых, сообщение для отправки (например,$messageData = "sendMeYourCoords!"
).function sendNotification($registrationIdsArray, $messageData) { $apiKey = "YOUR_API_KEY"; $headers = array("Content-Type:" . "application/json", "Authorization:" . "key=" . $apiKey); $data = array( 'data' => $messageData, 'registration_ids' => $registrationIdsArray ); $ch = curl_init(); curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers ); curl_setopt( $ch, CURLOPT_URL, "https://android.googleapis.com/gcm/send" ); curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 ); curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode($data) ); $response = curl_exec($ch); curl_close($ch); return $response; }
-
Когда-то в вашем клиенте просто обработайте это сообщение
GCM
и сделайте еще одинPOST
другомуURL
на удаленном сервере и передайте емуlongitude
иlatitude
. Для обработки сообщений я включаю несколько ссылок ниже.
И для получения координат без GPS кажется, что не слишком много решений, но есть некоторые. Это будет пример: как получить значение Latitude Longitude без использования GPS в Android?
Подробнее об этом:
-
Ссылка на облачные сообщения Google
-
Уведомления Android Push с помощью Google Cloud Messaging GCM – пример Android
-
Google Cloud Messaging с использованием PHP
-
Соединение между PHP (сервером) и Android (клиент) Использование HTTP и JSON
-
Notificaciones Push Android: Google Cloud Messaging (GCM). Реализованный клиент (Nueva Versión) (испанский)
Вот что я сделал.
-
Выбирать и хранить местоположения с помощью поставщика плавного доступа в сервисах Google Play, как описано здесь здесь
-
Я бы не стал настраивать службу, вместо этого вы должны вызвать тревогу, запрашивающую последнее доступное местоположение. Это еще больше экономит аккумулятор, поскольку приложение не ищет поисковую область, но использует то, что недавно запросили другие приложения. На мой взгляд, полученный ответ довольно точный. Так что сделайте что-нибудь подобное
public class LocationReceiver extends BroadcastReceiver { // Restart service every 30 seconds private static final long REPEAT_TIME = 1000 * 60 * 5; private static final long REPEAT_DAILY = 1000 * 60 * 60 * 24; @Override public void onReceive(Context context, Intent intent) { Log.v("TEST", "Service loaded at start"); AlarmManager service = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Calendar cal = Calendar.getInstance(); cal.add(Calendar.SECOND, 0); Intent i = new Intent(context, ServiceStartReceiver.class); PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,PendingIntent.FLAG_CANCEL_CURRENT); service.setInexactRepeating(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), REPEAT_TIME, pending); } }
-
Поскольку вы не упомянули, что хотите обновления в режиме реального времени, я думаю, вы можете просто сбросить все данные в базе данных temp sqlite.
-
Создайте приемник для прослушивания изменений в сети, и когда Wi-Fi просто отправит все данные на ваш сервер. Вы можете быть немного умнее, делая это, отправляя только тогда, когда определенное количество записей накапливается или периодически.
-
В качестве альтернативы сервер может отправить ping в приложение с помощью функции mnotification GCM, которая также может инициировать отправку данных на ваш сервер. это удивительный учебник для описания отправки сообщений GCM в приложение.
-
Наконец, здесь упоминаются некоторые очень интересные страtagsи размещения. Вы можете указать, когда следует активировать сохранение местоположения на основе активности пользователя или какого-либо другого контекста.
Надеюсь это поможет.