关闭应用程序时,Android 不会收到来自 Parse Push 的推送通知

Posted

技术标签:

【中文标题】关闭应用程序时,Android 不会收到来自 Parse Push 的推送通知【英文标题】:Android doesn't receive push notification from Parse Push when app is closed 【发布时间】:2015-03-03 18:08:50 【问题描述】:

当我在我的 android 手机上测试 Parse Push 时,只要应用程序运行,推送通知就会出现。 如果应用程序关闭:我只收到一条消息说<App name> has stopped. - 我没有收到任何推送 - 但仍然收到停止通知弹出窗口。我已逐步遵循 Parse 中的快速入门指南。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.ostsia.ostsia">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <!--
      IMPORTANT: Change "com.parse.starter.permission.C2D_MESSAGE" in the lines below
      to match your app's package name + ".permission.C2D_MESSAGE".
    -->
    <permission android:protectionLevel="signature"
        android:name="org.ostsia.ostsia.permission.C2D_MESSAGE" />
    <uses-permission android:name="org.ostsia.ostsia.permission.C2D_MESSAGE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ostsia"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="org.ostsia.ostsia.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name="com.parse.PushService"/>
        <receiver android:name="com.parse.ParseBroadcastReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.USER_PRESENT" />
            </intent-filter>
        </receiver>
        <receiver android:name="com.parse.ParsePushBroadcastReceiver"
            android:exported="false">

            <intent-filter>
                <action android:name="com.parse.push.intent.RECEIVE" />
                <action android:name="com.parse.push.intent.DELETE" />
                <action android:name="com.parse.push.intent.OPEN" />
            </intent-filter>
        </receiver>
        <receiver android:name="com.parse.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" />

                <!--
                  IMPORTANT: Change "com.parse.starter" to match your app's package name.
                -->
                <category android:name="org.ostsia.ostsia" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

03-03 21:27:10.829  31149-31149/org.ostsia.ostsia E/com.parse.PushService﹕ The Parse push service cannot start because Parse.initialize has not yet been called. If you call Parse.initialize from an Activity's onCreate, that call should instead be in the Application.onCreate. Be sure your Application class is registered in your AndroidManifest.xml with the android:name property of your <application> tag.
03-03 21:27:10.829  31149-31149/org.ostsia.ostsia D/AndroidRuntime﹕ Shutting down VM
03-03 21:27:10.839  31149-31149/org.ostsia.ostsia E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: org.ostsia.ostsia, PID: 31149
    java.lang.RuntimeException: Unable to start service com.parse.PushService@4d17bf6 with Intent  act=com.google.android.c2dm.intent.RECEIVE flg=0x10 pkg=org.ostsia.ostsia cmp=org.ostsia.ostsia/com.parse.PushService (has extras) : java.lang.RuntimeException: applicationContext is null. You must call Parse.initialize(context, applicationId, clientKey) before using the Parse library.
            at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3278)
            at android.app.ActivityThread.access$2200(ActivityThread.java:172)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1520)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:145)
            at android.app.ActivityThread.main(ActivityThread.java:5834)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
     Caused by: java.lang.RuntimeException: applicationContext is null. You must call Parse.initialize(context, applicationId, clientKey) before using the Parse library.
            at com.parse.Parse.checkContext(Parse.java:451)
            at com.parse.Parse.getApplicationContext(Parse.java:219)
            at com.parse.ManifestInfo.getContext(ManifestInfo.java:322)
            at com.parse.ManifestInfo.getPackageName(ManifestInfo.java:326)
            at com.parse.ManifestInfo.getIntentReceivers(ManifestInfo.java:131)
            at com.parse.ManifestInfo.hasIntentReceiver(ManifestInfo.java:123)
            at com.parse.ManifestInfo.getPushUsesBroadcastReceivers(ManifestInfo.java:174)
            at com.parse.PushService.wipeRoutingAndUpgradePushStateIfNeeded(PushService.java:454)
            at com.parse.PushService.onStartCommand(PushService.java:435)
            at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3261)
            at android.app.ActivityThread.access$2200(ActivityThread.java:172)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1520)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:145)
            at android.app.ActivityThread.main(ActivityThread.java:5834)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
03-03 21:27:12.599  31149-31149/org.ostsia.ostsia I/Process﹕ Sending signal. PID: 31149 SIG: 9

【问题讨论】:

接收器中可能存在一些错误,因此当您收到通知时应用程序崩溃。尝试获取一些日志 是的,请查看更新后的帖子。 你检查了吗? applicationContext is null. You must call Parse.initialize(context, applicationId, clientKey) before using the Parse library. 这就是我的文件现在的样子; public class MainActivity extends Activity /** 首次创建活动时调用。 */ WebView 网页; @Override public void onCreate(Bundle savedInstanceState) Parse.initialize(this, "XXXX", "XXXX");该行是否应该在“ WebView web;”之下/之上? 你绝对不应该在 MainActivity 中初始化解析,在 applicaton 类中进行 【参考方案1】:

在 Application 类中初始化解析,如下所示

public class AppClass extends Application 
    @Override
    public void onCreate() 
        super.onCreate();

        // Parse.enableLocalDatastore(this); // if you need this, put before init
        Parse.initialize(this, "gV6QK", "JJmFo99");
        PushService.setDefaultPushCallback(getApplicationContext(), MainActivity.class);
        ParseInstallation.getCurrentInstallation().saveInBackground();
    

不要忘记在清单中引用您的应用类

<application android:name=".AppClass">

从 MainActivity 中移除 Parse init

【讨论】:

Appclass.java: pastebin.com/idBNwkhx MainActicity: pastebin.com/RMmKW1Hj AndroidManifest.xml: pastebin.com/mNYrtKzH 当我尝试在 Appclass.java 中编译时遇到一些错误。 四:错误:(15, 8) 错误:需要类、接口或枚举 二:错误:(22, 87) 错误:预期 一:错误:(23, 51)错误: ';'预期一:错误:(27, 1) 错误:预期的类、接口或枚举所有这些错误都来自您在上面为 Appclass 提供的代码 您是否复制粘贴代码而没有进一步更改?当然你必须添加包声明和导入。 第一行的包声明? 是的,我完全忘记了。现在它唯一的 Error:(16, 12) error: class, interface, or enum expected and Error:(21, 87) error: expected from the last implementation.【参考方案2】:

抱歉 - 我不知道使用正确的函数来实现堆栈代码 - 如果您有更好的方法,请说出来。

我仍然得到“在使用 Parse 库之前,您必须调用 Parse.initialize(context, applicationId, clientKey)。”错误。现在,即使应用程序打开,我也无法接收通知。我已将 Parse Push 拆分为另一个类。下面是我的源代码。

主活动

package org.ostsia.ostsia;

import android.app.Activity;
import android.app.Application;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.content.Intent;
import android.net.Uri;


/*
 * Demo of creating an application to open any URL inside the application and clicking on any link from that URl
should not open Native browser but  that URL should open in the same screen.
 */

public class MainActivity extends Activity 
    /** Called when the activity is first created. */


    WebView web;


    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        web = (WebView) findViewById(R.id.webview01);
        web.setWebViewClient(new myWebClient());
        web.getSettings().setjavascriptEnabled(true);
        web.loadUrl("http://tconsulting.no/ostsia");
    



    public class myWebClient extends WebViewClient
    
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) 
            // TODO Auto-generated method stub
            super.onPageStarted(view, url, favicon);
        

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) 
            if( url.startsWith("http:") || url.startsWith("https:") ) 
                return false;
            

            // Otherwise allow the OS to handle it
            else if (url.startsWith("tel:")) 
                Intent tel = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
                startActivity(tel);
                return true;
            
            else if (url.startsWith("mailto:")) 
                String body = "Enter your Question, Enquiry or Feedback below:\n\n";
                Intent mail = new Intent(Intent.ACTION_SEND);
                mail.setType("application/octet-stream");
                mail.putExtra(Intent.EXTRA_EMAIL, new String[]"email address");
                mail.putExtra(Intent.EXTRA_SUBJECT, "Subject");
                mail.putExtra(Intent.EXTRA_TEXT, body);
                startActivity(mail);
                return true;
            
            return true;
        
    

    // To handle "Back" key press event for WebView to go back to previous screen.
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    
        if ((keyCode == KeyEvent.KEYCODE_BACK) && web.canGoBack()) 
            web.goBack();
            return true;
        
        return super.onKeyDown(keyCode, event);
    

应用类

package org.ostsia.ostsia;


import android.app.Application;


import org.ostsia.ostsia.MainActivity;
import com.parse.Parse;
import com.parse.ParseInstallation;
import com.parse.ParsePush;

public class AppClass extends Application 
    @Override
    public void onCreate() 
        super.onCreate();

        Parse.initialize(this, "XXX", "XX");
        // Parse.setDefaultPushCallback(getApplicationContext(), MainActivity.java);
        ParseInstallation.getCurrentInstallation().saveInBackground();
    

清单文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.ostsia.ostsia">
    <application android:name=".AppClass"/>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <!--
      IMPORTANT: Change "com.parse.starter.permission.C2D_MESSAGE" in the lines below
      to match your app's package name + ".permission.C2D_MESSAGE".
    -->
    <permission android:protectionLevel="signature"
        android:name="org.ostsia.ostsia.permission.C2D_MESSAGE" />
    <uses-permission android:name="org.ostsia.ostsia.permission.C2D_MESSAGE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ostsia"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="org.ostsia.ostsia.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name="com.parse.PushService"/>
        <receiver android:name="com.parse.ParseBroadcastReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.USER_PRESENT" />
            </intent-filter>
        </receiver>
        <receiver android:name="com.parse.ParsePushBroadcastReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="com.parse.push.intent.RECEIVE" />
                <action android:name="com.parse.push.intent.DELETE" />
                <action android:name="com.parse.push.intent.OPEN" />
            </intent-filter>
        </receiver>
        <receiver android:name="com.parse.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" />

                <!--
                  IMPORTANT: Change "com.parse.starter" to match your app's package name.
                -->
                <category android:name="org.ostsia.ostsia" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

【讨论】:

以上是关于关闭应用程序时,Android 不会收到来自 Parse Push 的推送通知的主要内容,如果未能解决你的问题,请参考以下文章

应用关闭或被杀时未收到 Android FCM 通知

即使App已关闭,也会收到Android推送通知

如果应用程序已经打开,则来自 expo-branch 的 Branch.subscribe 不会收到数据

MainActivity 中的 Android 类没有收到来自警报管理器的广播

在 asmack 中没有收到大量离线消息 [关闭]

Android - GCM 在打开应用程序时收到来自 gcm 的通知