我需要两个Android应用才能通过互联网进行通信。所以我选择了Google GCM。
我希望应用程序创建一个主题,以便其他应用程序可以将消息发布到该主题。我的目标是让两个应用程序在它们之间交换文本数据。
如何让他们直接沟通?我将什么放在JsonObject的“to”字段中?或者我应该使用“registration_id”字段并放置令牌ID吗?
或者我需要Web服务器吗?
我发布了代码供你查看我的内容。
if (sharedPreferences.getBoolean(context.getString(R.string.Google_Services), false)) {
//Upstream msg
new AsyncTask() {
@Override
protected Void doInBackground(Object[] params) {
try {
// Prepare JSON containing the GCM message content. What to send and where to send.
JSONObject jGcmData = new JSONObject();
JSONObject jData = new JSONObject();
jData.put("message", msgSend);
// Where to send GCM message
jGcmData.put("to", "/topics/phone");
//jGcmData.put("to","cPnatWR_2yo:APA91bFshaomZuuxEggU2rn1s_YSDoyH4zUOeOImfFXsm62dwUj2kMjbxLCWvgwKEedQlk59TxnpQoTqUjgMiDcsUJil3kZ702lk-NHSIraYM9nQ_mkf3g98gWjmusq0wNpk5o4gos8_");
//jGcmData.put("registration_ids","cPnatWR_2yo:APA91bFshaomZuuxEggU2rn1s_YSDoyH4zUOeOImfFXsm62dwUj2kMjbxLCWvgwKEedQlk59TxnpQoTqUjgMiDcsUJil3kZ702lk-NHSIraYM9nQ_mkf3g98gWjmusq0wNpk5o4gos8_");
// What to send in GCM message.
jGcmData.put("data", jData);
// Create connection to send GCM Message request.
URL url = new URL("https://android.googleapis.com/gcm/send");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "key=" + API_KEY);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestMethod("POST");
conn.setDoOutput(true);
// Send GCM message content.
OutputStream outputStream = conn.getOutputStream();
outputStream.write(jGcmData.toString().getBytes());
// Read GCM response.
InputStream inputStream = conn.getInputStream();
String resp = IOUtils.toString(inputStream);
System.out.println(resp);
System.out.println("Check your device/emulator for notification or logcat for " +
"confirmation of the receipt of the GCM message.");
} catch (IOException e) {
System.out.println("Unable to send GCM message.");
System.out.println("Please ensure that API_KEY has been replaced by the server " +
"API key, and that the device's registration token is correct (if specified).");
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
然后另一个应用程序注册了这个主题。
public class RegistrationIntentService extends IntentService {
private static final String TAG = "RegIntentService";
private static final String[] TOPICS = {"phone"};
public RegistrationIntentService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
try {
// [START register_for_gcm]
// Initially this call goes out to the network to retrieve the token, subsequent calls
// are local.
// R.string.gcm_defaultSenderId (the Sender ID) is typically derived from google-services.json.
// See https://developers.google.com/cloud-messaging/android/start for details on this file.
// [START get_token]
InstanceID instanceID = InstanceID.getInstance(this);
instanceID.deleteInstanceID();
String newIID = InstanceID.getInstance(this).getId();
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
// [END get_token]
Log.i(TAG, "GCM Registration Token: " + token);
// TODO: Implement this method to send any registration to your app's servers.
sendRegistrationToServer(token);
// Subscribe to topic channels
subscribeTopics(token);
// You should store a boolean that indicates whether the generated token has been
// sent to your server. If the boolean is false, send the token to your server,
// otherwise your server should have already received the token.
sharedPreferences.edit().putBoolean(getString(R.string.SENT_TOKEN_TO_SERVER), true).apply();
// [END register_for_gcm]
} catch (Exception e) {
Log.d(TAG, "Failed to complete token refresh", e);
// If an exception happens while fetching the new token or updating our registration data
// on a third-party server, this ensures that we'll attempt the update at a later time.
sharedPreferences.edit().putBoolean(getString(R.string.SENT_TOKEN_TO_SERVER), false).apply();
}
// Notify UI that registration has completed, so the progress indicator can be hidden.
Intent registrationComplete = new Intent(getString(R.string.REGISTRATION_COMPLETE));
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
/**
* Persist registration to third-party servers.
*
* Modify this method to associate the user's GCM registration token with any server-side account
* maintained by your application.
*
* @param token The new token.
*/
private void sendRegistrationToServer(String token) {
// Add custom implementation, as needed.
}
/**
* Subscribe to any GCM topics of interest, as defined by the TOPICS constant.
*
* @param token GCM token
* @throws IOException if unable to reach the GCM PubSub service
*/
// [START subscribe_topics]
private void subscribeTopics(String token) throws IOException {
GcmPubSub pubSub = GcmPubSub.getInstance(this);
for (String topic : TOPICS) {
//pubSub.unsubscribe(token,"/topics/" + topic);
pubSub.subscribe(token, "/topics/" + topic, null);
}
}
// [END subscribe_topics]
我包含接收应用的清单文件的GCM部分:
<!-- [START gcm_receiver] -->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="org.suportec.lost" />
</intent-filter>
</receiver>
<!-- [END gcm_receiver] -->
<!-- [START gcm_listener] -->
<service
android:name="org.suportec.lost.GoogleCMListener"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<!-- [END gcm_listener] -->
<!-- [START instanceId_listener] -->
<service
android:name="org.suportec.lost.MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<!-- [END instanceId_listener] -->
<service
android:name="org.suportec.lost.RegistrationIntentService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
我不能把它付诸实践。请帮我! 谢谢!
答案 0 :(得分:0)
我已经解决了这个问题!
GCM使用权限是一个问题。他们配置了其他应用程序包。这是愚蠢的原因在Kitkat工作,但在4和以前,不起作用。