Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/181.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
GCM服务在Android 2.2上不可用_Android_Android 2.2 Froyo_Google Cloud Messaging_Google Play Services_Service Not Available - Fatal编程技术网

GCM服务在Android 2.2上不可用

GCM服务在Android 2.2上不可用,android,android-2.2-froyo,google-cloud-messaging,google-play-services,service-not-available,Android,Android 2.2 Froyo,Google Cloud Messaging,Google Play Services,Service Not Available,我在Android 2.2设备上的GoogleCloudMessaging.register()调用中收到错误“SERVICE\u NOT\u AVAILABLE” 我正在编写一个应用程序,使用新的Google Play服务使用Google CloudMessaging。我使用Android网站上提供的指南实现了它,我的源代码中包含大量错误检查和处理代码,例如确保安装或更新了Google Play服务。GCM注册码还实现了一个指数退避,正如google建议的那样,可以实现一个指数退避来处理服务不

我在Android 2.2设备上的GoogleCloudMessaging.register()调用中收到错误“SERVICE\u NOT\u AVAILABLE”

我正在编写一个应用程序,使用新的Google Play服务使用Google CloudMessaging。我使用Android网站上提供的指南实现了它,我的源代码中包含大量错误检查和处理代码,例如确保安装或更新了Google Play服务。GCM注册码还实现了一个指数退避,正如google建议的那样,可以实现一个指数退避来处理服务不可用的错误

我已经在一系列设备上测试了我的应用程序,包括ICS、JB、Honeycom甚至2.3.x设备。GCM注册工作正常,我可以通过GCM向其发送消息。然而,在2.2设备上,我在GoogleCloudMessaging.register()调用中不断收到一个SERVICE\u NOT\u AVAILABLE错误,即使在指数退避的情况下也是如此

GCM的故障设备准确地说是三星SGH-I896,手机上有2个谷歌账户。我已经读到这个错误可能是由错误配置的时间引起的,但是时间被设置为自动。该手机没有调制解调器,正在运行三星股票ROM

我还尝试过重新启动设备以及重新安装GooglePlay服务,但运气不好。在此问题上的任何帮助都将不胜感激

编辑:我尝试使用旧的GCM.jar和gcmregistar实现GCM,结果它在设备上工作。然而,由于谷歌已经不再支持这一方法,我几乎不认为这是一个很好的解决方案。
EDIT2:查看已接受的答案。

目前,除非谷歌修复此漏洞或有人提供更好的解决方案,否则我使用的是混合解决方案,它将在最初几次使用谷歌播放器服务(指数退避),但之后切换到GCMRegistar。

我遇到了同样的问题。GCM在我运行安卓4.04的平板电脑上运行良好,但在我运行安卓2.3的智能手机上总是收到一个不可用的服务

我发现以下解决方法没有使用(据我所知)任何不推荐的类。将操作“com.google.android.c2dm.intent.REGISTRATION”添加到清单中的GCMBroadcastReceiver。这将使您能够在GCMBroadcastReceiver接收注册id

<receiver
   android:name="YOUR_PACKAGE_NAME.GCMBroadcastReceiver"
   android:permission="com.google.android.c2dm.permission.SEND" >
      <intent-filter>
         <action android:name="com.google.android.c2dm.intent.RECEIVE" />
         <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

         <category android:name="YOUR_PACKAGE_NAME" />
      </intent-filter>
</receiver>

虽然我仍然收到服务不可用错误,但我可以在我的GCMBroadcastReceiver中处理注册id,并且我可以向智能手机发送消息。这很奇怪,但对我来说是有效的。

服务不可用可能是由于旧的或丢失的GooglePlayServices造成的。 使用GooglePlayServicesUtil检查版本,如果错误,则重定向到市场,以便用户可以手动安装-这将修复服务不可用的问题,并获得所有改进 和错误修复(以及新的错误:-)

如果您不能做到这一点-使用register()没有意义,那么该方法希望匹配的播放服务检索结果。为了向后兼容,它确实生成相同的广播。直接使用REGISTER intent或不推荐使用的库将继续工作-我建议使用intent,GCMRegistar与GoogleServicesFramework中的旧实现绑定(它调用intent.setPackage(GSF_PACKAGE)),因此无法从任何修复中获益


