2014-03-19 29 views
6

我正在开发一个应用程序,其中我需要当前经纬度和设备的长度。 获取纬度/经度的时间范围将由服务器决定。只要需要获取纬度/经度,服务器就会发送通知。当设备从 得到服务器通知时,同时设备将其位置发送到服务器。如何在需要时在服务器上发送设备的位置

一些条件:

  • 我想经/纬即使设备不具备GPS

  • 如果用户不触摸或点击该通知,然后我也想取得 lat/long,即使设备处于睡眠模式。

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

回答

20

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

这种方法需要,你必须实现某些服务器(例如,使用PHP Web服务器),使用户与它交流,因此流程将是:

  1. 你的服务器发送一个广播消息给所有注册的设备,告诉他们必须注册GCM服务。

  2. 的设备得到的消息,并且您实现BroadcastReceiver得到经度和纬度,并将其发送给远程服务器,说http://www.mysuperserver.com/getlonglat.php,通过POST请求。

  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服务器已经知道该用户已注册whithin项目,并给了他一个regid

  4. 下一步是通知您自己的远程服务器,用户已经这样做了,并保存了它已经给出的地方regid,以便您稍后可以向他们发送消息。所以在客户端,请对您的服务器一个HTTP POST请求发送该regid并处理它与somethat这样的:

    $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的坐标似乎没有太多的解决方案,但也有一些。这将是一个例子:​​

更多关于这:

+1

非常好的答案。 – MKJParekh

+0

你的答案很有用,但并不完全符合我的要求。 – Dev

0

这里是我做到了。

  1. 取和这里描述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. 创建一个接收器来侦听网络的变化,以及通过无线网络时只需发送所有数据到您的服务器。只有当特定数量的条目已经累积或定期间隔发送时,您才可以更智能。

  5. 或者,服务器可以通过GCM通知向应用程序发送ping,这也可以触发向您的服务器发送数据。 this是一个神奇的教程来描述发送GCM消息到应用程序。

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

希望这会有所帮助。

相关问题