如何在Android Studio中实现GCM Hello World,使用 GCM 进行 Android 应用程序推送通知。

3

我已经搜索了几天如何实现Android的谷歌云消息传递(Google Cloud Messaging),但我有一些疑问。

似乎谷歌提供了一些好的信息,例如这里这里,但我对所有逻辑感到困惑。其中一页讲述客户端,另一页讲述服务器端,很好,但是如何绑定它们?如何实现HTTP和/或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.

这个基本应用程序需要哪些步骤才能实现?
谢谢。

如果您还没有看过这个,那么它是一个很好的起点。https://developers.google.com/cloud-messaging/android/start - Arthur Thompson
1个回答

10

如果您已经阅读了问题中的两个链接并理解了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>

@BKN感谢您的回复。您能否检查一下这篇其他的帖子?我非常感谢您在那里发表的评论。http://stackoverflow.com/questions/32322631/adding-google-cloud-messagin-gcm-for-android-registration-process - Danilo Setton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接