Подтвердить что ты не робот

BroadcastReceiver для WALLPAPER_CHANGED вызывает onReceive() несколько раз: Android

У меня есть BroadcastReceiver и объявлено так:

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

}

Выход My 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 >>
4b9b3361

Ответ 1

Повторенные вызовы 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);
}

Ответ 2

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

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

Ответ 3

Скорее всего, проблема с устройством.

В общем, используя флаг, я думаю, это рекомендуемое решение

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

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

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