Androidプラットフォームのプッシュ通知


266

サーバーからプッシュされたアラートを受信するアプリを書きたいと思っています。これを行う方法がいくつか見つかりました。

  1. SMS-着信SMSをインターセプトし、サーバーからのプルを開始します
  2. サーバーを定期的にポーリングする

それぞれに独自の制限があります。SMS-到着時間の保証はありません。投票によりバッテリーが消耗する可能性があります。

もっと良い提案がありますか?どうもありがとう。


4
また、プッシュ通知に関するGoogle I / O 2010プレゼンテーションを見ることができますdeveloper.android.com/videos/index.html#v=PLM4LajwDVc
vokilam

あなたはこの投稿を見ることができると思います:stackoverflow.com/questions/17629942/…Worklightを使用すると、GCMを含むさまざまなチャネルを介してプッシュを受信できます。
Neeraj Krishna 2014

1
Google I / O 2010のプレゼンテーションはyoutube.com/watch?v=PLM4LajwDVc
elcuco 2014年

「投票によりバッテリーが消耗する可能性があります。」AlarmManagerを使用してポーリングを中止できるため、バッテリーの消耗が激しいことはありません。シンプルで無料(GCMのように支払う必要がない)ソリューションです。
Deepscorn 2015

回答:


203

Googleの公式回答はAndroid Cloud to Device Messaging Framework(非推奨) Google Cloud Messaging(非推奨) Firebase Cloud Messagingです

Android 2.2以上で動作します(Playストアのあるスマートフォン)。


現在はベータ版ですが、アクティブ化を期待してサインアップできます。
Brackの

3
通常、アクティベーションは非常に迅速に行うことができ、GMailのようなものに使用されているため、運用環境で機能することがわかっています。残念ながら、C2DMのサーバー側の側面と通信するためのサンプルコードが不足しています。私はここでその様相のためのチュートリアルを書いているblog.boxedice.com/2010/10/07/...
davidmytton

6
問題は、ユーザー用のGoogleアカウントが必要であることです。これが制約だと思います。
カフェイン2012

33
Android Cloud to Device Messaging Frameworkは非推奨になっていることに注意してください。新しいフレームワークはGoogleクラウドメッセージングと呼ばれ、次の場所にあります:developer.android.com/guide/google/gcm/index.html
Ryan Berger

2018年4月10日、GoogleはGCMを廃止しました。GCMサーバーとクライアントAPIは2019年5月29日に削除されました。GCMアプリをFirebase Cloud Messaging(FCM)に移行してください。詳細については、移行ガイドをご覧ください。
パイエゴ

29

私が同様の質問に与えた回答からのクロス投稿-Androidはほぼリアルタイムのプッシュ通知をサポートしていますか?

私は最近、この種のことを行う方法として、Android向けのMQTT http://mqtt.org(つまり、SMSではなくデータ主導のプッシュ通知、ほぼ即時のメッセージ配信、ポーリングではないなど)を試し始めました。

役立つ場合に備えて、これに関する背景情報をブログに投稿しています

http://dalelane.co.uk/blog/?p=938

(注:MQTTはIBMテクノロジーであり、私がIBMで働いていることを指摘しておきます。)


こんにちはデール、私はMQTTに関するあなたのブログ投稿を読みました、そしてそれは間違いなく携帯電話でほとんど即時の通知のための法案に合うようです。しかし、それが実際にどのように機能するかについての情報を見つけることができませんでした。それは常にソケットを開いたままにしますか?IPアドレスが変更された場合、サーバーにどのように通知しますか?これに光を当てていただければ幸いです。乾杯ナレン
ナレン

2
接続を開いたままにします。フォローアップの投稿(dalelane.co.uk/blog/?p=1009)で、接続を開いたままにすることの影響について詳しく説明しました-わかりましたか?接続が切断された場合、サーバーとクライアントの両方に通知できます。次に、応答方法(再接続など)を決定するのはアプリケーション層の決定です。投稿で参照されているドキュメントに詳細情報があります(例:IA92:www-01.ibm.com/support/docview.wss?rs=171&uid=swg24006006 pdf(そのページにはpdf、そのページのzipにはJavadoc))
dalelane 2009年

18