拥有最新版本的GCM——通过使用GooglePlayServicesUtil处理未自动安装的设备——不仅有助于注册。

在阅读了来自的帖子后,我尝试了下面的代码,我成功地让我的活动获得了注册。只需添加以下内容:

<activity
    android:name=".MyActivity"
    ... />
    <intent-filter>
        <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
        <category android:name="your.package.here" />
    </intent-filter>
</activity>


在您的AndroidManifest.xml中,还有一件事需要注意,这让我大吃一惊。 我让它在emulator+和测试应用程序中运行良好,但在实际设备上部署它时遇到了问题。
始终获得服务\u不可用错误,并采用与上述答案类似的方法:

     IntentFilter filter = new IntentFilter("com.google.android.c2dm.intent.REGISTRATION");
     BroadcastReceiver receiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             Log.i(TAG, "Got into onReceive for manual GCM retrieval. "
             + intent.getExtras());
             String regId = intent.getStringExtra("registration_id");

             if (regId != null && !regId.isEmpty()) {
                 theResult.add(regId);
             } else {
                 theResult.add("");
             }
             lastDitchEffortComplete = true;
             }
         };
     cont.registerReceiver(receiver, filter);
这种方法奏效了。 但收到这些信息花了相当长的时间,在我的等待循环中,只有在我放弃并让事情继续进行之后,它才会检索到这些信息

这让我想到服务不可用可能还有另一个原因

这是我必须使用GCM进行抓取/注册的代码:

new AsyncTask<Void, Void, Void>() {
                final long timeSleep = 1000;

                @Override
                protected Void doInBackground(Void... params) {
                    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(cont);
                    String registrationId = "";
                    int count = 0;
                    while (count < 1) {
                        try {
                            count++;
                            Log.i(TAG, "Starting GCM Registration Attempt #" + count);
                            registrationId = gcm.register(CLOUDAPPID);
                            rph.storeRegistrationId(registrationId);
                            return null;
                        } catch (IOException e) {
                            e.printStackTrace();
                        }

                        Log.w(TAG, "Registration failed.  Retrying in " + timeSleep + " ms.");
                        try {
                            Thread.sleep(timeSleep);
                        } catch (InterruptedException e) {
                        }
                    }

                    return null;
                }
            }.execute().get();
阻止异步线程外结果的“聪明/欺骗”方法

事实证明,这就是造成问题的原因。 我刚一有:

.execute();

让它通过,并使算法/代码与报告一起工作,而不需要立即注册id,然后就可以了。我甚至不需要手动广播接收器,它只是正常工作。

如果标记的答案对您不起作用(就像对我一样),请检查您设备前面的人,可能摇动它,然后启用internet连接。为我工作;-)


如果没有internet,您会收到相同的异常,我花了一个下午的时间研究服务的复杂问题……

这个错误也发生在我身上,但它发生了,因为我试图通过公司的防火墙在GCM中注册。在我找到的文档中:

“注意:如果您的组织具有限制流量的防火墙 到Internet或从Internet访问时,您需要将其配置为允许 连接GCM,以便您的Android设备接收 要打开的端口通常为:5228、5229和5230.GCM 仅使用5228,但有时使用5229和5230。GCM不使用 提供特定的IP,因此您应该允许防火墙接受 到IP块中包含的所有IP地址的传出连接 在谷歌15169年的ASN中列出。”


一旦我打开端口或尝试从另一个网络,它就工作了。

我也有同样的问题,但它发生在所有设备上。我花了很长时间才发现我的问题,但我想我
.execute.get();
.execute();
public class Login extends Activity {
    Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        context = getApplicationContext();

        //Get GCM registration id
        new GcmRegistrationAsyncTask().execute(context);

        Set<Tuple> timeline = new HashSet<Tuple>();
        try {
            //Get data from Redis database
            timeline = new RedisAsyncTask().execute(context).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
public class Login extends Activity {
    Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        context = getApplicationContext();

        new GcmRegistrationAsyncTask().execute(context);
        new RedisAsyncTask().execute(context);
    }
}