谷歌云消息注册失败

7

问题已解决 更新:

我已经解决了这个问题。 问题出现在方法registerGCMInBackground()中。 GoogleCloudMessaging.getInstance()需要传入ApplicationContext作为参数。

    private void registerGCMInBackground(final String userId) {
    new AsyncTask<Void, Void, String>() {
        @Override
        protected String doInBackground(Void... params) {
            String msg = "";
            Log.d("Register GCM", "started");
            try {
                if (gcm == null) {
                    //PROBLEM SOLVED HERE
                    gcm = GoogleCloudMessaging.getInstance(getApplicationContext());
                    Log.d("GCM", gcm.toString());
                }



                regid = gcm.register(SENDER_ID); //////NULL POINTER EXCEPTION
                msg = "Device registered, registration ID=" + regid;



                // You should send the registration ID to your server over HTTP
                sendRegistrationIdToBackend(userId, regid);

                // For this demo: we don't need to send it because the device will send
                // upstream messages to a server that echo back the message using the
                // 'from' address in the message.

                // Persist the regID - no need to register again.
                storeRegistrationId(context, regid);
            } catch (IOException ex) {
                return "Error :" + ex.getMessage();
                // If there is an error, don't just keep trying to register.
                // Require the user to click a button again, or perform
                // exponential back-off.
            }
            return regid;
        }

--------问题已解决--------------

我在使用 GCM (Google Cloud Messaging) 注册我的 Android 设备时遇到了问题。我正在使用来自 Google Developers 的示例。通过使用 Google Developer 示例,我确保了以下几点:

  • 添加最新的 Play 服务库
  • 添加最新的 Play 服务 JAR
  • 正确的清单文件(Manifest file)
  • 在设备上安装了 Play 服务 APK
  • 使用项目编号作为 SENDER_ID

看起来这个问题与这个 问题 是一样的。不幸的是,它仍未得到解答。 我在以下代码行中遇到了 Null Pointer Exception:

regid = gcm.register(SENDER_ID);

这是我的问题代码: 示例活动

     static final String TAG = "GCM";
    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 static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
    String SENDER_ID = "xxxxxxxxxxxxxxx";
    GoogleCloudMessaging gcm;
    AtomicInteger msgId = new AtomicInteger();
    Context context;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);
            setContentView(R.layout.registration);

            final Button register = (Button) findViewById(R.id.btn_register);

            register.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {

                     EditText mobilePhoneNumber = (EditText) findViewById(R.id.et_phonenumber);

                    if(!mobilePhoneNumber.getText().toString().isEmpty()){
                    User user = new User();
                    user.setMobilePhoneNumber(mobilePhoneNumber.getText().toString());

                     EditText firstName = (EditText) findViewById(R.id.et_firstName);
                    user.setFirstName(firstName.getText().toString());

                     EditText lastName = (EditText) findViewById(R.id.et_lastName);
                    user.setLastName(lastName.getText().toString());

                     EditText email = (EditText) findViewById(R.id.et_email);
                    user.setEmail(email.getText().toString());
                    Log.d("email: ", user.getEmail().toString());

                    if (android.os.Build.VERSION.SDK_INT>14) {
                        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
                                .permitAll().build();
                        StrictMode.setThreadPolicy(policy);
                    }

                    UserService userService = new UserService();
                    String path = userService.createNewUser(user);




                    Log.d("Location: ", path);
                    Toast.makeText(getApplicationContext(), 
                            path, Toast.LENGTH_LONG).show();

                    String userID = path.replace("/user/", "");
                    userID = userID.replace("/users/", "");
                    Log.d("UserID:::", userID);
                    Log.d("User Service", "register in Background started");
                    if(checkPlayServices()){
                    registerGCMInBackground(userID);
                    }

                    }
                    else{
                        Toast.makeText(getApplicationContext(), 
                                "Please enter your Mobile Phone Number", Toast.LENGTH_LONG).show();
                    }           
                }
            });

    private void registerGCMInBackground(final String userId) {
        new AsyncTask<Void, Void, String>() {
            @Override
            protected String doInBackground(Void... params) {
                String msg = "";
                Log.d("Register GCM", "started");
                try {
                    if (gcm == null) {
                        gcm = GoogleCloudMessaging.getInstance(context);
                        Log.d("GCM", gcm.toString());
                    }



                    regid = gcm.register(SENDER_ID); //////NULL POINTER EXCEPTION
                    msg = "Device registered, registration ID=" + regid;



                    // You should send the registration ID to your server over HTTP
                    sendRegistrationIdToBackend(userId, regid);

                    // For this demo: we don't need to send it because the device will send
                    // upstream messages to a server that echo back the message using the
                    // 'from' address in the message.

                    // Persist the regID - no need to register again.
                    storeRegistrationId(context, regid);
                } catch (IOException ex) {
                    return "Error :" + ex.getMessage();
                    // If there is an error, don't just keep trying to register.
                    // Require the user to click a button again, or perform
                    // exponential back-off.
                }
                return regid;
            }

            @Override
            protected void onPostExecute(String msg) {

            }
        }.execute(null, null, null);
    }

这是我的控制台输出: 控制台输出

我已经花了两天时间来处理这个问题。:(非常感谢!


同样的问题...这个问题解决了吗? - thedjaney
问题已经解决。请查看更新。 - FullPatrickJoin
6
如果你找到了你问题的答案,建议你把它作为一个回答发布,而不是添加到问题中。我看到你这样做了,并在某人的评论后删除了答案。那个评论是错误的。人们经常在SO上回答自己的问题,这完全没有问题。甚至标记自己的答案为已接受也是可以的(因为它解决了你的问题)。 - Eran
@Eran 谢谢你的启示。 - FullPatrickJoin
这非常有用。我之前一直依赖于捕获(gcm.register)行上的异常,然后等待意图,但现在我直接得到了正确的id。 - Carlos
显示剩余2条评论
2个回答

2

据说从2015年5月28日开始,使用gcm.register()获取注册令牌已被弃用。新的应用程序开发应使用Instance ID API来处理注册令牌的创建,旋转和更新。有关更多信息,请参阅“注册客户端应用程序”和“在Android上设置GCM客户端应用程序”。

来自Google:https://developers.google.com/cloud-messaging/android/legacy-regid


1
我解决了这个问题。 问题在于registerGCMInBackground()方法。 GoogleCloudMessaging.getInstance()需要ApplicationContext作为参数。
    private void registerGCMInBackground(final String userId) {
    new AsyncTask<Void, Void, String>() {
        @Override
        protected String doInBackground(Void... params) {
            String msg = "";
            Log.d("Register GCM", "started");
            try {
                if (gcm == null) {
                    //PROBLEM SOLVED HERE
                    gcm = GoogleCloudMessaging.getInstance(getApplicationContext());
                    Log.d("GCM", gcm.toString());
                }



                regid = gcm.register(SENDER_ID); //////NULL POINTER EXCEPTION
                msg = "Device registered, registration ID=" + regid;



                // You should send the registration ID to your server over HTTP
                sendRegistrationIdToBackend(userId, regid);

                // For this demo: we don't need to send it because the device will send
                // upstream messages to a server that echo back the message using the
                // 'from' address in the message.

                // Persist the regID - no need to register again.
                storeRegistrationId(context, regid);
            } catch (IOException ex) {
                return "Error :" + ex.getMessage();
                // If there is an error, don't just keep trying to register.
                // Require the user to click a button again, or perform
                // exponential back-off.
            }
            return regid;
        }

这很奇怪。我有同样的问题,将其更改为getApplicationContext()并不能解决问题。该应用在Lollipop上运行良好。 - bashan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接