Help us understand the problem. What is going on with this article?

PythonからGoogleのAPIを利用してAndroidへPUSH通知する

More than 5 years have passed since last update.

GoogleのAPIを用いてAndroid端末へのPUSHとステータスバーへの通知の表示メモ

クライアント(Android)

AndroidでPUSH通知をするための準備はhttp://dev.classmethod.jp/smartphone/android/gcm/に書いてあります。
本当に参考になりました。

ここからは上のリンクからの変更点と追加点についてです。

-
Google Developers Consoleでの手順が多少変わっているので、そこについて説明します。

まず、https://console.developers.google.com/projectにアクセスし、既存のprojectか"CREATE PROJECT"を選択します。

projectを作成or選択してprojectのページを開きます。
ページ上部の"Project Number"は控えておきましょう。
そして、左側のサイドメニューの"APIs & auth" > "APIs" から"Google Cloud Messaging for Android"のSTATUSをONにします。
なお、公式のドキュメントはここです。

次に、"APIs & auth" > "Credentials"で"Public API access"の"CREATE NEW KEY"を選択し、新しくAPI keyを取得します。
表示されるダイアログでは"Server Key"を選択し、IPアドレスは0.0.0.0を入力します。
ここは必要があれば変更しましょう。
テスト用であれば0.0.0.0で問題ありません。多分。

-
GcmBroadcastReceiver.javaは上のリンクのものをそのまま利用させてもらいます。
次に、GcmIntentService.javaを通知のために書き換えます。

GcmIntentService.java
public class GcmIntentService extends IntentService {
    private static final String TAG = GcmIntentService.class.getSimpleName();
    private Notification notification;
    private NotificationManager nm;

    public GcmIntentService() {
        super("GcmIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.v(TAG, "onHandleIntent");
        Bundle extras = intent.getExtras();
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
        String messageType = gcm.getMessageType(intent);

        if (!extras.isEmpty()) {
            if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
                Log.d(TAG, "messageType: " + messageType + ",body:" + extras.toString());
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
                Log.d(TAG,"messageType: " + messageType + ",body:" + extras.toString());
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
                Log.d(TAG,"messageType: " + messageType + ",body:" + extras.toString());
            }
        }

        // ここまでhttp://dev.classmethod.jp/smartphone/android/gcm/のものとほぼ同じ
        // extrasに、サーバーからのdataが入っている
        // ここでは、すべて文字列として格納してある
        Log.v(TAG, extras.toString());
        int userId = Integer.parseInt(extras.getString("user_id"));
        String text = extras.getString("text");

        // 通知を開くとMainActivityが表示されるようにする
        Intent i = new Intent(getApplicationContext(), MainActivity.class);
        i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
        i.setType("notification");
        i.putExtra("user_id", userId);
        i.putExtra("text", text);

        // 第4引数を0にすると、Intentのextrasだけ更新されず、通知のテキストは違うのにextrasだけ同じなため、
        // Intent先のMainActivityでextrasを取得すると同じ値しかとれなくなる事態に
        PendingIntent pi = PendingIntent.getActivity(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);

        Notification.Builder notificationBuilder =
                new Notification.Builder(getApplicationContext())
                        .setContentIntent(pi)
                        .setSmallIcon(R.drawable.icon_small)
                        .setTicker("通知がきました")  // 通知が来た時にステータスバーに表示されるテキスト
                        .setContentTitle("通知のタイトル")  // 通知バーを開いた時に表示されるタイトル
                        .setContentText("通知のテキスト") // タイトルの下に表示されるテキスト
                        .setWhen(System.currentTimeMillis());  // 通知が表示されるタイミング?

        long[] vibrate_ptn = {0, 100, 300, 1000}; // 振動パターン(適当)
        notification = notificationBuilder.build();
        notification.vibrate = vibrate_ptn;
        notification.defaults |= Notification.DEFAULT_LIGHTS; // デフォルトLED点滅パターンを設定
        notification.flags = Notification.FLAG_ONGOING_EVENT;

        // NotificationManagerのインスタンス取得
        nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        nm.notify(R.string.app_name, notification); // 設定したNotificationを通知する
        GcmBroadcastReceiver.completeWakefulIntent(intent);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        nm.cancel(R.string.app_name);
    }
}

続いて通知をタップした時の動作として起動されるMainActivityです。
大体上のリンクのものでいいですが、onCreateに以下のコードを追加します。


MainActivity.java
// notification表示関係
Intent intent = getIntent();
String intentType = intent.getType();
if (intentType != null && intentType.equals("notification")) {
    Log.v(TAG + " extras", intent.getExtras().toString());
    // extrasからGcmIntentService.javaでいれたデータを取り出す
    int user_id = intent.getIntExtra("user_id", 0);
    String text = intent.getStringExtra("text");

    NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    // ダイアログの表示
    Toast.makeText(this, text, Toast.LENGTH_LONG);
}

registerInBackground()によってLog catにregistrationIdが表示されるので、これを控えます。
アプリケーションとして実装するなら、このIDをサーバーに渡して保存するようにします。

サーバー(Python)

pythonからはrequestsを利用してGoogleへリクエストを送ります。

api.py
import requests
import json

def push_notificate(user_id, text):
    '''エラーが出るとrにエラーメッセージが入る
    これを呼び出せばAndroidに通知が行く
    '''
    gcm_url = 'https://android.googleapis.com/gcm/send'

    # 上で控えたregistrationIdとAPI key
    regid = REGID
    key = "key=" + APIKEY

    headers = {'content-type': 'application/json', 'Authorization': key}
    # 渡すデータは適当です。
    # dictのkeyはAndroidのextrasのkeyと合わせましょう
    params = json.dumps(\
            {'registration_ids': [regid], \
            'data': {'id': user_id, 'text': text}})

    r = requests.post(gcm_url, data=params, headers=headers)
    print r.text
    return

requestsでbasic認証をクリアするには引数にauth=(username, password)を渡しますが、今回はheadersに入れて渡します。

これで大丈夫だと思います。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした