17

У меня есть BroadcastReceiver и объявил это так:BroadcastReceiver для WALLPAPER_CHANGED вызывает OnReceive() несколько раз: 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> 

и приемник:

@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); 
} 

Когда я изменить обои здесь это следует вызывать один раз. Это действительно работает по моим ожиданиям некоторое время, через несколько минут он вызывает onreceive() несколько (10-18) раз, хотя изменение в обоях выполняется один раз. Еще более странно, что он отлично работает на планшете Samsung Galaxy 4.4.2, но не работает на Motorola (Moto E 4.4.4).

Моя служба:

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(); 
    } 

} 

Мой выход 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 >> 

ответ

3

Повторные вызовы WALLPAPER_CHANGED вызваны меньшими устройствами Android, на которых установлены циклы масштабирования на изображении, чтобы они соответствовали экрану. Это наблюдается в AOSP code. Вы менее склонны видеть это поведение, когда отношение экрана соответствует или больше изображения, поэтому почему таблетка не проявляет такого поведения.

Вы можете решить эту проблему путем двойной проверки на наличие признаков нежелательного поведения:

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

Наиболее вероятно устройство специфическая проблема.

В общем, используя флаг я думаю это 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); 
    } 
} 

Обратите внимание, что я не сбросить флаг снова в петле, вероятно, вы должны сделать это после определенного количества времени с момента последнего изменения ИЛИ сохранить некоторый идентификатор текущего обои в общей прив и матч против этого и установить флаг и т.д., основываясь на вашем требовании

идея заключается в том, чтобы обойти т он выдает, так что вы преодолеваете ложные срабатывания и фактически меняете реальные звонки wallpaper_change. Это Workaround, а не фактическое решение проблемы.

+0

firstReceive = ложь; не сделано нигде, поэтому я думаю, что это не полезно в моей очереди. –

+0

Да, это то, что я упомянул в своем ответе. Это вам нужно, чтобы сбросить его правильно, чтобы вы не допустили ложных срабатываний, но также не отменили фактические изменения на стене – Slartibartfast

0

Я не уверен, почему это происходит на некоторых устройствах, но мне кажется, что это скорее всего проблема с этим конкретным устройством. Хотя я не могу решить эту проблему, потенциально вы могли бы удерживать переменную, которая переключается после того, как ваш слушатель попадает и перезагружается через некоторое время. Это приведет к тому, что ваш слушатель будет игнорировать будущие призывы в течение короткого периода времени. Думайте об этом как о защите от наводнений.

Я знаю, что это не решит вашу актуальную проблему, но я надеюсь, что это обеспечит подходящее обходное решение.

Смежные вопросы