BroadcastReceiver for WALLPAPER_CHANGED calls onReceive() multiple times : Android

橙三吉。 提交于 2019-12-04 22:50:59

The repeated WALLPAPER_CHANGED calls are caused by smaller Android devices running crop-scale cycles on the image to fit the screen. This is observed in the AOSP code. You're less likely to see this behavior when the screen ratio fits or is bigger than the image, hence why the tablet doesn't exhibit this behavior.

You can fix this problem by double-checking for signs of the unwanted behavior:

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

I'm not sure why this happens on some devices but it would seem to me to most likely be a problem with that specific device. Whilst I cannot resolve that issue, potentially you could hold a variable that is toggled once your listener is hit and reset after a period of time. This will thus cause your listener to ignore future calls for a short period of time.. think of it like flood protection.

I know that doesn't resolve your actual issue but I hope it will provide a suitable workaround.

Slartibartfast

Most possibly a device specific problem.

In general using a flag I guess is the recommended solution

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

Note that I haven't reset the flag again in the Loop, you should probably do it after a certain amount of time since last change OR save some current wallpaper identifier in shared pref and match against that and set the flag etc., based on your requirement

The idea is to workaround the issue, so you get over the false positives and actually change for real wallpaper_change calls. This is a Workaround and not an actual solution to why the problem exists.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!