Android 平台中的推送通知

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1378671/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 03:01:17  来源:igfitidea点击:

Push Notifications in Android Platform

androidpushalerts

提问by Vinod

I am looking to write an app that receives pushed alerts from a server. I found a couple of methods to do this.

我正在寻找编写一个从服务器接收推送警报的应用程序。我找到了几种方法来做到这一点。

  1. SMS - Intercept the incoming SMS and initiate a pull from the server
  2. Poll the server periodically
  1. SMS - 拦截传入的 SMS 并从服务器发起拉取
  2. 定期轮询服务器

Each has its own limitations. SMS- no guarantee on arrival time. Poll may drain the battery.

每个都有其自身的局限性。短信 - 不保证到达时间。轮询可能会耗尽电池电量。

Do you have a better suggestion please? Thanks very much.

请问您有更好的建议吗?非常感谢。

采纳答案by BoD

Google's official answer is the Android Cloud to Device Messaging Framework(deprecated)Google Cloud Messaging(deprecated)Firebase Cloud Messaging

Google 的官方答案是Android Cloud to Device Messaging Framework(deprecated) Google Cloud Messaging(deprecated) Firebase Cloud Messaging

It will work on Android >= 2.2 (on phones that have the Play Store).

它适用于 Android >= 2.2(在具有 Play 商店的手机上)。

回答by dalelane

(cross-posting from an answer I gave to a similar question - Does Android support near real time push notification?)

从我对类似问题的回答中交叉发布 - Android 是否支持近乎实时的推送通知?

I recently started playing with MQTT http://mqtt.orgfor Android as a way of doing this sort of thing (i.e. push notification that is not SMS but data driven, almost immediate message delivery, not polling, etc.)

我最近开始在Android 上使用 MQTT http://mqtt.org作为做这种事情的一种方式(即不是 SMS 而是数据驱动的推送通知,几乎是即时的消息传递,而不是轮询等)

I have a blog post with background information on this in case it's helpful

我有一篇博客文章,里面有这方面的背景信息,以防万一

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

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

(Note: MQTT is an IBM technology, and I should point out that I work for IBM.)

(注意:MQTT 是 IBM 的一项技术,我应该指出我为 IBM 工作。)

回答by Lalit

My understanding/experience with Android push notification are:

我对 Android 推送通知的理解/经验是:

  1. C2DMGCM- If your target android platform is 2.2+, then go for it. Just one catch, device users have to be always logged with a Google Accountto get the messages.

  2. MQTT- Pub/Sub based approach, needs an active connection from device, may drain battery if not implemented sensibly.

  3. Deacon- May not be good in a long run due to limited community support.

  1. C2DM GCM- 如果你的目标安卓平台是 2.2+,那就去吧。只是一个问题,设备用户必须始终使用 Google 帐户登录才能获取消息。

  2. MQTT- 基于 Pub/Sub 的方法,需要来自设备的主动连接,如果实施不当,可能会耗尽电池电量。

  3. 执事- 由于社区支持有限,从长远来看可能不会很好。

Edit: Added on November 25, 2013

编辑:2013 年 11 月 25 日添加

GCM- Google says...

GCM- 谷歌说...

For pre-3.0 devices, this requires users to set up their Google account on their mobile devices. A Google account is not a requirement on devices running Android 4.0.4 or higher.*

对于 3.0 之前的设备,这要求用户在其移动设备上设置其 Google 帐户。运行 Android 4.0.4 或更高版本的设备不需要 Google 帐户。*

回答by chiranjib

Android Cloud to Device Messaging Framework

Android 云到设备消息传递框架

Important: C2DM has been officially deprecated as of June 26, 2012.This means that C2DM has stopped accepting new users and quota requests. No new features will be added to C2DM. However, apps using C2DM will continue to work. Existing C2DM developers are encouraged to migrate to the new version of C2DM, called Google Cloud Messaging for Android (GCM). See the C2DM-to-GCM Migration document for more information. Developers must use GCM for new development.

重要提示:C2DM 已于 2012 年 6 月 26 日正式弃用。这意味着 C2DM 已停止接受新用户和配额请求。C2DM 不会添加任何新功能。但是,使用 C2DM 的应用程序将继续工作。鼓励现有的 C2DM 开发人员迁移到新版本的 C2DM,称为 Android 版 Google Cloud Messaging (GCM)。有关更多信息,请参阅 C2DM 到 GCM 迁移文档。开发人员必须使用 GCM 进行新的开发。

Kindly check the following link:

请检查以下链接:

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

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

回答by swiftBoy

Here I have written few steps for How to Get RegID and Notification starting from scratch

在这里我写了几个步骤如何从头开始获取 RegID 和通知

  1. Create/Register App on Google Cloud
  2. Setup Cloud SDK with Development
  3. Configure project for GCM
  4. Get Device Registration ID
  5. Send Push Notifications
  6. Receive Push Notifications
  1. 在 Google Cloud 上创建/注册应用
  2. 使用开发设置 Cloud SDK
  3. 为 GCM 配置项目
  4. 获取设备注册 ID
  5. 发送推送通知
  6. 接收推送通知

You can find complete tutorial in below URL link

您可以在以下 URL 链接中找到完整的教程

Getting Started with Android Push Notification : Latest Google Cloud Messaging (GCM) - step by step complete tutorial

Android 推送通知入门:最新的 Google Cloud Messaging (GCM) - 分步完整教程

enter image description here

在此处输入图片说明

Code snip to get Registration ID (Device Token for Push Notification).

获取注册 ID(推送通知的设备令牌)的代码片段。

Configure project for GCM

为 GCM 配置项目



Update AndroidManifest file

更新 AndroidManifest 文件

For enable GCM in our project we need to add few permission in our manifest file Go to AndroidManifest.xml and add below code Add Permission

为了在我们的项目中启用 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" />

Add GCM Broadcast Receiver declaration

添加 GCM 广播接收器声明

add GCM Broadcast Receiver declaration in your application tag

在您的应用程序标签中添加 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/>

Add GCM Servie declaration

添加 GCM 服务声明

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


Get Registration ID (Device Token for Push Notification)

获取注册 ID(推送通知的设备令牌)

Now Go to your Launch/Splash Activity

现在转到您的启动/启动活动

Add Constants and Class Variables

添加常量和类变量

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;

Update OnCreate and OnResume methods

更新 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);
}


Note: please store REGISTRATION_KEY, it is important for sending PN Message to GCM also keep in mine this will be unique for all device, by using this only GCM will send Push Notification.

注意:请存储 REGISTRATION_KEY,将 PN 消息发送到 GCM 很重要也请保存在我的这对所有设备都是唯一的,通过使用这个只有 GCM 将发送推送通知。

Receive Push Notifications

接收推送通知

Add GCM Broadcast Receiver Class

添加 GCM 广播接收器类

As we have already declared “GcmBroadcastReceiver.java” in our Manifest file, So lets create this class update receiver class code this way

由于我们已经在 Manifest 文件中声明了“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();
    }
}

Add GCM Service Class

添加 GCM 服务类

As we have already declared “GcmBroadcastReceiver.java” in our Manifest file, So lets create this class update receiver class code this way

由于我们已经在 Manifest 文件中声明了“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());
     }
}

回答by mtbkrdave

There is a new open-source effort to develop a Java library for push notifications on Android based on the Meteor web server. You can check it out at the Deacon Project Blog, where you'll find links to Meteor and the project's GitHub repository. We need developers, so please spread the word!

有一项新的开源工作是为基于 Meteor Web 服务器的 Android 上的推送通知开发 Java 库。您可以在Deacon 项目博客 中查看它,在那里您可以找到 Meteor 和该项目的 GitHub 存储库的链接。我们需要开发人员,所以请宣传!

回答by peter

You can use Xtify (http://developer.xtify.com) - they have a push notifications webservice that works with their SDK. it's free and so far, it's worked really well for me.

您可以使用 Xtify ( http://developer.xtify.com) - 他们有一个适用于他们的 SDK 的推送通知网络服务。它是免费的,到目前为止,它对我来说效果很好。

回答by Isaac Waller

or....

或者....

3)Keep a connection to the server, send keep-alives every few minutes, and the server can push messages instantly. This is how Gmail, Google Talk, etc. works.

3)保持与服务器的连接,每隔几分钟发送一次keep-alives,服务器可以即时推送消息。这就是 Gmail、Google Talk 等的工作原理。

回答by Orr

I recommend using GCM - Google Cloud Messaging for AndroidIt's free, and for simple uses it's should be very easy.

我建议使用GCM - 适用于 Android 的 Google Cloud Messaging它是免费的,对于简单的使用来说应该很容易。

However it requires to maintain a 3rd side server to send the notifications on your behalf. If you want to avoid that there are some very good industrial solutions for Android push notifications service:

但是,它需要维护一个第三端服务器来代表您发送通知。如果你想避免 Android 推送通知服务有一些非常好的工业解决方案:

  • Urban Airship- free up to 1M notifications per month, afterwards you are charged per 1000 notifications
  • PushApps- free for 1M notifications per month, and unlimited notifications for 19.99 per month
  • PushWoosh- free for 1M devices, premium plans are from 39 EURO
  • Urban Airship- 每月最多免费 100 万条通知,之后每 1000 条通知收费
  • PushApps- 每月 100 万条通知免费,每月 19.99 条通知无限制
  • PushWoosh- 100 万台设备免费,高级计划起价 39 欧元

Diclaimer- I work in PushApps and also use their product in my applications for over a year now.

免责声明- 我在 PushApps 工作并且在我的应用程序中使用他们的产品已经一年多了。

回答by Freek Nortier

As of 18/05/2016 Firebaseis Google's unified platform for mobile developers including push notifications.

截至 2016 年 5 月 18 日,Firebase是 Google 为移动开发人员提供的统一平台,包括推送通知。