2个Android应用与GCM之间的通信

时间:2015-06-30 19:18:00

标签: php android google-cloud-messaging

我在两个不同的设备上有2个Android应用。 App 1是固定的,app 2是移动的。我希望应用程序1找到最近的应用程序2设备并像Snapchat一样进行通信,但我想用应用程序2的当前位置更新应用程序1。我将应用1的位置存储在服务器中并检索应用2的位置并计算它们之间的距离,并通过GCM将应用1的位置发送到应用2。但事实证明这比我原先想象的要复杂得多。我还尝试将移动应用程序的位置存储在数据库中,并在静止请求通信后获取更新的位置,但这意味着更新数据库太多。有人能给我一个提示如何有效地完成这个任务吗?以下是用于计算它们之间的距离和发送位置的代码片段。

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 个答案:

答案 0 :(得分:1)

我想到的是,当app 1客户端想要进行通信时,它会向您的应用服务器发送消息。然后,app服务器向所有适当的移动设备发送GCM推送消息,每个设备上的app 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;
}

上游消息(app server - 再次使用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;
    }
}