17

Ho un BroadcastReceiver e ha dichiarato così:BroadcastReceiver per WALLPAPER_CHANGED chiama OnReceive() più volte: Android

<receiver 
    android:name="com.services.Receiver" 
    android:enabled="true" 
    android:exported="true" > 
    <intent-filter android:priority="999" > 
     <action android:name="android.intent.action.WALLPAPER_CHANGED" /> 
    </intent-filter> 
</receiver> 

e il ricevitore è:

@Override 
public void onReceive(final Context context, final Intent intent) 
{ 
    change_wallpepar.myPrefs = context.getSharedPreferences("myPrefs", Context.MODE_PRIVATE); 
    new Handler().postDelayed(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      Log.d("MAYUR", "<< wallpepar changed >>"); 
      if (change_wallpepar.myPrefs.getLong("temp_for_change", 1) == 0) 
      { 
       context.stopService(new Intent(context, change_wallpepar.class)); 
      } 
      else 
      { 
       SharedPreferences.Editor e = change_wallpepar.myPrefs.edit(); 
       e.putLong("temp_for_change", 0); 
       e.commit(); 
      } 
     } 
    }, 4000); 
} 

quando cambio la carta da parati qui dovrebbe essere chiamato una volta Funziona davvero secondo le mie aspettative per un po ', dopo alcuni minuti chiama il numero onreceive() multiplo (10-18) volte, anche se il cambio di sfondo viene eseguito una sola volta. Ancora più strano è che sta funzionando bene su un tablet Samsung Galaxy versione 4.4.2, ma non funziona su Motorola (Moto E 4.4.4).

Il mio servizio:

public class change_wallpepar extends Service { 

    @Override 
    public void onCreate() 
    { 
     // TODO Auto-generated method stub 
     super.onCreate(); 
     mytimer = new Timer(); 
     wpm = WallpaperManager.getInstance(change_wallpepar.this); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) 
    { 
     // TODO Auto-generated method stub 
     myPrefs = getSharedPreferences("myPrefs", MODE_PRIVATE); 
     intervall = myPrefs.getLong("someValue", 60000); 

     path_of_wallpepar.clear(); 
     path_of_wallpepar.add("" + "/storage/emulated/0/Android/data/WallpeparAppHistoryPhotos/514.jpg"); 
     path_of_wallpepar.add("" + "/storage/emulated/0/Android/data/WallpeparAppHistoryPhotos/513.jpg"); 

     DisplayImageOptions defaultOption = new DisplayImageOptions.Builder().cacheInMemory(true).cacheOnDisk(true).bitmapConfig(Bitmap.Config.RGB_565).build(); 
     ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(change_wallpepar.this).defaultDisplayImageOptions(defaultOption).build(); 
     ImageLoader.getInstance().init(config); 

     mytimer.schedule(new TimerTask() 
     { 
      @Override 
      public void run() 
      { 

       try 
       { 
        wpm.setBitmap(ImageLoader.getInstance().loadImageSync("file://" + path_of_wallpepar.get(temper))); 

       } 
       catch (IOException e) 
       { 
        e.printStackTrace(); 
       } 

       temper++; 

       if (temper == path_of_wallpepar.size()) 
        temper = 0; 

       SharedPreferences.Editor e = change_wallpepar.myPrefs.edit(); 
       e.putLong("temp_for_change", 1); 
       e.commit(); 

       Log.e("MAYUR", "wallpepar seted"); 

      } 
     }, 0, intervall); 

     return super.onStartCommand(intent, flags, startId); 

    } 

    @Override 
    public IBinder onBind(Intent intent) 
    { 
     // TODO Auto-generated method stub 

     return null; 
    } 

    public void onDestroy() 
    { 
     Toast.makeText(this, "Service Destroyed", Toast.LENGTH_SHORT).show(); 
     Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 
     v.vibrate(1000); 
     mytimer.cancel(); 
     super.onDestroy(); 
    } 

} 

La mia uscita Logcat è:

