【问题标题】:BroadcastReceiver for WALLPAPER_CHANGED calls onReceive() multiple times : Android用于 WALLPAPER_CHANGED 的 BroadcastReceiver 多次调用 onReceive() :Android
【发布时间】:2015-04-16 05:48:12
【问题描述】:

我有一个 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)次,即使墙纸的更改只完成了一次。更奇怪的是,它在三星 Galaxy 平板电脑 4.4.2 版上运行良好,但在摩托罗拉 (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 >>

【问题讨论】:

    标签: android android-service android-broadcast android-wallpaper


    【解决方案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】:

      我不确定为什么会在某些设备上发生这种情况,但在我看来,这很可能是该特定设备的问题。虽然我无法解决该问题,但您可能会持有一个变量,一旦您的侦听器被击中并在一段时间后重置,该变量就会被切换。因此,这将导致您的听众在短时间内忽略未来的呼叫.. 将其视为防洪。

      我知道这并不能解决您的实际问题,但我希望它能提供合适的解决方法。

      【讨论】:

        【解决方案3】:

        很可能是特定于设备的问题。

        我猜一般使用标志是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,并不是问题存在的实际解决方案。

        【讨论】:

        • firstReceive = false;没有在任何地方做过,所以我认为它对我的问题没有用。
        • 是的,这就是我在回答中提到的。您可以正确重置它,这样您就不会允许误报,但也不会筛选出实际的墙纸变化
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多