2013-03-13 22 views
8

W mojej aplikacji używam DownloadManager, do pobierania plików PDF, który powiadamia aplikację przez BroadcastReceiver po zakończeniu pobierania. Mój problem polega na tym, że metoda onReceive() programu BroadcastReceiver jest wywoływana dwa razy. Kod jest następujący:BroadcastReceiver onReceive() jest wywoływany dwa razy

W adapterze z mojej listy uruchamiana jest pętla for do pobrania wybranych plików pdf. Kod pobierania jest zapisany w innej klasie w następujący sposób:

public static void downloadCheat(final SherlockFragmentActivity activity, final String cheatName, String pathOnServer){ 

    Request request = new Request(
      Uri.parse(ApplicationConstants.CHEAT_DOWNLOAD_SERVER_URL 
        + "/" + pathOnServer + cheatName + ".pdf")); 

    if(Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) { 
     request.setShowRunningNotification(true); 
    } 
    else { 
     request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); 
    } 

    final DownloadManager dm = (DownloadManager) activity 
      .getSystemService(Context.DOWNLOAD_SERVICE); 
    final long enqueue = dm.enqueue(request); 

    BroadcastReceiver receiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      String action = intent.getAction(); 
      long i = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); 
      System.out.println(i); 
      if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) { 
       Query query = new Query(); 
       query.setFilterById(enqueue); 
       Cursor c = dm.query(query); 

       if (c.moveToFirst()) { 
        int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS); 
        if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) { 
        } 
       } 
            //create custom notification 
      } 
     } 
    }; 

    activity.registerReceiver(receiver, new IntentFilter(
      DownloadManager.ACTION_DOWNLOAD_COMPLETE)); 
} 

Próbuję dodać powiadomienia do każdego pobrania pdf. Działa to doskonale z wewnętrznymi powiadomieniami menedżerów pobierania dla HoneyComb i wyżej wymienionych wersji, ale dla GingerBread to nie działa i dlatego muszę przesłać własne niestandardowe powiadomienie. Muszę więc określić dokładny czas, kiedy plik PDF zostanie pobrany całkowicie. Obecnie mogę przesłać własne niestandardowe powiadomienie, ale powiadomienia przychodzą dwa razy za każde pobranie pdf (ponieważ onReceive() dostaje dwa razy za każdy plik pdf). Czy ktoś może wyjaśnić, dlaczego funkcja onReceive() jest wywoływana dwukrotnie (dla każdego pliku pdf). Czy istnieje jakieś obejście tego problemu? Czy ktoś mógłby polecić, w jaki sposób odbiornik może być niezarejestrowany w moim przypadku tutaj? Powyższy kod nie jest częścią działania, więc nie jestem pewien jak wyrejestrować odbiornik.

Dzięki za zatrzymanie się i przeczytanie postu.

+1

jest pobieranie id taką samą wartość w tym, że dwa onReceive() wywołuje? downloadid można pobrać przez intent.getLongExtra (DownloadManager.EXTRA_DOWNLOAD_ID, -1) – StarPinkER

+0

Sprawdziłem. Kiedy pobieram dwa pliki pdf, identyfikator pobierania jest taki sam dla obu plików pdf po raz pierwszy, gdy wywoływany jest onReceive (first.pdf -> id = 1, second.pdf -> Id = 1). Kiedy jest automatycznie wywoływana po raz drugi, zmienia się identyfikator pobierania (first.pdf -> Id = 2, second.pdf -> id = 2). Zasadniczo dostaję cztery wydruki, które drukują 1,1,2,2. czy identyfikator powinien być unikalny dla każdego pobrania pdf? – andro

+0

Jestem zdezorientowany twoim pierwszym.pdf-> id = 1 i second.pdf-> id = 1. Czy możesz zaktualizować swój kod, aby lepiej zrozumieć, co jest twoje pierwsze i drugie? – StarPinkER

Odpowiedz

3

Zwykle rejestrujesz odbiorców onResume() i wyrejestrujesz w onPause(). Czy robisz tak?


Myślę, że mogłem początkowo źle zrozumieć to, co próbujesz zrobić. Powinieneś być w stanie zadzwonić pod numer unregisterReceiver z onReceive. Czy to robi to, co chcesz?

+0

Nie rejestruję odbiornika w onResume(). BroadcastReceiver jest tworzony dla każdego pliku do pobrania.Jak wspomniałem wcześniej, kod znajduje się w oddzielnej klasie, a nie w części klasy Activity. – andro

+0

Rozumiem. Zaktualizowałem swoją odpowiedź. Co się stanie, jeśli wyrejestrujesz odbiornik z onReceive? – yarian

+0

Jeśli spróbuję wyrejestrować odbiornik w trybie onReceive(), aplikacja ulega awarii, mówiąc "Odbiornik niezarejestrowany". Zobacz moje zaktualizowane pytanie, aby uzyskać bardziej szczegółowy pomysł na temat tego, co próbuję osiągnąć. Dziękuję za Twój czas. – andro

1

Powiedziałeś, że pobierasz dwa pliki pdf. Widzę tylko jedno żądanie pobierania w twojej metodzie. Zakładam więc, że to, co zrobiłeś, to dwukrotne wywołanie tej metody. Jeśli to prawda, zarejestrowałeś dwa odbiorniki, aby odebrać zdarzenie ACTION_DOWNLOAD_COMPLETE.

Należy zarejestrować tylko raz wCreate lub onStart lub inne metody. W celu powiadomienia można użyć numeru intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1), aby uzyskać identyfikator pobierania, identyfikator jest unikalny dla każdego pobrania. Możesz użyć tego identyfikatora, aby uzyskać informacje o pobranym pliku i dokonać powiadomienia specyficznego dla pliku.

+0

Tak, nazwałem tę metodę dwukrotnie (raz na każdy plik do pobrania). Powodem, dla którego to zrobiłem, jest utworzenie osobnego powiadomienia dla każdego pliku pdf. Czy istnieje sposób, w jaki mogę to osiągnąć, używając tylko jednego odbiornika? – andro

+0

Odpowiedź zaktualizowana. @andro – StarPinkER