Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.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
Java 应用程序关闭后未收到推送_Java_Android_Parse Platform_Push Notification - Fatal编程技术网

Java 应用程序关闭后未收到推送

Java 应用程序关闭后未收到推送,java,android,parse-platform,push-notification,Java,Android,Parse Platform,Push Notification,在将其标记为副本之前: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.parse.starter" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:

在将其标记为副本之前:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.parse.starter"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="21"/>

    <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="com.parse.starter.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.parse.starter.permission.C2D_MESSAGE" />

    <application
        android:name=".ParseApplication"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:allowBackup="true">
        <activity
            android:name=".ParseStarterProjectActivity"
            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="com.parse.starter" />
            </intent-filter>
        </receiver>
    </application>

</manifest>
package com.parse.starter;
...

public class ParseApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // Initialize Crash Reporting.
        ParseCrashReporting.enable(this);

        // Enable Local Datastore.
        Parse.enableLocalDatastore(this);

        ParseUser.enableAutomaticUser();

        // Add your initialization code here
        Parse.initialize(this, "***", "***");

        ParseACL defaultACL = new ParseACL();
        // Optionally enable public read access.
        // defaultACL.setPublicReadAccess(true);
        ParseACL.setDefaultACL(defaultACL, true);

        ParsePush.subscribeInBackground("", new SaveCallback() {
            @Override
            public void done(ParseException e) {
                if (e == null) {
                    Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
                } else {
                    Log.e("com.parse.push", "failed to subscribe for push", e);
                }
            }
        });
    }
}
我读过至少15个类似的线程,每个线程都在使用旧的解析代码(现在已弃用的setDefaultPushCallback),或者问题是在活动中而不是在应用程序类中调用Parse.initialize(…)的结果。但这不适用于我的情况。官方示例(我正在使用)显然做得不错,因此代码已经在应用程序类中

我已经下载了,并在模拟器上进行了测试。我只在应用程序运行时接收推送。当它关闭的那一刻(从“最近的应用”列表中删除,而不是强制删除),我就不再得到推送。这使得整个功能相当无用。。。我试过使用和不使用GCM,行为是一样的

有什么线索可能是错的吗?所有类都是股票示例类,我没有覆盖或添加任何类(除了id/key和我从指南中复制的ParsePush.subscribeInBackground调用)。奇怪的是,示例代码不包含ParsePush.subscribeInBackground,并且没有提到它。它甚至给出了一个测试按钮,据说它会发送一个我从未收到过的按钮,无论有没有订阅背景。到目前为止,我能够获得推送的唯一方法是使用subscribeInBackground并通过web控制台手动发送推送,并且只有在应用程序正在运行时才能这样做。网络控制台还不断告诉我们有两个注册设备。。。这是不真实的

清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.parse.starter"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="21"/>

    <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="com.parse.starter.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.parse.starter.permission.C2D_MESSAGE" />

    <application
        android:name=".ParseApplication"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:allowBackup="true">
        <activity
            android:name=".ParseStarterProjectActivity"
            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="com.parse.starter" />
            </intent-filter>
        </receiver>
    </application>

</manifest>
package com.parse.starter;
...

public class ParseApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        // Initialize Crash Reporting.
        ParseCrashReporting.enable(this);

        // Enable Local Datastore.
        Parse.enableLocalDatastore(this);

        ParseUser.enableAutomaticUser();

        // Add your initialization code here
        Parse.initialize(this, "***", "***");

        ParseACL defaultACL = new ParseACL();
        // Optionally enable public read access.
        // defaultACL.setPublicReadAccess(true);
        ParseACL.setDefaultACL(defaultACL, true);

        ParsePush.subscribeInBackground("", new SaveCallback() {
            @Override
            public void done(ParseException e) {
                if (e == null) {
                    Log.d("com.parse.push", "successfully subscribed to the broadcast channel.");
                } else {
                    Log.e("com.parse.push", "failed to subscribe for push", e);
                }
            }
        });
    }
}

为了澄清为什么会出现这种行为,Parse提供了两种不同的推送通知方式:

  • “Parse way”:Parse SDK在您的应用程序中运行一个组件,该组件保持与Parse后端服务器的连接。这只会在应用程序实际运行时起作用,因为杀死它会中断与解析后端的连接
  • GCM“Google”推送通知:通过Google Play Services工作,该应用程序始终在后台运行,需要时可以启动应用程序。除非强制停止应用程序,否则这将始终有效

  • 在您的示例中,存在包名冲突:
    com.parse.starter
    是示例中实际包含的包名。这导致GCM无法工作,因为它已经知道不同签名下的包。将包名更改为独特的名称,如
    com.parse.kaqqao
    ,应该可以解决问题。

    原因如下:

  • 有两个BroadcastReceiver,即“com.parse.ParsePushBroadcastReceiver”和“com.parse.GcmBroadcastReceiver”。我相信第一个接收者的优先级高于GCMBroadcastReceiver,因此移除或保留此接收者不会影响行为。这也可能是由于操作“com.parse.push.intent.RECEIVE”,该操作可能正在处理推送消息接收操作。如果两个接收器都执行相同的推送消息解析任务(在后台启动相同的服务),那么在一个接收器中包含意图过滤器,并让它处理所有类型的推送消息。因为GCMBroadcastReceiver拥有C2DM权限

  • 尝试更改清单中两个广播接收器标记的顺序。(将GCMBroadcastReceiver置于接收器之前)

  • 这可能是由于android:exported=“false”,可能是因为它阻止了接收者监听服务器发送的推送消息。尝试更改为true


  • 嗨,Kaqqao,当你最近关闭应用程序时,通过“解析方式”获取推送通知将停止工作。这是因为杀死你的应用程序会中断与解析后端服务器的连接,因此服务器无法再推送任何东西。但是,即使您的应用程序被终止(而不是强制停止),通过GCM的推送通知也应该有效。这是因为GCM通过Google Play Services工作,这是一款始终在后台运行的应用程序,可以在需要时启动你的应用程序(而不是强制停止)。你的代码看起来也是正确的,所以我没有真正看到问题所在。我想知道是否存在包名冲突(因为你使用的是与示例相同的包),即有多个应用程序使用相同的包,但签名不同。你能试着把你的包裹换成独一无二的吗
    com.parse.kaqqao
    @jmols-OMG,看来你的包名理论是正确的!更改名称后,我开始在应用程序关闭时接收消息。不知道为什么它能在应用程序运行时工作,不过。。。不管怎样,请你把你的两个评论转换成一个答案,这样我就可以在赏金到期之前奖励你了?太好了!很高兴听到!我已经把帖子转换成了答案。