Androidプッシュ通知に関する私の理解/経験は次のとおりです。

  1. C2DM GCMは -あなたのターゲットAndroidプラットフォームが2.2以降であれば、それのために行きます。たった1つのキャッチとして、デバイスユーザーはメッセージを取得するために常に Googleアカウントでログインする必要があります。

  2. MQTT -Pub / Subベースのアプローチ。デバイスからのアクティブな接続が必要です。適切に実装されていないと、バッテリーを消耗する可能性があります。

  3. 執事 -コミュニティのサポートが限られているため、長期的にはうまくいかない可能性があります。

編集:2013年11月25日に追加

GCM-グーグルは言う...

3.0より前のデバイスの場合、ユーザーはモバイルデバイスでGoogleアカウントをセットアップする必要があります。Android 4.0.4以降を実行しているデバイスでは、Googleアカウントは必須ではありません。*


4.0.4以降ではGoogleアカウントは必要ありませんが、Google Playアプリをインストールする必要があるようです。Googleアカウントがなくても、どうやってインストールするのでしょうか。

1
@Jan:Google Playアプリはデバイスにインストールされています。ユーザーがインストールする必要はありません。
デクスター

@Dexter、すべてのAndroidデバイスにデフォルトでGoogle Playがインストールされているわけではありません。ほとんどはデフォルトでインストールされています。特に評判の良い電話ベンダーから購入したデバイスですが、Android OSがフラッシュされているだけのデバイスは、必ずしもGoogle Playを備えているとは限りません。(たとえば、新しいGenymotionデバイスなどの多くのAndroidエミュレーターには、デフォルトでGoogle Playがありません。)
Spencer D

では、MQTTはGoogle PlayがインストールされていないAndroidデバイスに最適なオプションですか?
Yeung

17

Android Cloud to Deviceメッセージングフレームワーク

重要:C2DMは、2012年6月26日をもって正式に廃止されました。をもってこれは、C2DMが新しいユーザーと割り当てリクエストの受け入れを停止したことを意味します。C2DMに新機能は追加されません。ただし、C2DMを使用するアプリは引き続き機能します。既存のC2DM開発者は、Google Cloud Messaging for Android(GCM)と呼ばれる新しいバージョンのC2DMに移行することをお勧めします。詳細については、C2DMからGCMへの移行に関するドキュメントをご覧ください。開発者は新しい開発にGCMを使用する必要があります。

以下のリンクをご確認ください。

http://developer.android.com/guide/google/gcm/index.html


17

ここでは、最初からRegIDと通知を取得する方法についていくつかの手順を説明しました

  1. Google Cloudでアプリを作成/登録
  2. 開発でCloud SDKを設定する
  3. GCMのプロジェクトを構成する
  4. デバイス登録IDを取得する
  5. プッシュ通知を送信する
  6. プッシュ通知を受け取る

以下のURLリンクで完全なチュートリアルを見つけることができます

Androidプッシュ通知の開始:最新のGoogleクラウドメッセージング(GCM)-ステップバイステップの完全なチュートリアル

ここに画像の説明を入力してください

登録ID(プッシュ通知のデバイストークン)を取得するコードスニップ。

GCMのプロジェクトを構成する


AndroidManifestファイルを更新する

プロジェクトでGCMを有効にするには、マニフェストファイルにいくつかの権限を追加する必要があります。AndroidManifest.xmlに移動し、以下のコードを追加します。権限の追加

<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="android.permission.VIBRATE" />

<uses-permission android:name=“.permission.RECEIVE" />
<uses-permission android:name=“<your_package_name_here>.permission.C2D_MESSAGE" />
<permission android:name=“<your_package_name_here>.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

GCMブロードキャストレシーバー宣言を追加

アプリケーションタグにGCMブロードキャストレシーバー宣言を追加する

<application
        <receiver
            android:name=".GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" ]]>
            <intent-filter]]>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <category android:name="" />
            </intent-filter]]>

        </receiver]]>
     
<application/>

GCM Servie宣言を追加

<application
     <service android:name=".GcmIntentService" />
<application/>

登録ID(プッシュ通知のデバイストークン)を取得する

次に、起動/スプラッシュアクティビティに移動します

定数とクラス変数を追加する