## Logcat ## 
04-16 11:06:30.654: E/MAYUR(3405): wallpepar seted 
04-16 11:06:34.636: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:06:59.584: E/MAYUR(3405): wallpepar seted 
04-16 11:07:03.551: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:07:30.078: E/MAYUR(3405): wallpepar seted 
04-16 11:07:33.979: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:07:59.433: E/MAYUR(3405): wallpepar seted 
04-16 11:08:03.340: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:08:30.029: E/MAYUR(3405): wallpepar seted 
04-16 11:08:33.933: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:08:59.481: E/MAYUR(3405): wallpepar seted 
04-16 11:09:03.383: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:09:30.066: E/MAYUR(3405): wallpepar seted 
04-16 11:09:33.966: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:09:59.448: E/MAYUR(3405): wallpepar seted 
04-16 11:10:03.353: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:10:30.049: E/MAYUR(3405): wallpepar seted 
04-16 11:10:33.955: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:10:59.455: E/MAYUR(3405): wallpepar seted 
04-16 11:11:03.350: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:11:30.182: E/MAYUR(3405): wallpepar seted 
04-16 11:11:34.177: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:11:59.406: E/MAYUR(3405): wallpepar seted 
04-16 11:12:03.315: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:12:30.025: E/MAYUR(3405): wallpepar seted 
04-16 11:12:33.929: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:12:34.103: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:12:34.298: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:12:34.497: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:12:34.676: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:12:34.854: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:12:35.022: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:12:35.190: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:12:35.355: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:12:35.522: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:12:35.683: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:12:35.852: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:12:36.023: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:12:36.187: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:12:36.350: D/MAYUR(3405): << wallpepar changed >> 
04-16 11:12:36.513: D/MAYUR(3405): << wallpepar changed >> 

risposta

3

Le chiamate ripetute WALLPAPER_CHANGED sono causate da dispositivi Android più piccoli che eseguono cicli di ritaglio sull'immagine per adattarsi allo schermo. Questo è stato osservato nel AOSP code. È meno probabile che tu veda questo comportamento quando il rapporto dello schermo si adatta o è più grande dell'immagine, quindi perché il tablet non mostra questo comportamento.

È possibile risolvere questo problema con un doppio controllo per i segni di comportamento indesiderato:

long lastExec = System.currentTimeMillis(); 

@Override 
public void onReceive(final Context context, final Intent intent) 
{ 
    change_wallpepar.myPrefs = context.getSharedPreferences("myPrefs", Context.MODE_PRIVATE); 
    new Handler().postDelayed(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      if(System.currentTimeMillis()-lastExec>1000) 
      { 
      Log.d("MAYUR", "<< wallpepar changed >>"); 
      if (change_wallpepar.myPrefs.getLong("temp_for_change", 1) == 0) 
      { 
       context.stopService(new Intent(context, change_wallpepar.class)); 
      } 
      else 
      { 
       SharedPreferences.Editor e = change_wallpepar.myPrefs.edit(); 
       e.putLong("temp_for_change", 0); 
       e.commit(); 
      } 
      } 
      lastExec = System.currentTimeMillis(); 
     } 
    }, 4000); 
} 
-1

La maggior parte probabilmente di un dispositivo specifico problema.

In generale utilizzando un flag Credo che sia la soluzione recommended

@Override 
public void onReceive(final Context context, final Intent intent) 
{ 
    private static boolean firstReceive = true; 
    change_wallpepar.myPrefs = context.getSharedPreferences("myPrefs", Context.MODE_PRIVATE); 
    new Handler().postDelayed(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      if(firstReceive){ 
      Log.d("MAYUR", "<< wallpepar changed >>"); 
      if (change_wallpepar.myPrefs.getLong("temp_for_change", 1) == 0) 
      { 
       context.stopService(new Intent(context, change_wallpepar.class)); 
      } 
      else 
      { 
       SharedPreferences.Editor e = change_wallpepar.myPrefs.edit(); 
       e.putLong("temp_for_change", 0); 
       e.commit(); 
      } 
     } 
    ///CHANGE firstReceive BASED ON EITHER TIME SINCE LAST WALLPAPER CHANGE 
    ///OR ANY OTHER PARAMETER THAT SUITS YOUR REQUIREMENT 
    }, 4000); 
    } 
} 

Nota che non ho ripristinare di nuovo la bandiera nel Loop, probabilmente si dovrebbe farlo dopo un certo periodo di tempo dopo modifica O risparmiare qualche identificatore sfondo corrente in pref condiviso e partita contro che e impostare il flag ecc, in base al requisito

l'idea è quella di aggirare t emette, quindi si ottiene oltre i falsi positivi e in realtà cambia per le chiamate reali wallpaper_change. Questo è un Workaround e non una vera soluzione al perché il problema esiste.

+0

firstReceive = false; non fatto da nessuna parte, quindi penso che non sia utile nel mio caso. –

+0

Sì, questo è quello che ho menzionato nella mia risposta. Sta a te reimpostare correttamente in modo da non consentire falsi positivi, ma anche non schermare le modifiche effettive della carta da parati – Slartibartfast

0

Non sono sicuro del motivo per cui questo accade su alcuni dispositivi, ma mi sembra che molto probabilmente sia un problema con quel dispositivo specifico. Anche se non riesco a risolvere il problema, potenzialmente potresti tenere una variabile che viene attivata una volta che il listener viene colpito e ripristinato dopo un certo periodo di tempo. In questo modo, il tuo ascoltatore ignorerà le chiamate future per un breve periodo di tempo. Pensa ad esso come una protezione dalle inondazioni.

So che non risolve il problema, ma spero che fornisca una soluzione adeguata.

Problemi correlati