首页 文章

在Android平台中推送通知

提问于
浏览
260

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

  • SMS - 拦截传入的SMS并从服务器启动拉取

  • 定期轮询服务器

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

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

20 回答

  • 2

    Android Cloud to Device Messaging Framework

    Important: C2DM has been officially deprecated as of June 26, 2012. 这意味着C2DM已停止接受新用户和配额请求 . C2DM不会添加任何新功能 . 但是,使用C2DM的应用程序将继续运行 . 鼓励现有C2DM开发人员迁移到新版本的C2DM,称为Google Cloud Messaging for Android(GCM) . 有关更多信息,请参阅C2DM-to-GCM迁移文档 . 开发人员必须使用GCM进行新开发 .

    请检查以下链接:

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

  • 17

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

    • 在Google Cloud上创建/注册应用

    • 使用开发设置Cloud SDK

    • 为GCM配置项目

    • 获取设备注册ID

    • 发送推送通知

    • 接收推送通知

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

    Android推送通知入门:最新的Google Cloud 消息传递(GCM) - 一步一步的完整教程

    enter image description here

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

    Configure project for 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 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/>
    

    添加GCM Servie声明

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

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

    Now Go to your Launch/Splash Activity

    添加常量和类变量

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

    Note :请存储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();
        }
    }
    

    添加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());
         }
    }
    
  • 29

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

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

  • 1

    (从我给出的类似问题的答案中交叉发布 - Does Android support near real time push notification?

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

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

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

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

  • 8

    你可以使用Pusher

    它是一种托管服务,可以非常轻松地为Web和移动应用程序添加实时数据和功能 .
    Pusher提供了集成到所有主要运行时和框架的库 .

    PHP, Ruby, Python, Java, .NET, Go and Node 在服务器上
    JavaScript, Objective-C (iOS) and Java (Android) 在客户端上 .

  • 6

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

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

    • MQTT - 基于发布/订阅的方法,需要从设备进行主动连接,如果没有合理实施,可能会耗尽电池 .

    • Deacon - 由于社区支持有限,从长远来看可能不太好 .

    Edit :已于2013年11月25日添加

    GCM - Google说......

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

  • 2

    有一项新的开源工作,即在Android上基于Meteor Web服务器开发推送通知的Java库 . 你可以在the Deacon Project Blog查看它,你在哪里'll find links to Meteor and the project'的GitHub存储库 . 我们需要开发人员,所以请传播!

  • 17

    您可以使用Xtify(http://developer.xtify.com) - 他们有一个推送通知Web服务,可以与他们的SDK一起使用 . 它's free and so far, it'对我来说真的很好 .

  • 1

    要么....

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

  • 3

    我建议使用GCM - Google Cloud Messaging for Android它's free, and for simple uses it'应该很容易 .

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

    • Urban Airship - 每月最多可提供1M次通知,之后每1000次通知收费

    • PushApps - 每月免费提供1M次通知,每月免费通知19.99次

    • PushWoosh - 1M设备免费,优惠计划为39欧元

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

  • 1

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

  • 201

    我担心你找到了两种可能的方法 . 谷歌至少在最初阶段将实施一个可用于推/拉实现的GChat API . 可悲的是,该库被Android 1.0削减了 .

  • 11

    我不知道这是否仍然有用 . 我在http://www.pushlets.com/用java库实现了类似的功能

    Althoug在服务中执行此操作不会阻止android关闭它以杀死侦听器线程 .

  • 9

    Google C2DM现已弃用,因此您可以使用新服务GCM(Google Cloud Messaging) . 有关说明,请参阅http://developer.android.com/guide/google/gcm/gs.html

  • 6

    C2DM:您的应用用户必须拥有Gmail帐户 .

    MQTT:当你的连接达到1024时,由于它使用了linux的“select model”,它将停止工作 .

    有一个免费的推送服务和api for android,你可以尝试一下:http://push-notification.org

  • 17

    Free and easy method:

    如果您的目标用户群不是很大(小于1000)并且您想要免费服务,那么Airbop是最好和最方便的 .

    Airbop Website它通过其API使用Google Cloud Messaging服务,并提供了良好的性能 . 我已将它用于我的两个项目,并且很容易实现它 .

    像Urbanship这样的服务非常出色,但提供整个部署堆栈而不仅仅是推送通知 .

    如果只推送服务是您的目标,Airbop将正常工作 .

    我没有使用Pushwoosh,但也是一个很好的选择 . 它允许免费推送1,000,000台设备

  • 0

    我建议使用短信和HTTP . 如果用户未登录,则向他们的手机发送短信通知他们有消息等待 .

    这就是爱立信实验室服务的工作方式:https://labs.ericsson.com/apis/mobile-java-push/

    如果您自己实现这一点,那么棘手的部分是删除传入的SMS,而无需用户看到它 . 或者,如果他们在你的情况下看到它,也许没关系 .

    看起来像这样:Deleting SMS Using BroadCastReceiver - Android

    是的,编写这样的代码可能很危险,并且您可能会破坏某人的生命,因为您的应用程序删除了它不应该拥有的SMS .

  • 2

    您可以使用Google Cloud Messaging或GCM,它免费且易于使用 . 您也可以使用第PushWoosh之类的第三方推送服务器,它可以提供更大的灵活性

  • 4

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

  • 1

    Firebase Cloud Messaging(FCM)是GCM的新版本 . FCM是一种跨平台的消息传递解决方案,允许您安全且免费地发送消息 . 继承GCM的中央基础架构,在Android,iOS,Web(javascript),Unity和C上可靠地传递消息 .

    截至2018年4月10日,谷歌已经拒绝了GCM . GCM服务器和客户端API已弃用,将于2019年4月11日删除.Google建议将GCM应用程序迁移到Firebase Cloud Messaging(FCM),后者继承了可靠且可扩展的GCM基础架构 .

    Resource

相关问题