2015-02-08 17 views
6

Trước khi ghi nhãn này là trùng lặp:đẩy không nhận được sau khi ứng dụng được đóng

Tôi đã đọc ít nhất 15 chủ đề tương tự và mỗi người là một trong hai sử dụng mã Parse cũ (các setDefaultPushCallback bây giờ bị phản) hoặc vấn đề là kết quả của việc gọi Parse.initialize (...) trong một hoạt động chứ không phải trong lớp Ứng dụng. Nhưng đây là không phải áp dụng cho trường hợp của tôi. Ví dụ chính thức (mà tôi đang sử dụng) rõ ràng là làm đúng, vì vậy mã đã có trong lớp Ứng dụng.

Tôi đã tải xuống Push Starter example from Parse's official guides và dùng thử trên trình giả lập. Tôi chỉ nhận được push trong khi ứng dụng đang chạy. Khoảnh khắc của nó bị đóng (bị xóa khỏi danh sách "ứng dụng gần đây", không phải là bị giết), tôi không còn bị đẩy nữa. Mà làm cho toàn bộ tính năng khá vô ích ... Tôi đã thử và không có GCM, hành vi là như nhau.

Bất kỳ manh mối nào có thể sai? Tất cả các lớp là những ví dụ cổ phiếu, không có gì ghi đè hoặc thêm bởi tôi (ngoại trừ id/key và ParsePush.subscribeInBackground cuộc gọi mà tôi đã sao chép từ hướng dẫn). Thật kỳ lạ, mã ví dụ không chứa ParsePush.subscribeInBackground và QuickStart không đề cập đến nó. Nó thậm chí còn cung cấp cho một nút Test được cho là gửi một push mà tôi không bao giờ nhận được, có hoặc không có subscribeInBackground. Cách duy nhất tôi đã có thể có được một đẩy cho đến nay là với subscribeInBackground và gửi một cách thủ công mặc dù giao diện điều khiển web, và chỉ vì vậy nếu ứng dụng đang chạy. Bảng điều khiển web cũng cho biết có 2 thiết bị đã đăng ký ... không đúng sự thật.

Manifest:

<?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> 

ParseApplication:

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

Xin chào Kaqqao, nhận thông báo đẩy qua "Cách phân tích cú pháp" sẽ ngừng hoạt động bất cứ khi nào bạn từ chối ứng dụng của mình từ lần gần đây nhất. Điều này là do việc giết chết ứng dụng của bạn sẽ phá vỡ kết nối với các máy chủ phụ trợ Parse và do đó các máy chủ không thể đẩy bất cứ điều gì nữa. Thông báo đẩy qua GCM sẽ hoạt động tuy nhiên, ngay cả khi ứng dụng của bạn bị giết (không bị buộc phải dừng). Điều này là do GCM hoạt động thông qua Dịch vụ của Google Play, một ứng dụng luôn chạy trong nền và có thể khởi động ứng dụng của bạn khi cần thiết (và không dừng lại). Mã của bạn cũng có vẻ chính xác, vì vậy tôi không thực sự thấy vấn đề. –

+0

Tôi tự hỏi nếu có xung đột tên gói (vì bạn sử dụng cùng một gói như ví dụ), theo cách đó có nhiều ứng dụng có cùng gói, nhưng có chữ ký khác. Bạn có thể thử thay đổi gói của mình thành thứ gì đó độc đáo không? 'com.parse.kaqqao' –

+0

@jmols OMG, có vẻ như lý thuyết tên gói của bạn là chính xác! Sau khi tôi đổi tên, tôi bắt đầu nhận tin nhắn với ứng dụng đã đóng. Không có lý do tại sao nó làm việc với các ứng dụng đang chạy, mặc dù ... Dù sao, bạn xin vui lòng chuyển đổi hai ý kiến ​​của bạn thành một câu trả lời để tôi có thể trao cho bạn tiền thưởng trước khi nó hết hạn? – kaqqao

Trả lời

1

Chỉ cần làm rõ lý do tại sao bạn đang nhìn thấy hành vi này, Parse có hai cách khác nhau để cung cấp các thông báo đẩy:

  1. "Pa rse way ": Parse SDK có một thành phần đang chạy trong ứng dụng của bạn, giúp giữ kết nối với các máy chủ phụ trợ Parse. Điều này sẽ chỉ hoạt động khi ứng dụng của bạn thực sự đang chạy, vì việc giết nó sẽ phá vỡ kết nối với phần phụ trợ Parse.
  2. Thông báo đẩy GCM "Google": Tính năng này hoạt động qua Dịch vụ của Google Play, một ứng dụng luôn chạy trong nền và có thể khởi động ứng dụng của bạn khi cần. Điều này sẽ luôn hoạt động, trừ khi bạn buộc dừng ứng dụng.

Trong trường hợp của bạn, bạn có xung đột tên gói: com.parse.starter là tên gói thực sự được đưa vào ví dụ. Điều này khiến GCM không hoạt động, bởi vì nó đã biết gói dưới một chữ ký khác. Thay đổi tên gói của bạn thành một cái gì đó độc đáo như com.parse.kaqqao sẽ giải quyết vấn đề.

1

Có một vài lý do cho việc này:

  1. Có hai BroadcastReceiver tức các "com.parse.ParsePushBroadcastReceiver" và "com.parse.GcmBroadcastReceiver". Tôi tin rằng người nhận đầu tiên đang được ưu tiên hơn GCMBroadcastReceiver và do đó hành vi không bị ảnh hưởng bởi việc loại bỏ hoặc giữ máy thu này. Nó cũng có thể là do hành động "com.parse.push.intent.RECEIVE", có thể xử lý các tin nhắn push RECEIVE action.Nếu cả hai người nhận thực hiện cùng một nhiệm vụ phân tích cú pháp tin nhắn Push (bắt đầu cùng một dịch vụ trong nền), sau đó bao gồm bộ lọc ý định bên trong một bộ thu và cho phép nó xử lý tất cả các loại tin nhắn push. Vì GCMBroadcastReceiver giữ quyền C2DM.

  2. Thử thay đổi thứ tự của hai thẻ người nhận phát sóng trong tệp kê khai. (Giữ GCMBroadcastReceiver trước khi ParsePushBroadcastReceiver)

  3. Có thể là do android: exports = "false", có thể nó ngăn người nhận nghe tin nhắn push được gửi bởi máy chủ. Hãy thử thay đổi thành sự thật.

Các vấn đề liên quan