【问题标题】:How to send location of the device on server when needed需要时如何在服务器上发送设备的位置
【发布时间】:2014-04-25 12:50:48
【问题描述】:

我正在开发一个应用程序,其中我需要设备的当前纬度和经度。 获取纬度/经度的时间范围将由服务器决定。每当需要获取 lat/lang 时,服务器都会发送通知。当设备收到通知时 服务器,同时设备将其位置发送给服务器。

一些条件:

  • 即使设备没有 GPS,我也想要纬度/经度

  • 如果用户没有触摸或点击通知,那么我也想获取 纬度/经度,即即使设备处于睡眠模式。

  • 另外,我不想整天运行后台服务,因为 它会消耗设备的电池。

【问题讨论】:

    标签: android service push-notification


    【解决方案1】:

    我肯定会建议在这里使用Google Cloud Messaging。这样做的好处是,一旦设备运行您的应用程序,您可以使其注册到 GCM,并且您可以向他们发送一些消息,让他们将其坐标注册到您的数据库中。

    这种方法需要你必须实现一些服务器(例如,使用 PHP 的 Web 服务器)并让用户与之通信,所以流程是:

    1. 您的服务器向所有已注册的设备发送一条广播消息,告诉它们必须注册GCM 服务。

    2. 设备收到消息,您实现 BroadcastReceiver 以获取纬度和经度,然后通过 POST 请求将其发送到您的远程服务器,例如 http://www.mysuperserver.com/getlonglat.php

    3. 您的服务器接受这两个参数,然后您保存它们或执行任何您需要的操作。

    如果您想遵循这种方法,您必须遵循以下步骤:

    1. 转到https://console.developers.google.com。使用您的 Google 帐户注册一个新项目。这将为您提供 API 密钥和发件人 ID。

    2. 您需要在GCM 中针对您的项目注册设备。您可以通过在项目中导入Google Play Services 来实现这一点,一旦完成,请执行类似的操作:

      GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
      final String regid = gcm.register("YOUR_SENDER_ID");
      
    3. 此时,GCM 服务器已经知道该用户已在您的项目中注册并给了他一个regid

    4. 下一步是通知您自己的远程服务器用户已这样做,并将已提供的regid 保存在某处,以便您以后可以向他们发送消息。因此,在客户端,对发送 regid 的服务器发出 HTTP POST 请求,并使用以下方式处理它:

      $regid = $_POST['regid'];
      
      if (($regId) && ($ipAddr))
        sql_query("INSERT INTO gcm_subscribers(regid) VALUES($regid')");
      
    5. 一旦完成,您就知道谁已经在您的数据库中注册了。您可以SELECT所有用户并向他们发送信号,将他们的坐标发回给您。在以下示例中,参数首先是一组注册 ID,其次是要发送的消息(例如,$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;
      }
      
    6. 在您的客户端中,只需处理该 GCM 消息,然后将另一个 POST 发送到您的远程服务器上的另一个 URL,并将 longitudelatitude 传递给它。为了处理这些消息,我在下面添加了一些链接。

    对于没有 GPS 的情况下获取坐标似乎没有太多解决方案,但有一些解决方案。这就是一个例子:How to get Latitute Longitude value without using GPS in Android?

    更多信息:

    【讨论】:

    • 您的回答很有用,但不完全符合我的要求。
    【解决方案2】:

    这就是我所做的。

    1. 使用此处所述的 Google Play 服务融合位置提供程序获取和存储位置here

    2. 我会避免设置服务,而是您应该触发警报,请求最后一个可用位置。这进一步节省了电池电量,因为该应用程序不会寻找位置值,而是使用其他应用程序最近可能请求的内容。在我看来,收到的回复是相当准确的.. 所以做这样的事情

      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);
      
      }
      }
      
    3. 由于您没有提到要实时更新,我认为您可以将所有数据转储到临时 sqlite 数据库中。

    4. 创建一个接收器来监听网络的变化,当通过 wifi 时,只需将所有数据发送到您的服务器。通过仅在累积一定数量的条目时或定期发送时,您可以更聪明地执行此操作。

    5. 或者,服务器可以通过 GCM mnotification 向应用发送 ping,这也可以触发向您的服务器发送数据。this 是一个很棒的教程,用于描述向应用发送 GCM 消息。

    6. 最后提到了一些非常有趣的定位策略here。您可以根据用户活动或其他上下文确定何时触发您的位置保存。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-20
      • 1970-01-01
      • 2016-11-02
      相关资源
      最近更新 更多