private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
public static final String EXTRA_MESSAGE = "message";
public static final String PROPERTY_REG_ID = "registration_id";
private static final String PROPERTY_APP_VERSION = "appVersion";
private final static String TAG = "LaunchActivity";
protected String SENDER_ID = "Your_sender_id";
private GoogleCloudMessaging gcm =null;
private String regid = null;
private Context context= null;

OnCreateメソッドとOnResumeメソッドを更新する

@Override
protected void onCreate(Bundle savedInstanceState)
{
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_launch);
     context = getApplicationContext();
         if (checkPlayServices()) 
     {
            gcm = GoogleCloudMessaging.getInstance(this);
            regid = getRegistrationId(context);

            if (regid.isEmpty())
            {
                registerInBackground();
            }
            else
            {
            Log.d(TAG, "No valid Google Play Services APK found.");
            }
      }
 }

@Override protected void onResume()
{
       super.onResume();       checkPlayServices();
}


# Implement GCM Required methods (Add below methods in LaunchActivity)

private boolean checkPlayServices() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
                GooglePlayServicesUtil.getErrorDialog(resultCode, this,
                        PLAY_SERVICES_RESOLUTION_REQUEST).show();
            } else {
                Log.d(TAG, "This device is not supported - Google Play Services.");
                finish();
            }
            return false;
        }
        return true;
 }

private String getRegistrationId(Context context) 
{
   final SharedPreferences prefs = getGCMPreferences(context);
   String registrationId = prefs.getString(PROPERTY_REG_ID, "");
   if (registrationId.isEmpty()) {
       Log.d(TAG, "Registration ID not found.");
       return "";
   }
   int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
   int currentVersion = getAppVersion(context);
   if (registeredVersion != currentVersion) {
        Log.d(TAG, "App version changed.");
        return "";
    }
    return registrationId;
}

private SharedPreferences getGCMPreferences(Context context) 
{
    return getSharedPreferences(LaunchActivity.class.getSimpleName(),
                Context.MODE_PRIVATE);
}

private static int getAppVersion(Context context) 
{
     try 
     {
         PackageInfo packageInfo = context.getPackageManager()
                    .getPackageInfo(context.getPackageName(), 0);
            return packageInfo.versionCode;
      } 
      catch (NameNotFoundException e) 
      {
            throw new RuntimeException("Could not get package name: " + e);
      }
}


private void registerInBackground() 
{     new AsyncTask() {
     Override
     protected Object doInBackground(Object... params) 
     {
          String msg = "";
          try 
          {
               if (gcm == null) 
               {
                        gcm = GoogleCloudMessaging.getInstance(context);
               }
               regid = gcm.register(SENDER_ID);               Log.d(TAG, "########################################");
               Log.d(TAG, "Current Device's Registration ID is: "+msg);     
          } 
          catch (IOException ex) 
          {
              msg = "Error :" + ex.getMessage();
          }
          return null;
     }     protected void onPostExecute(Object result) 
     { //to do here };
  }.execute(null, null, null);
}

注意:REGISTRATION_KEYを保存してください。PNメッセージをGCMに送信することは重要です。これは、GCMがプッシュ通知を送信するだけで、すべてのデバイスで一意になることにください。

プッシュ通知を受け取る

GCMブロードキャストレシーバークラスを追加

マニフェストファイルで「GcmBroadcastReceiver.java」をすでに宣言しているので、このクラスを作成して、この方法でレシーバークラスコードを更新します。

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) 
    {        ComponentName comp = new ComponentName(context.getPackageName(),
                GcmIntentService.class.getName());        startWakefulService(context, (intent.setComponent(comp)));
        setResultCode(Activity.RESULT_OK);
        Toast.makeText(context, wow!! received new push notification", Toast.LENGTH_LONG).show();
    }
}

GCMサービスクラスを追加

マニフェストファイルで「GcmBroadcastReceiver.java」をすでに宣言しているので、このクラスを作成して、この方法でレシーバークラスコードを更新します。

