简体   繁体   English

在Android平台中推送通知

[英]Push Notifications in Android Platform

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 SMS-拦截传入的SMS并启动从服务器的拉取
  2. Poll the server periodically 定期轮询服务器

Each has its own limitations. 每个都有其自身的局限性。 SMS- no guarantee on arrival time. SMS-无法保证到达时间。 Poll may drain the battery. 轮询可能会耗尽电池。

Do you have a better suggestion please? 请问您有更好的建议吗? Thanks very much. 非常感谢。

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 (不推荐使用) Google Cloud Messaging (不推荐使用) Firebase Cloud Messaging

It will work on Android >= 2.2 (on phones that have the Play Store). 它将在大于等于2.2的Android上运行(在具有Play商店的手机上)。

( 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.org for Android as a way of doing this sort of thing (ie 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工作。)

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. 重要说明:自2012年6月26日起,C2DM已正式弃用。这意味着C2DM已停止接受新用户和配额请求。 No new features will be added to C2DM. 不会将任何新功能添加到C2DM。 However, apps using C2DM will continue to work. 但是,使用C2DM的应用将继续运行。 Existing C2DM developers are encouraged to migrate to the new version of C2DM, called Google Cloud Messaging for Android (GCM). 鼓励现有的C2DM开发人员迁移到新版本的C2DM,称为Android的Google Cloud Messaging(GCM)。 See the C2DM-to-GCM Migration document for more information. 有关更多信息,请参见从C2DM到GCM的迁移文档。 Developers must use GCM for new development. 开发人员必须使用GCM进行新开发。

Kindly check the following link: 请检查以下链接:

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

Here I have written few steps for How to Get RegID and Notification starting from scratch 在这里,我已经写了一些有关如何从头开始获取RegID和通知的步骤

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

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 Push Notification入门:最新的Google Cloud Messaging(GCM)-逐步完成教程

在此处输入图片说明

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 Servie声明

<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 因为我们已经在清单文件中声明了“ 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 因为我们已经在清单文件中声明了“ 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());
     }
}

My understanding/experience with Android push notification are: 我对Android推送通知的了解/经验是:

  1. C2DM GCM - If your target android platform is 2.2+, then go for it. C2DM GCM-如果您的目标android平台是2.2+,请继续使用。 Just one catch, device users have to be always logged with a Google Account to get the messages. 仅需注意,设备用户必须始终使用Google帐户登录才能获取消息。

  2. MQTT - Pub/Sub based approach, needs an active connection from device, may drain battery if not implemented sensibly. MQTT-基于发布/ 订阅的方法,需要与设备进行主动连接,如果不明智地实施,则可能会耗尽电池。

  3. Deacon - May not be good in a long run due to limited community support. 执事 -由于社区支持有限,从长远来看可能并不好。

Edit : Added on November 25, 2013 编辑 :2013年11月25日新增

GCM - Google says... GCM -Google说...

For pre-3.0 devices, this requires users to set up their Google account on their mobile devices. 对于3.0之前的设备,这要求用户在其移动设备上设置其Google帐户。 A Google account is not a requirement on devices running Android 4.0.4 or higher.* 运行Android 4.0.4或更高版本的设备不需要Google帐户。*

There is a new open-source effort to develop a Java library for push notifications on Android based on the Meteor web server. 有一个新的开放源代码工作,用于开发基于Meteor Web服务器的Android上的推送通知的Java库。 You can check it out at the Deacon Project Blog , where you'll find links to Meteor and the project's GitHub repository. 您可以在Deacon Project博客上进行检查,在该博客中您可以找到指向Meteor和项目的GitHub存储库的链接。 We need developers, so please spread the word! 我们需要开发人员,所以请大声疾呼!

You can use Xtify ( http://developer.xtify.com ) - they have a push notifications webservice that works with their SDK. 您可以使用Xtify( http://developer.xtify.com )-他们具有与SDK配合使用的推送通知网络服务。 it's free and so far, it's worked really well for me. 它是免费的,到目前为止,它对我来说真的很好用。

or.... 要么....

3) Keep a connection to the server, send keep-alives every few minutes, and the server can push messages instantly. 3)保持与服务器的连接,每隔几分钟发送一次保持连接状态,服务器可以立即推送消息。 This is how Gmail, Google Talk, etc. works. 这就是Gmail,Google Talk等的工作方式。

I recommend using GCM - Google Cloud Messaging for Android It'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 城市飞艇 -每月最多可免费发送100万条通知,之后每1000条通知向您收费
  • PushApps - free for 1M notifications per month, and unlimited notifications for 19.99 per month PushApps-每月免费发送1M通知,每月无限发送通知19.99
  • PushWoosh - free for 1M devices, premium plans are from 39 EURO PushWoosh -1M设备免费,高级计划从39欧元起

Diclaimer - I work in PushApps and also use their product in my applications for over a year now. 免责声明 -我在PushApps工作,并且在我的应用程序中使用它们的产品已有一年多的时间。

自2016年5月18日起, Firebase是Google面向移动开发人员的统一平台,其中包括推送通知。

I'm afraid you've found both possible methods. 恐怕您已经找到了两种可能的方法。 Google was, at least initially, going to implement a GChat api you could use for a push/pull implementation. 至少在最初,Google打算实现可用于推/拉实现的GChat api。 Sadly, that library was cut by Android 1.0. 可悲的是,该库已被Android 1.0切断。

