2013年4月26日金曜日

Android GCM を使う

サーバからAndroid 端末へメッセージをデータ送信できる GCM を使いました。(無料です)
GCM: Getting Started の手順に沿って「サーバからメッセージを送って、Logcatに表示する」仕組みを作ります。

■Google API Project の作成:
  1. Google APIs Console page へアクセス
  2. まだAPI Projectを作成していない場合、下記のような画面が現れます。
    API Projectを既に作成している場合、DashBoard が表示されます。この画面の API Projectドロップダウンメニュー(画面左上)から、Other Projects > Create. で、新規プロジェクトを作成できます。
  3. Create Project ボタンをクリックすると、ブラウザのURLが下記のように変わります。
    https://code.google.com/apis/console/#project:4815162342:services
  4. #project:以降の値をメモしておきます(3.の場合、4815162342 )。この値がプロジェクトIDで、今後 GCM のsender ID として使われます。

■GCM サービスを有効にする:
  1. 左側のメニューより、Services を選択します。
  2. Google Cloud Messaging for Android を on にします。
  3. 利用規約が表示されるので、I agreeにチェックを入れ、Accept をクリックします。

■API キーの取得:
  1. 左側のメニューより、API Access を選択すると、下記のような画面が表示されます。
    IP アドレス制限をかけない場合は、このAPI キーを使用する。制限をかける場合は2へ
  2. Create new Server key ボタンをクリックする。下記ダイアログが表示されるので、
  3. サーバのIPアドレスを入力し、Create をクリックすると、下記のように Key for server apps (with IP locking)  が追加される。

■Helperライブラリのインストール:
  • SDK Manager を起動し、Extras > Google Cloud Messaging for Android をインストールする。Android SDKのディレクトリ内は下記のようになります。

■Androidアプリの作成:
  1. 新規プロジェクトを作成 ( minSdkVersionは、8以上に設定 )し、プロジェクトのビルドパスへ、gmc.jar を追加します。
  2. AndroidManifest.xmlを次のようにします。
    1. sdkの設定 (この通りになっているはず)
      <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="xx" />
    2. パーミッションの設定を追加
      <permission android:name="my_app_package.permission.C2D_MESSAGE" android:protectionLevel="signature" />
      <uses-permission android:name="my_app_package.permission.C2D_MESSAGE" /> 
      my_app_package は、マニフェストのpackage名を入れます。
    3. 以下のパーミッションも追加
      <!-- App receives GCM messages. -- >
      <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
      <!-- GCM connects to Google Services. -- >
      <uses-permission android:name="android.permission.INTERNET" />
      <!-- GCM requires a Google account. -- >
      <uses-permission android:name="android.permission.GET_ACCOUNTS" />
      <!-- Keeps the processor from sleeping when a message is received. -- >
      <uses-permission android:name="android.permission.WAKE_LOCK" />
    4. 以下の broadcast receiver を追加
      <receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" 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="my_app_package" />
        </intent-filter>
      </receiver>
    5. 以下のサービスを追加
      <service android:name=".GCMIntentService" />

■サービスクラスの作成:
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.google.android.gcm.GCMBaseIntentService;

public class GCMIntentService extends GCMBaseIntentService {
 private static final String TAG = GCMIntentService.class.getSimpleName();

 @Override
 protected void onError(Context arg0, String arg1) {
  Log.d(TAG, "onError");
 }

 @Override
 protected void onMessage(Context context, Intent intent) {
  Log.d(TAG, "onMessage");
 }

 @Override
 protected void onRegistered(Context context, String regId) {
  Log.d(TAG, "regId registered:" + regId);
 }

 @Override
 protected void onUnregistered(Context context, String regId) {
  Log.d(TAG, "regId not registered:" + regId);
 }

 @Override
 protected boolean onRecoverableError(Context context, String errorId) {
  // TODO Auto-generated method stub
  return super.onRecoverableError(context, errorId);
 }
}


■MainActivityの修正:

import文追加
import com.google.android.gcm.GCMRegistrar;

onCreate() メソッド内に以下を追加
SENDER_ID は、Google API Project の作成 の 4 でメモした値を定数定義します。
端末のデバイスIDを知りたいので、LogcatにregIdを出力します。
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
final String regId = GCMRegistrar.getRegistrationId(this);
Log.d(TAG, "regId :" + regId);

if (regId.equals("")) {
  GCMRegistrar.register(this, SENDER_ID);
} else {
  Log.v(TAG, "Already registered");
}

■サーバ側のプログラム作成:
  1. GCM SDK の gcm-server.jar をサーバのクラスパスが通っているところへコピーします。
  2. GCMServer.java 作成(サンプルとほぼ変わりません)
    デバイスID・・・作成したAndroidアプリを端末へインストールして、Logcatに出力されたID
    Google API Key ・・・APIプロジェクトを登録したときに取得したもの
    import java.util.ArrayList;
    import com.google.android.gcm.server.*;
    
    public class GCMServer {
      
      public static void main(String[] args) {
      try{
        String sendMessage = "say hello from my server!";
        ArrayList devices = new ArrayList();
        devices.add( デバイスID );
        Sender sender = new Sender( Google API Key );
        Message message = new Message.Builder().addData("message", sendMessage).build();
        MulticastResult result = sender.send(message, devices, 5);
      } catch (Exception e) {
        System.out.println(e);
      }
      }
    }
    
    

    コンパイルは通りましたが、実行時にエラーが発生しました。
    Exception in thread "main" java.lang.NoClassDefFoundError: org/json/simple/parser/ParseException

    StackOverFlow に載っていました。 json-simple-1.1.1.jar を追加し、再度挑戦したら、動きました。

■GCMIntentService.javaを修正:

サーバからのメッセージをログに出力したいので、GCMIntentService.java の onMessage() メソッドを修正します。
String str = intent.getStringExtra("message");
Log.d(TAG, "onMessage str:" + str);

再度端末へインストールして、サーバ側のプログラムを実行すると、Logcatにでました。
 onMessage str:say hello from my server!

日本語も表示できるか確認します。
GCMServer.java のメッセージ文字列に日本語を追加し、実行します。
String sendMessage = "say hello from my server! 日本語いけるかな?";

無事でました。
 onMessage str:say hello from my server! 日本語いけるかな?

0 件のコメント:

コメントを投稿