public class GcmIntentService extends IntentService
{     public static final int NOTIFICATION_ID = 1;     private NotificationManager mNotificationManager;     private final static String TAG = "GcmIntentService";     public GcmIntentService() {
     super("GcmIntentService");     
     }     @Override
     protected void onHandleIntent(Intent intent) {
          Bundle extras = intent.getExtras();
          Log.d(TAG, "Notification Data Json :" + extras.getString("message"));

          GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
          String messageType = gcm.getMessageType(intent);          if (!extras.isEmpty()) {          if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
               .equals(messageType)) {
               sendNotification("Send error: " + extras.toString());
          } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
          .equals(messageType)) {
          sendNotification("Deleted messages on server: "
          + extras.toString());          // If it's a regular GCM message, do some work.
          } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
          .equals(messageType)) {
          // This loop represents the service doing some work.
          for (int i = 0; i < 5; i++) {
               Log.d(TAG," Working... " + (i + 1) + "/5 @ "
               + SystemClock.elapsedRealtime());               try {
                    Thread.sleep(5000);
               } catch (InterruptedException e) {
               }
             }
             Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
             sendNotification(extras.getString("message"));
           }
        }        // Release the wake lock provided by the WakefulBroadcastReceiver.
        GcmBroadcastReceiver.completeWakefulIntent(intent);
     }     // Put the message into a notification and post it.
     // This is just one simple example of what you might choose to do with
     // a GCM message.
     private void sendNotification(String msg) {          mNotificationManager = (NotificationManager) this
          .getSystemService(Context.NOTIFICATION_SERVICE);
          PendingIntent contentIntent = PendingIntent.getActivity(this, 0,          new Intent(this, LaunchActivity.class), 0);

          NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(          this)
          .setSmallIcon(R.drawable.icon)
          .setContentTitle("Ocutag Snap")
          .setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
          .setContentText(msg)
          .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);

          mBuilder.setContentIntent(contentIntent);          mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
     }
}

@Rohitは、完全なチュートリアルがあるリンクを確認しましたか。また、不足しているものを教えてください。答えを更新します。
swiftBoy

11

Meteor Webサーバーに基づいて、Androidでプッシュ通知用のJavaライブラリを開発する新しいオープンソースの取り組みがあります。あなたはでそれをチェックアウトすることができディーコンプロジェクトブログあなたは流星へのリンクや、プロジェクトのGitHubのリポジトリを見つけることができます。開発者が必要なので広めてください!


9

Xtify(http://developer.xtify.com)を使用できます-彼らは彼らのSDKで動作するプッシュ通知ウェブサービスを持っています。それは無料で、今のところ、私にとっては非常にうまく機能しています。


3
彼らのVPから、プッシュサービスに課金する予定はないという返事がありました。それはかなり素晴らしいSDKです。
Crowe T. Robot

8

または...

3)サーバーへの接続を維持し、数分ごとにキープアライブを送信すると、サーバーは即座にメッセージをプッシュできます。これがGmailやGoogleトークなどの仕組みです。


5
悲しいことに、これはかなりの量のバッテリーを消耗させると思います。この方法をとる場合は、これを行う時間を制限するようにしてください。
haseman 2009

いいえ、実際にはありません。アイドル状態のTCP / IP接続は、セルモデムの電力をほとんど消費しないためです。
Isaac Waller

実際には、時間がかかるので大丈夫です。キープアライブを長い間隔で送信すると、非常に役立ちます。
Isaac Waller

これに関して「長い間隔」とは何ですか?私はGmailのプッシュがこのように機能することを知っていますが、どのタイムアウト間隔を使用するのかわかりません。
tobsen 2009

プルパフォーマンスとプッシュパフォーマンスに関するこの画像を見つけました:labs.ericsson.com/files/battery.jpgエリクソンプッシュAPIから取得し
Menda

6

GCMを使用することをお勧めします-Android向けGoogleクラウドメッセージングは 無料で、簡単に使用するには非常に簡単です。

ただし、ユーザーに代わって通知を送信するには、サードサイドサーバーを維持する必要があります。あなたがそれを避けたいなら、Androidのプッシュ通知サービスのためのいくつかの非常に優れた産業ソリューションがあります:

  • アーバン飛行船-1か月あたり最大100万通の通知が無料で、その後は1000通の通知ごとに課金されます
  • PushApps -1か月あたり100万通の通知は無料、1か月あたり19.99通は無制限の通知
  • PushWoosh -100万台のデバイスで無料、プレミアムプランは39ユーロから