I dont know if this is still useful. 我不知道这是否仍然有用。 I achieved something like this with a java library at http://www.pushlets.com/ 我通过http://www.pushlets.com/上的java库实现了类似的功能

Althoug doing it in a service won't prevent android from shutting it down an killing the listener thread. Althoug在服务中执行此操作不会阻止android将其关闭,从而杀死侦听器线程。

C2DM: your app-users must have the gmail account. C2DM:您的应用程序用户必须具有gmail帐户。

MQTT: when your connection reached to 1024, it will stop work because of it used "select model " of linux. MQTT:当您的连接数达到1024时,由于使用了Linux的“ select model”,它将停止工作。

There is a free push service and api for android, you can try it: http://push-notification.org 有一个免费的推送服务和适用于Android的api,您可以尝试: http : //push-notification.org

Google C2DM is depreciated now, for that, you have o use the new service GCM (Google Cloud Messaging). Google C2DM已过时,为此,您必须使用新服务GCM(Google Cloud Messaging)。 For documantation, see http://developer.android.com/guide/google/gcm/gs.html 有关文档的信息,请参见http://developer.android.com/guide/google/gcm/gs.html

Free and easy method: 自由简便的方法:

If your target user base is not large(less than a 1000) and you want a free service to start with, then Airbop is the best and most convenient. 如果您的目标用户群不大(少于1000),并且您想开始免费服务,那么Airbop就是最好和最方便的选择。

Airbop Website It uses Google Cloud Messaging service through its API and is provides a good performance. Airbop网站通过其API使用Google Cloud Messaging服务,并提供良好的性能。 i have used it for two of my projects and it was easy implementing it. 我已经将它用于我的两个项目,并且很容易实现。

Services like and Urbanship are excellent but provide an entire deployment stack and not just the push notifications thing. 诸如Urbanship之类的服务非常出色,但提供了整个部署堆栈,而不仅仅是推送通知。

If only push service is your target, Airbop will work fine. 如果仅推送服务是您的目标,Airbop会正常工作。

I haven't used Pushwoosh , but is also a great choice. 我没有使用Pushwoosh ,但这也是一个不错的选择。 It allows push to 1,000,000 devices for free 它允许免费推送到1,000,000台设备

You can use Google Cloud Messaging or GCM , it's free and easy to use. 您可以使用Google Cloud Messaging或GCM ,它是免费且易于使用的。 Also you can use third party push servers like PushWoosh which gives you more flexibility 您也可以使用第三方推送服务器,例如PushWoosh ,它可以为您提供更大的灵活性

有很多第三方服务器,例如Urban Airship ,Xtify, Mainline ,...,这些服务器不仅允许在Android上发送,而且还可以在iO,Windows Phone上发送...

I would suggest using both SMS and HTTP. 我建议同时使用SMS和HTTP。 If the user is not signed in send their phone an SMS to notify them there's a message waiting. 如果用户未登录,请向其手机发送一条SMS通知他们正在等待消息。

That's how this Ericsson Labs service works: https://labs.ericsson.com/apis/mobile-java-push/ 这就是爱立信实验室服务的工作方式: https : //labs.ericsson.com/apis/mobile-java-push/

If you implement this yourself the tricky part is deleting the incoming SMS without the user seeing it. 如果您自己执行此操作,那么棘手的部分是删除传入的SMS,而用户不会看到它。 Or maybe it's ok if they see it in your case. 或者,如果他们看到您的情况,也可以。

Looks like this works: Deleting SMS Using BroadCastReceiver - Android 看起来像这样: 使用BroadCastReceiver删除短信-Android

Yes, writing code like this can be dangerous and you can potentially ruin someone's life because your application deleted an SMS it shouldn't have. 是的,这样编写代码可能很危险,并且可能会破坏某人的生命,因为您的应用程序删除了本不应该的SMS。

Firebase Cloud Messaging (FCM) is the new version of GCM. Firebase Cloud Messaging (FCM)是GCM的新版本。 FCM is a cross-platform messaging solution that allows you to send messages securely and for free. FCM是一种跨平台的消息传递解决方案,使您可以安全地免费发送消息。 Inherits GCM's central infrastructure to deliver messages reliably on Android, iOS, Web (javascript), Unity and C ++. 继承GCM的中央基础结构,以在Android,iOS,Web(javascript),Unity和C ++上可靠地传递消息。

As of April 10, 2018, Google has disapproved of GCM. 截至2018年4月10日,Google已拒登GCM。 The GCM server and client APIs are deprecated and will be removed on April 11, 2019. Google recommends migrating GCM applications to Firebase Cloud Messaging (FCM), which inherits the reliable and scalable GCM infrastructure. 不建议使用GCM服务器和客户端API,并将于2019年4月11日删除。Google建议将GCM应用程序迁移到Firebase Cloud Messaging(FCM),后者继承了可靠且可扩展的GCM基础架构。

Resource 资源资源

You can use Pusher 您可以使用Pusher

It's a hosted service that makes it super-easy to add real-time data and functionality to web and mobile applications. 它是一项托管服务,可以非常轻松地向Web和移动应用程序添加实时数据和功能。
Pusher offers libraries to integrate into all the main runtimes and frameworks. Pusher提供了可集成到所有主要运行时和框架中的库。

PHP, Ruby, Python, Java, .NET, Go and Node on the server PHP, Ruby, Python, Java, .NET, Go and Node
JavaScript, Objective-C (iOS) and Java (Android) on the client. 客户端上的JavaScript, Objective-C (iOS) and Java (Android)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM