我想在按钮点击中使用GCM从一台设备向多台设备发送推送通知。我已经关注了GCM的所有过程。我获得了设备的服务器密钥和注册ID,但我没有使用GCM获得推送通知。我也在谷歌搜索但没有得到正确的解决方案。
请建议我如何在多台设备上发送推送通知。
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
private static final String TAG = "MainActivity";
private BroadcastReceiver mRegistrationBroadcastReceiver;
private ProgressBar mRegistrationProgressBar;
private TextView mInformationTextView;
private boolean isReceiverRegistered;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRegistrationProgressBar = (ProgressBar) findViewById(R.id.registrationProgressBar);
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mRegistrationProgressBar.setVisibility(ProgressBar.GONE);
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(context);
boolean sentToken = sharedPreferences
.getBoolean(QuickstartPreferences.SENT_TOKEN_TO_SERVER, false);
if (sentToken) {
mInformationTextView.setText(getString(R.string.gcm_send_message));
} else {
mInformationTextView.setText(getString(R.string.token_error_message));
}
}
};
mInformationTextView = (TextView) findViewById(R.id.informationTextView);
// Registering BroadcastReceiver
registerReceiver();
if (checkPlayServices()) {
// Start IntentService to register this application with GCM.
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
@Override
protected void onResume() {
super.onResume();
registerReceiver();
}
@Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);
isReceiverRegistered = false;
super.onPause();
}
private void registerReceiver(){
if(!isReceiverRegistered) {
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(QuickstartPreferences.REGISTRATION_COMPLETE));
isReceiverRegistered = true;
}
}
/**
* Check the device to make sure it has the Google Play Services APK. If
* it doesn't, display a dialog that allows users to download the APK from
* the Google Play Store or enable it in the device's system settings.
*/
private boolean checkPlayServices() {
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (apiAvailability.isUserResolvableError(resultCode)) {
apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
.show();
} else {
Log.i(TAG, "This device is not supported.");
finish();
}
return false;
}
return true;
}
}
MyGcmListenerService.java
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
/**
* Called when message is received.
*
* @param from SenderID of the sender.
* @param data Data bundle containing message data as key/value pairs.
* For Set of keys use data.keySet().
*/
// [START receive_message]
@Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
if (from.startsWith("/topics/")) {
// message received from some topic.
} else {
// normal downstream message.
}
// [START_EXCLUDE]
/**
* Production applications would usually process the message here.
* Eg: - Syncing with server.
* - Store message in local database.
* - Update UI.
*/
/**
* In some cases it may be useful to show a notification indicating to the user
* that a message was received.
*/
sendNotification(message);
// [END_EXCLUDE]
}
// [END receive_message]
/**
* Create and show a simple notification containing the received GCM message.
*
* @param message GCM message received.
*/
private void sendNotification(String message) {
Log.d(TAG, "Preparing to send notification...: " + message);
mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, MainActivity.class), 0);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("GCM Notification")
.setSound(defaultSoundUri)
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
.setContentText(message);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
Log.d(TAG, "Notification sent successfully.");
}
}
RegistrationIntentService.java
public class RegistrationIntentService extends IntentService {
private static final String TAG = "RegIntentService";
private static final String[] TOPICS = {"global"};
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);
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderIdd),
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(QuickstartPreferences.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(QuickstartPreferences.SENT_TOKEN_TO_SERVER, false).apply();
}
// Notify UI that registration has completed, so the progress indicator can be hidden.
Intent registrationComplete = new Intent(QuickstartPreferences.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.subscribe(token, "/topics/" + topic, null);
}
}
// [END subscribe_topics]
}
GcmSender.java
public class GcmSender {
public static final String API_KEY = "AIzaSyClNEQb0X2Pp8k6_JaZx_XWnJAzsm3VSDQ";
public static void main(String[] args) throws JSONException {
if (args.length < 1 || args.length > 2 || args[0] == null) {
System.err.println("usage: ./gradlew run -Pmsg=\"MESSAGE\" [-Pto=\"DEVICE_TOKEN\"]");
System.err.println("");
System.err.println("Specify a test message to broadcast via GCM. If a device's GCM registration token is\n" +
"specified, the message will only be sent to that device. Otherwise, the message \n" +
"will be sent to all devices subscribed to the \"global\" topic.");
System.err.println("");
System.err.println("Example (Broadcast):\n" +
"On Windows: .\\gradlew.bat run -Pmsg=\"<Your_Message>\"\n" +
"On Linux/Mac: ./gradlew run -Pmsg=\"<Your_Message>\"");
System.err.println("");
System.err.println("Example (Unicast):\n" +
"On Windows: .\\gradlew.bat run -Pmsg=\"<Your_Message>\" -Pto=\"<Your_Token>\"\n" +
"On Linux/Mac: ./gradlew run -Pmsg=\"<Your_Message>\" -Pto=\"<Your_Token>\"");
System.exit(1);
}
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", args[0].trim());
// Where to send GCM message.
if (args.length > 1 && args[1] != null) {
jGcmData.put("to", args[1].trim());
} else {
jGcmData.put("to", "/topics/global");
}
// 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();
}
}
}
答案 0 :(得分:0)
使用此课程 @Override
public boolean onContextItemSelected(MenuItem item) {
Log.d("mySelectedItem", ""+ globalVariable) //use the globalVariable as you need
return super.onContextItemSelected(item);
}
并使用以下com.google.android.gcm.server.Sender
方法
sendMessage
这在我的项目中有效。
为此,您必须添加/**
* androidTargets is list of device ids to send message.
* data is the data you want to send to Android App.
*/
protected void sendMessage(List<String> androidTargets, String data) {
String collapseKey = "";
String userMessage = "";
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("data", data);
String userMessage = jsonObject.toJSONString();
Sender sender = new Sender(API_KEY);
Message message = new Message.Builder()
.collapseKey(collapseKey)
.timeToLive(30)
.delayWhileIdle(true)
.addData("message", userMessage)
.build();
try {
MulticastResult result = sender.send(message, androidTargets, 1);
if (result.getResults() != null) {
int canonicalRegId = result.getCanonicalIds();
if (canonicalRegId != 0) {
System.out.println(result.getResults());
}
} else {
int error = result.getFailure();
System.out.println("Broadcast failure: " + error);
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
return;
}
}
个文件。
希望它能运作。