在Android平台中推送通知

Vin*_*nod 264 android push alerts

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

  1. SMS - 拦截传入的SMS并从服务器启动拉取
  2. 定期轮询服务器

每个都有自己的局限性.短信 - 抵达时无法保证.民意调查可能会耗尽电池电量.

你有更好的建议吗?非常感谢.

BoD*_*BoD 203

Google的官方答案是Android云到设备消息传递框架(已弃用) Google云消息传递(已弃用) Firebase云消息传递

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

  • 请注意,已弃用Android Cloud to Device Messaging Framework.新框架称为Google Cloud Messaging,可在此处找到:http://developer.android.com/guide/google/gcm/index.html (33认同)
  • 问题是您需要为您的用户设置一个Google帐户:我认为这是一个约束. (6认同)
  • @Vinod请接受这个作为正确答案,以便它出现在结果的顶部.这绝对是未来的发展方向! (5认同)
  • 您通常可以非常快速地激活它,它被用于像GMail这样的东西,所以知道在生产中工作.不幸的是,他们缺乏与C2DM服务器端方面通信的示例代码.我在这里写了一个关于这个方面的教程http://blog.boxedice.com/2010/10/07/android-push-notifications-tutorial/ (3认同)

dal*_*ane 29

(从我给出的类似问题的答案中交叉发布 - Android是否支持实时推送通知?)

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

我有一篇博客文章,其中包含有关这方面的背景信息,以防它有用

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

(注意:MQTT是一种IBM技术,我应该指出我在IBM工作.)

  • 它确实保持连接打开.在后续帖子(http://dalelane.co.uk/blog/?p=1009)中,我确实更多地讨论了保持连接打开的含义 - 你看到了吗?如果连接断开,则可以通知服务器和客户端.然后是应用层决定决定如何响应(例如重新连接).该帖子中提到的文档中有更多信息(例如IA92:该页面上的http://www-01.ibm.com/support/docview.wss?rs=171&uid=swg24006006 pdf,以及邮编中的Javadoc那个页面) (2认同)

小智 17

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

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

  2. MQTT - 基于发布/ 订阅的方法,需要来自设备的有效连接,如果没有明智地实现,可能会耗尽电池.

  3. 执事 - 由于社区支持有限,长期来看可能并不好.

编辑:2013年11月25日添加

GCM - 谷歌说......

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


chi*_*jib 17

Android云到设备消息传递框架

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

请检查以下链接:

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


swi*_*Boy 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" />
Run Code Online (Sandbox Code Playgroud)

添加GCM广播接收器声明

在应用程序标记中添加GCM Broadcast Receiver声明

<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/>
Run Code Online (Sandbox Code Playgroud)

添加GCM Servie声明

<application
     <service android:name=".GcmIntentService" />
<application/>
Run Code Online (Sandbox Code Playgroud)

获取注册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;
Run Code Online (Sandbox Code Playgroud)

更新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);
}
Run Code Online (Sandbox Code Playgroud)

注意:请存储REGISTRATION_KEY,将GC消息发送到GCM也很重要,这对于所有设备都是唯一的,通过使用此功能,只有GCM才会发送推送通知.

接收推送通知

添加GCM广播接收器类

因为我们已经在我们的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

添加GCM服务类

因为我们已经在我们的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());
     }
}
Run Code Online (Sandbox Code Playgroud)


mtb*_*ave 11

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


小智 9

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

  • 我得到了他们的副总裁的答复说,没有计划对推送服务收费.这是一个非常棒的SDK. (3认同)

Isa*_*ler 8

要么....

3)保持与服务器的连接,每隔几分钟发送一次保持活动,服务器可以立即推送消息.这就是Gmail,Google Talk等的工作方式.

  • 遗憾的是,我认为这会产生大量的电池消耗.如果您采取这种方式,请确保限制您执行此操作的时间. (5认同)

Orr*_*Orr 6

我建议使用GCM - Google Cloud Messaging for Android 它是免费的,对于简单的用途,它应该非常简单.

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

  • Urban Airship - 每月免费提供1M次通知,之后每1000次通知收费
  • PushApps - 每月1M次通知免费,每月19.99次无限制通知
  • PushWoosh - 免费提供1M设备,优惠计划为39欧元

Diclaimer - 我在PushApps工作,并且在我的应用程序中使用他们的产品已有一年多了.


Fre*_*ier 6

截至2016年5月18日,Firebase是Google面向移动开发者的统一平台,包括推送通知.