2015-01-15 2 views
2

그래서이 문제가 있습니다. 일종의 GCM 알림 파서 인 종속성 프로젝트를 사용하고 있습니다. 그것은 약간 부실하게 쓰여지지만, 나는 일과 관련된 이유 때문에 그것을 사용하도록 강요 당한다. 어쨌든 :WakefulBroadcastReceiver의 IntentService에있는 BroadcastReceiver가 항상 작동하지 않는 경우

IntentService를 확장하는 기본 서비스가 WakefulBroadcastReceiver와 함께 시작됩니다. GCM에서 메시지를받은 후 일부 마법을 사용하여 브로드 캐스트를 사용하여 기본 앱으로 전송합니다. 주 앱에서 나는 메시지를 잡아 데이터베이스의 모든 것을 저장하는 다른 BroadcastReceiver와 지속적으로 서비스를 실행하고 있습니다.

왜 그렇게 복잡한가요? 첫째, 원래는 다른 누군가의 프로젝트 였고 지금은 버그를 수정하려고합니다. 둘째 - 브로드 캐스트 메시지를 전달할 때 주 응용 프로그램 프로젝트에 대한 종속성에 대한 액세스 권한이 없습니다.

이제 재미있는 부분이 있습니다. 알림 표시 여부를 필터링해야합니다. 내 주 AppService에 메시지를 보내는 동안 이전 메시지의 기록을 확인한 다음이 메시지를 User에게 표시할지 여부를 결정합니다. 그러나 내 결정이 무엇이든 내 의존성은 여전히 ​​내 알림을 보여줍니다. 그래서 또 다른 브로드 캐스트를 추가했습니다. 유효성 검사가 성공적으로 끝나면 종속성 알림 빌드 방법에서 시작됩니다. 여기

코드입니다 :

내 WakefulBroadcastReceiver : 여기

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver { 
@Override 
public void onReceive(Context context, Intent intent) { 
    ComponentName comp = new ComponentName(context.getPackageName(), PushService.class.getName()); 
    startWakefulService(context, (intent.setComponent(comp))); 
    setResultCode(Activity.RESULT_OK); 
} 
} 

가 내 Depencency 서비스

 public NotificationCheckerReceiver notificationCheckerReceiver; 

     ... 

     @Override 
     protected void onHandleIntent(Intent intent) { 
      Bundle extras = intent.getExtras(); 
      GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this); 
      String messageType = gcm.getMessageType(intent); 

      if (!extras.isEmpty()) { 

       if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) { 

        //Launch my "approval" receiving broadcast 
        launchBroadcastReceiver(extras, intent); 

        //send broadcast to main app with the message we will parse etc. 
        sendSmsBroadcast(...)); 


       } 
      } 

     } 


     @Override 
     public void onDestroy() { 
      unregisterReceiver(notificationCheckerReceiver); 
      super.onDestroy(); 
     } 

     //Launch to build notification 
     public void showNotification(Bundle extras){ 
      ... 
      //Basic notification builder 
     } 

     //Receive broadcast from DB if notification was already in the DB 
     private void launchBroadcastReceiver(Bundle extras, Intent intent){ 
      Log.d(TAG, "Broadcast receiver loaded"); 

      notificationCheckerReceiver = new NotificationCheckerReceiver(new NotiFlag() { 
       @Override 
       public void onReceiveApproval(Boolean flag, Intent intent, Bundle extras) { 
        Log.d(TAG, "Approved notification show"); 
        showNotification(extras); 
        JustPushGcmBroadcastReceiver.completeWakefulIntent(intent); 
       } 
      }, intent, extras); 

      registerReceiver(notificationCheckerReceiver, new IntentFilter(notificationCheckerReceiver.INTENT_EVENT_NAME)); 
     } 

     public void sendSmsBroadcast(String message, boolean isAppOnScreen){ 
      ... 
      //This works 
     } 

    } 

