2015-06-30 27 views
0

我在兩個不同的設備上有2個Android應用。應用1靜止不動,應用2可移動。我希望應用程序1能夠找到最接近的應用程序2設備,並像snapchat一樣溝通,但我想用應用程序2的當前位置更新應用程序1。我將應用1的位置存儲在服務器中,並檢索應用2的位置並計算它們之間的距離,並通過GCM將應用1的位置發送到應用2。但事實證明這比我原先想象的更復雜。我還嘗試將移動應用程序的位置存儲在數據庫中,並在固定請求進行通信時獲取更新的位置,但這意味着更新數據庫太多。有人能給我一個關於如何高效完成這個任務的提示嗎?以下是代碼片段來計算它們之間的距離併發送位置。GCM上的2個Android應用之間的通信

function distance_slc($lat1, $lon1, $lat2, $lon2) { 
    global $earth_radius; 
    global $delta_lat; 
    global $delta_lon; 
    $distance = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($delta_lon)); 
    $distance = acos($distance); 
    $distance = rad2deg($distance); 
    $distance = $distance * 60 * 1.1515; 
    $distance = round($distance, 4); 

    return $distance; 
} 


     function compute($id, $lat, $lon) { 
     $p = getPLocation(); 
     $d = array($id, $lat, $lon); 

     foreach ($d as $index => $value) { 
     $d_pass_distance = distance_slc($p['latitude'], $p['longitude'], $d['1'], $d['2']); 

     $closest_d = 0; 
     if ($closest_d = min($d_pass_distance)) { 

      sendPLocation($d['0'], $p['latitude'], $p['longitude']); 
     } 
    } 
} 

function sendUserLocation($id, $lat, $lon) { 
//request url 
     //$url = 'https://android.googleapis.com/gcm/send'; 
     $url = 'gcm-preprod.googleapis.com:5236'; //this url is only for testing not production 
//your api key 
     $apiKey = 'myserverapikeyhere'; 


     $fields = array('id' => $id, 'latitude' => $lat, 'longitude' => $lon); 

//http header 
     $headers = array('Authorization: key=' . $apiKey, 
     'Content-Type: application/json'); 

//curl connection 
     $ch = curl_init(); 

     curl_setopt($ch, CURLOPT_URL, $url); 
     curl_setopt($ch, CURLOPT_POST, true); 
     curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
     curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields)); 

     $result = curl_exec($ch); 

     curl_close($ch); 

     echo $result; 
     } 

回答

1

想到什麼是當應用程序1客戶端想要溝通它發送消息到您的應用程序服務器。應用程序服務器然後向所有適當的移動設備發送GCM推送消息,每個設備上的應用程序2客戶端接收消息,確定其當前位置,並使用上游消息將其位置發送到應用程序服務器。應用程序服務器確定最近的設備(可能等待幾秒鐘以獲取所有各種響應),然後使用適當的信息向最近的應用程序2客戶端(以及可選的應用程序1客戶端)發送推送消息。

編輯:包含上游和下游消息的一些示例代碼。總的來說,我不包括一般消息的東西。您可以取代「內容」和「用戶名」字段與你自己的東西,並需要有不同類型的上游消息

下游消息(應用程序服務器端 - 這是Java)

public void actionPerformed(ActionEvent e) { 
    // who are we sending it to? 
    String toAddr = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"; 

    // create the message 
    Map<String, Object> message = new HashMap<String, Object>(); 
    message.put("to", toAddr); 
    message.put("message_id", myNextMessageId()); 

    HashMap<String, String> dataPayload = new HashMap<>(); 
    dataPayload.put("contents", dataInfo.getText()); 

    message.put("data", dataPayload); 

    // actually send the message 
    try { 
      Packet request = new GcmPacketExtension(JSONValue.toJSONString(message)).toPacket(); 
      connection.sendPacket(request); 
    } catch (NotConnectedException enc) { 
     // quietly ignore the error 
    } 
} 

下行消息(Android客戶端)

public class MyGcmListenerService extends GcmListenerService { 
    public MyGcmListenerService() { } 

    public void onMessageReceived (String from, Bundle data) { 
     // get info ("data" stuff) 
     String contents = data.getString("contents"); 

     ... process contents 
    } 
} 

上游消息(Android客戶端)

GoogleCloudMessaging gcm; 
String SENDER_ID = "999999999999"; 

// send the registration to the back-end app server 
private void sendUpstreamMessage(user) { 
    // use upstream message to register with the app server 
    // app server uses the 'from' field of the message 
    String msg = ""; 
    try { 
     Bundle data = new Bundle(); 
     String user = getGoogleAccount(); 

     // username is the user email 
     data.putString("username", user); 
     // and note this is a registration request 
     data.putString("my_action", "edu.eku.styere.gcmpushclient.REGISTER"); 

     String id = myNewMessageId(); 

     // send the registration message 
     gcm.send(SENDER_ID + "@gcm.googleapis.com", id, data); 
    } catch (IOException ex) { 
     // for now ignore error 
    } 
    return; 
} 

上游消息(應用服務器 - 再次使用Java)

// assume we already know this is an upstream message and not an ACK or something else 
protected void handleUpstreamMessage(Map<String, Object> jsonObject) { 
    // PackageName of the application that sent this message. 
    String category = (String) jsonObject.get("category"); 
    String from = (String) jsonObject.get("from"); 
    @SuppressWarnings("unchecked") 
    Map<String, String> payload = (Map<String, String>) jsonObject.get("data"); 

    // what action do they want? 
    String my_action = (String) payload.get("my_action"); 
    if (my_action.equals("edu.eku.styere.gcmpushclient.REGISTER")) { 
    // registration request 
    String username = (String) payload.get("username"); 

    registerUser(username, from); 

    return; 
    } 
} 
+0

+1 @Eugene Styer,這是一個有效的解決方案。當從應用程序服務器接收到下游消息時,您是否知道如何獲得GCM響應? –

+0

編輯答案以包含上游/下游樣本消息 - 您的應用將獲取請求設備位置的下游消息,然後發送包含該信息的上游消息 –