17

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()壁紙の変更が1回行われたとしても、数分後に複数回(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 >>
4

3 に答える 3

3

繰り返しWALLPAPER_CHANGED呼び出されるのは、画面に合わせて画像上でトリミング スケール サイクルを実行する小さな Android デバイスが原因です。これは、 AOSP コードで観察されます。画面の比率が画像に適合するか、画像よりも大きい場合、この動作が見られる可能性は低くなります。そのため、タブレットがこの動作を示さないのはこのためです。

望ましくない動作の兆候を再確認することで、この問題を解決できます。

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);
}
于 2015-04-23T18:35:33.303 に答える
0

これが一部のデバイスで発生する理由はわかりませんが、その特定のデバイスに問題がある可能性が高いようです。その問題を解決することはできませんが、リスナーがヒットして一定期間後にリセットされると、トグルされる変数を保持できる可能性があります。したがって、これにより、リスナーは将来の呼び出しを短期間無視します..これは、フラッド保護のようなものと考えてください。

これで実際の問題が解決されないことは承知していますが、適切な回避策が提供されることを願っています。

于 2015-04-23T17:45:40.287 に答える
-1

ほとんどの場合、デバイス固有の問題です。

一般的に、フラグを使用することが推奨される解決策だと思います

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

Loop でフラグを再度リセットしていないことに注意してください。おそらく、最後の変更から一定時間後にリセットするか、現在の壁紙識別子を共有設定に保存し、それに基づいてフラグなどを設定する必要があります。あなたの要件

アイデアは、問題を回避することです。そのため、誤検知を乗り越えて、実際のwallpaper_change呼び出しに実際に変更します。これはWorkaround、問題が存在する理由に対する実際の解決策ではありません。

于 2015-04-22T11:41:01.853 に答える