我在两个不同的设备上有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;
}
答案 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;
}
}