내 "결함"수신기 : 공용 클래스 NotificationCheckerReceiver가 {

브로드 캐스트 리시버를 확장
private final String TAG = getClass().getSimpleName(); 

    public static final String INTENT_EVENT_NAME = "NOTIFLAG"; 
    public static final String INTENT_FLAG_KEY = "FLAG"; 

    Intent intent; 
    Bundle extras; 

    NotiFlag nofiFlag; 

    public NotificationCheckerReceiver(NotiFlag nofiFlag, Intent intent, Bundle extras){ 
     Log.d(TAG, "Launched constructor NotificationChecker"); 
     this.nofiFlag = nofiFlag; 
     this.intent = intent; 
     this.extras = extras; 

    } 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     Log.d(TAG, "Launched onReceive"); 
     Boolean bool = intent.getExtras().getBoolean(INTENT_FLAG_KEY); 
     Log.d(TAG, "___________Broadcast receiver got something and it is intent: "+bool); 

     if (bool != false) { 
      nofiFlag.onReceiveApproval(bool, this.intent, this.extras); 
     } 

    } 
} 

그리고 마지막으로는, 내가 내 주요 서비스에서 전송하고있어 :

public void sendNotificationCheckerBroadcast(Boolean message){ 
     Intent flag = new Intent(NotificationCheckerReceiver.INTENT_EVENT_NAME); 
     flag.putExtra(NotificationCheckerReceiver.INTENT_FLAG_KEY, message); 
     DvLogs.d(TAG, "__________Sending intent: "+message); 
     sendBroadcast(flag); 
    } 

무슨 일입니다 내가 시작 지점 eveything "sendNotificationCheckerBroadcast을()". 나는 내가 어떤 종류의 부울을 보냈다는 사실을 알게되었다.

재미있는 부분은 : 때때로 작동합니다. 왜 그런지는 모르겠지만 어떤 이유로 그것이 시작될 때 - 모든 것이 훌륭합니다.

편집 :

01-15 11:20:22.204 3234-3234/pl.digitalvirgo.lafarge E/ActivityThread﹕ Service com.example.name.PushService has leaked IntentReceiver [email protected] that was originally registered here. Are you missing a call to unregisterReceiver()? 
     android.app.IntentReceiverLeaked: Service com.example.name.PushService has leaked IntentReceiver [email protected] that was originally registered here. Are you missing a call to unregisterReceiver()? 
       at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:814) 
       at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:610) 
       at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1772) 
       at android.app.ContextImpl.registerReceiver(ContextImpl.java:1752) 
       at android.app.ContextImpl.registerReceiver(ContextImpl.java:1746) 
       at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:479) 
       at com.example.name.PushService.launchBroadcastReceiver(Unknown Source) 
       at com.example.name.PushService.onHandleIntent(Unknown Source) 
       at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65) 
       at android.os.Handler.dispatchMessage(Handler.java:102) 
       at android.os.Looper.loop(Looper.java:157) 
       at android.os.HandlerThread.run(HandlerThread.java:61) 

아마 어떻게 든 관련이 : 그것이 작동 할 때 때때로 않기 때문에 , 나는이 오류가? 어딘가에서이 수신기를 등록 해제해야한다는 것을 알고 있습니다. onStop을 시도했지만, 우리가 볼 수있는 것처럼 성공하지 못했습니다.

편집 2 : 이상. 나는 문제가 onStop() 메소드에 있다고 믿는다. 아마도 너무 일찍 전화했는데 (?) 수신자가 일할 기회가 없었습니다. 등록하지 않고 앱을 실행하면 모든 것이 제대로 작동합니다. 물론 나는 위의 버그를 얻었지만 여전히 ... 그것은 뭔가입니다. 아이디어가 있으십니까?

답변

2

음. 문제는 IntentService의 아이디어 안에있었습니다.

intentService는 onHandleIntent() 메서드 이후에 자체적으로 종료됩니다. 그래서이 문제에 대한 해결책은 IntentService를 서비스 중지로 처리하는 것을 기억하는 것입니다.

관련 문제