如何使用 Android Studio 为 Android 实施 GCM Hello World
How to implement a GCM Hello World for Android using Android Studio
几天来我一直在寻找如何为 Android 实施 Google 云消息传递,但我对此有一些严重的怀疑。
我的意思是,显然 Google 在网上发布了一些很好的信息,例如 here and here,但我对所有逻辑感到困惑。一页讨论客户端,另一页讨论服务器端。太好了,但我如何将所有这些绑定在一起?我如何实施 HTTP and/or XMPP 协议来与 GCM 连接服务器通信?
我想为 GCM 实现一个基本的 HelloWorld,它可以通过以下步骤工作:
1. App send a message (say "HelloWorld") to GCM;
2. Receive that message from GCM and add it to a TextView.
实现这个基本应用程序需要哪些步骤?
谢谢,
如果您已经阅读问题中的两个链接并了解 GCM 关键概念,那么您可以参考以下示例代码:
当然,假设你已经完成了:
- 在 Google Developers Console
处创建项目及其服务器 API 密钥
- 像这样在您的 AndroidManifest 文件中设置权限
<uses-permission android:name="android.permission.INTERNET" />
服务器端:
public class MainActivity extends AppCompatActivity {
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.textView);
new GCMRequest().execute();
}
...
private class GCMRequest extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... voids) {
final String API_KEY = "..."; // An API key saved on the app server that gives the app server authorized access to Google services
final String CLIENT_REG_ID = "..."; //An ID issued by the GCM connection servers to the client app that allows it to receive messages
final String postData = "{ \"registration_ids\": [ \"" + CLIENT_REG_ID + "\" ], " +
"\"delay_while_idle\": true, " +
"\"data\": {\"tickerText\":\"My Ticket\", " +
"\"contentTitle\":\"My Title\", " +
"\"message\": \"Test GCM message from GCMServer-Android\"}}";
try {
URL url = new URL("https://android.googleapis.com/gcm/send");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Authorization", "key=" + API_KEY);
OutputStream outputStream = new BufferedOutputStream(urlConnection.getOutputStream());
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "utf-8"));
writer.write(postData);
writer.flush();
writer.close();
outputStream.close();
int responseCode = urlConnection.getResponseCode();
InputStream inputStream;
if (responseCode < HttpURLConnection.HTTP_BAD_REQUEST) {
inputStream = urlConnection.getInputStream();
} else {
inputStream = urlConnection.getErrorStream();
}
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String temp, response = "";
while ((temp = bufferedReader.readLine()) != null) {
response += temp;
}
return response;
} catch (IOException e) {
e.printStackTrace();
return e.toString();
}
}
@Override
protected void onPostExecute(String message) {
super.onPostExecute(message);
if (mTextView != null) {
try {
JSONObject jsonObject = new JSONObject(message);
mTextView.setText(jsonObject.toString(5));
} catch (JSONException e) {
e.printStackTrace();
mTextView.setText(e.toString());
}
}
}
}
}
客户端:
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private final Context mContext = this;
private final String SENDER_ID = "..."; // Project Number at https://console.developers.google.com/project/...
private final String SHARD_PREF = "com.example.gcmclient_preferences";
private final String GCM_TOKEN = "gcmtoken";
public static TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences appPrefs = mContext.getSharedPreferences(SHARD_PREF, Context.MODE_PRIVATE);
String token = appPrefs.getString(GCM_TOKEN, "");
if (token.isEmpty()) {
try {
getGCMToken();
} catch (Exception e) {
e.printStackTrace();
}
}
mTextView = (TextView) findViewById(R.id.textView);
}
...
private void getGCMToken() {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
InstanceID instanceID = InstanceID.getInstance(mContext);
String token = instanceID.getToken(SENDER_ID, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
if (token != null && !token.isEmpty()) {
SharedPreferences appPrefs = mContext.getSharedPreferences(SHARD_PREF, Context.MODE_PRIVATE);
SharedPreferences.Editor prefsEditor = appPrefs.edit();
prefsEditor.putString(GCM_TOKEN, token);
prefsEditor.apply();
}
Log.i("GCM", token);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}.execute();
}
}
GcmService.java:
public class GcmService extends GcmListenerService {
@Override
public void onMessageReceived(String from, Bundle data) {
JSONObject jsonObject = new JSONObject();
Set<String> keys = data.keySet();
for (String key : keys) {
try {
jsonObject.put(key, data.get(key));
} catch (JSONException e) {
e.printStackTrace();
}
}
try {
sendNotification("Received: " + jsonObject.toString(5));
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onDeletedMessages() {
sendNotification("Deleted messages on server");
}
@Override
public void onMessageSent(String msgId) {
sendNotification("Upstream message sent. Id=" + msgId);
}
@Override
public void onSendError(String msgId, String error) {
sendNotification("Upstream message send error. Id=" + msgId + ", error" + error);
}
private void sendNotification(final String msg) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
if (MainActivity.mTextView != null) {
MainActivity.mTextView.setText(msg);
}
}
});
}
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gcmandroid" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.example.gcm.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:fullBackupContent="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<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.REGISTRATION" />
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.example.gcm" />
</intent-filter>
</receiver>
<service android:name=".GcmService" android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
几天来我一直在寻找如何为 Android 实施 Google 云消息传递,但我对此有一些严重的怀疑。
我的意思是,显然 Google 在网上发布了一些很好的信息,例如 here and here,但我对所有逻辑感到困惑。一页讨论客户端,另一页讨论服务器端。太好了,但我如何将所有这些绑定在一起?我如何实施 HTTP and/or XMPP 协议来与 GCM 连接服务器通信?
我想为 GCM 实现一个基本的 HelloWorld,它可以通过以下步骤工作:
1. App send a message (say "HelloWorld") to GCM;
2. Receive that message from GCM and add it to a TextView.
实现这个基本应用程序需要哪些步骤?
谢谢,
如果您已经阅读问题中的两个链接并了解 GCM 关键概念,那么您可以参考以下示例代码:
当然,假设你已经完成了:
- 在 Google Developers Console 处创建项目及其服务器 API 密钥
- 像这样在您的 AndroidManifest 文件中设置权限
<uses-permission android:name="android.permission.INTERNET" />
服务器端:
public class MainActivity extends AppCompatActivity {
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.textView);
new GCMRequest().execute();
}
...
private class GCMRequest extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... voids) {
final String API_KEY = "..."; // An API key saved on the app server that gives the app server authorized access to Google services
final String CLIENT_REG_ID = "..."; //An ID issued by the GCM connection servers to the client app that allows it to receive messages
final String postData = "{ \"registration_ids\": [ \"" + CLIENT_REG_ID + "\" ], " +
"\"delay_while_idle\": true, " +
"\"data\": {\"tickerText\":\"My Ticket\", " +
"\"contentTitle\":\"My Title\", " +
"\"message\": \"Test GCM message from GCMServer-Android\"}}";
try {
URL url = new URL("https://android.googleapis.com/gcm/send");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Authorization", "key=" + API_KEY);
OutputStream outputStream = new BufferedOutputStream(urlConnection.getOutputStream());
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "utf-8"));
writer.write(postData);
writer.flush();
writer.close();
outputStream.close();
int responseCode = urlConnection.getResponseCode();
InputStream inputStream;
if (responseCode < HttpURLConnection.HTTP_BAD_REQUEST) {
inputStream = urlConnection.getInputStream();
} else {
inputStream = urlConnection.getErrorStream();
}
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String temp, response = "";
while ((temp = bufferedReader.readLine()) != null) {
response += temp;
}
return response;
} catch (IOException e) {
e.printStackTrace();
return e.toString();
}
}
@Override
protected void onPostExecute(String message) {
super.onPostExecute(message);
if (mTextView != null) {
try {
JSONObject jsonObject = new JSONObject(message);
mTextView.setText(jsonObject.toString(5));
} catch (JSONException e) {
e.printStackTrace();
mTextView.setText(e.toString());
}
}
}
}
}
客户端:
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private final Context mContext = this;
private final String SENDER_ID = "..."; // Project Number at https://console.developers.google.com/project/...
private final String SHARD_PREF = "com.example.gcmclient_preferences";
private final String GCM_TOKEN = "gcmtoken";
public static TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences appPrefs = mContext.getSharedPreferences(SHARD_PREF, Context.MODE_PRIVATE);
String token = appPrefs.getString(GCM_TOKEN, "");
if (token.isEmpty()) {
try {
getGCMToken();
} catch (Exception e) {
e.printStackTrace();
}
}
mTextView = (TextView) findViewById(R.id.textView);
}
...
private void getGCMToken() {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
InstanceID instanceID = InstanceID.getInstance(mContext);
String token = instanceID.getToken(SENDER_ID, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
if (token != null && !token.isEmpty()) {
SharedPreferences appPrefs = mContext.getSharedPreferences(SHARD_PREF, Context.MODE_PRIVATE);
SharedPreferences.Editor prefsEditor = appPrefs.edit();
prefsEditor.putString(GCM_TOKEN, token);
prefsEditor.apply();
}
Log.i("GCM", token);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}.execute();
}
}
GcmService.java:
public class GcmService extends GcmListenerService {
@Override
public void onMessageReceived(String from, Bundle data) {
JSONObject jsonObject = new JSONObject();
Set<String> keys = data.keySet();
for (String key : keys) {
try {
jsonObject.put(key, data.get(key));
} catch (JSONException e) {
e.printStackTrace();
}
}
try {
sendNotification("Received: " + jsonObject.toString(5));
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onDeletedMessages() {
sendNotification("Deleted messages on server");
}
@Override
public void onMessageSent(String msgId) {
sendNotification("Upstream message sent. Id=" + msgId);
}
@Override
public void onSendError(String msgId, String error) {
sendNotification("Upstream message send error. Id=" + msgId + ", error" + error);
}
private void sendNotification(final String msg) {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
if (MainActivity.mTextView != null) {
MainActivity.mTextView.setText(msg);
}
}
});
}
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.gcmandroid" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.example.gcm.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />
<application
android:allowBackup="true"
android:fullBackupContent="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<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.REGISTRATION" />
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.example.gcm" />
</intent-filter>
</receiver>
<service android:name=".GcmService" android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>