Diclaimer-私はPushAppsで働いており、1年以上も自分のアプリケーションでその製品を使用しています。



4

両方の可能な方法を見つけたと思います。Googleは、少なくとも最初は、プッシュ/プル実装に使用できるGChat APIを実装する予定でした。残念ながら、そのライブラリはAndroid 1.0によって削除されました。


1
彼らは、セキュリティ問題が解決されたらそれを取り戻すと約束しました...それが起こった場合。
ジェレミーローガン

3

これがまだ有用かどうかはわかりません。私はhttp://www.pushlets.com/の javaライブラリでこのようなことを達成しました

Althougをサービスで実行しても、Androidがシャットダウンしてリスナースレッドが強制終了されるのを防ぐことはできません。


2

Google C2DMは廃止されました。そのため、新しいサービスGCM(Google Cloud Messaging)を使用します。文書化については、http: //developer.android.com/guide/google/gcm/gs.htmlを参照してください


2

C2DM:アプリユーザーはGmailアカウントを持っている必要があります。

MQTT:接続が1024に達すると、Linuxの「モデルの選択」を使用したため、動作が停止します。

Androidには無料のプッシュサービスとAPIがあり、試してみることができます:http : //push-notification.org


2

無料で簡単な方法:

ターゲットユーザーベースが大きくなく(1000未満)、無料のサービスを開始したい場合は、Airbopが最適で最も便利です。

Airbopウェブサイト は、APIを介してGoogleクラウドメッセージングサービスを使用し、優れたパフォーマンスを提供します。私は2つのプロジェクトで使用しており、簡単に実装できました。

およびUrbanshipのようなサービスは優れていますが、プッシュ通知だけでなく、デプロイメントスタック全体を提供します。

プッシュサービスのみがターゲットの場合、Airbopは正常に動作します。

私はPushwooshを使用していませんが、素晴らしい選択でもあります。1,000,000デバイスまで無料でプッシュできます


1

SMSとHTTPの両方を使用することをお勧めします。ユーザーがサインインしていない場合は、電話にSMSを送信して、メッセージが待機中であることを通知します。

これが、このエリクソンラボサービスのしくみです。https//labs.ericsson.com/apis/mobile-java-push/

これを自分で実装する場合、トリッキーな部分は、ユーザーに表示されずに着信SMSを削除することです。または、彼らがあなたのケースでそれを見た場合、それは大丈夫です。

次のように機能します: BroadCastReceiverを使用してSMSを削除する-Android

はい、このようなコードを書くことは危険である可能性があり、アプリケーションが必要のないSMSをアプリケーションが削除したため、誰かの人生を台無しにする可能性があります。


1
笑:「はい、このようなコードを書くのは危険な場合があり、アプリケーションが不要なSMSを削除したため、誰かの人生を台無しにする可能性があります。」そのために賛成票を投じます。笑。
Kumar Ravi 2013年

Mobile Java Pushへのリンクは無効になっており、サービス自体は廃止されているようです。
naXa

1

GoogleクラウドメッセージングまたはGCMを使用できます。無料で簡単に使用できます。また、PushWooshのようなサードパーティのプッシュサーバーを使用して、柔軟性を高めることもできます。



1

Firebase Cloud Messaging(FCM)はGCMの新しいバージョンです。FCMは、メッセージを安全かつ無料で送信できるクロスプラットフォームのメッセージングソリューションです。GCMの中央インフラストラクチャを継承して、Android、iOS、Web(JavaScript)、Unity、C ++でメッセージを確実に配信します。

2018年4月10日の時点で、GoogleはGCMを承認していません。GCMサーバーとクライアントAPIは非推奨であり、2019年4月11日に削除されます。GCMアプリケーションを、信頼性が高くスケーラブルなGCMインフラストラクチャを継承するFirebase Cloud Messaging(FCM)に移行することをお勧めします。

資源


0

プッシャーを使用できます

これは、Webおよびモバイルアプリケーションにリアルタイムのデータと機能を簡単に追加できるようにするホスティングサービスです。
プッシャーは、すべての主要なランタイムとフレームワークに統合するライブラリを提供します。

PHP, Ruby, Python, Java, .NET, Go and Nodeサーバー
JavaScript, Objective-C (iOS) and Java (Android)上のクライアント。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.