onHandleIntent() - смена обоев работает некорректно

Я использую IntentService для смены обоев в фоновом режиме. Используя приведенный ниже код внутри основного класса Activity, обои правильно меняются на изображение, но когда код добавляется в onHandleItent(), фон каждый раз меняется на другой сплошной цвет. Это проблема с памятью или что?

Код внутри класса Activity - работает правильно:

public void ChangeWallpaper(String imagepath) {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels << 2;
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap decodedSampleBitmap = BitmapFactory.decodeFile(imagepath, options);
options.inSampleSize = calculateInSampleSize(options, width, height);
options.inJustDecodeBounds = false;
decodedSampleBitmap = BitmapFactory.decodeFile(imagepath, options);
WallpaperManager wm = WallpaperManager.getInstance(this);
try {
    wm.setBitmap(decodedSampleBitmap);
} catch (IOException e) {
}
}

Код внутри onHandleIntent() - НЕ работает корректно:

    @Override
    protected void onHandleIntent(Intent workIntent) {
    String imagepath = workIntent.getStringExtra("String");
    DisplayMetrics displayMetrics = new DisplayMetrics();
    WindowManager hi = ((WindowManager) getBaseContext().getSystemService(Context.WINDOW_SERVICE));
    int height = displayMetrics.heightPixels;
    int width = displayMetrics.widthPixels << 2;
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    Bitmap decodedSampleBitmap = BitmapFactory.decodeFile(imagepath, options);
    options.inSampleSize = calculateInSampleSize(options, width, height);
    options.inJustDecodeBounds = false;
    decodedSampleBitmap = BitmapFactory.decodeFile(imagepath, options);
    WallpaperManager wm = WallpaperManager.getInstance(this);
    try {
        wm.setBitmap(decodedSampleBitmap);
    } catch (IOException e) {
    }
}

есть идеи?

РЕДАКТИРОВАНИЕ 2 — ПРОБЛЕМА (нерешенная)

Оказывается, что-то не так с самим onHandleIntent().

Чтобы проверить это, я сделал

  1. Я добавил SharedPreferences в onHandleIntent(), чтобы написать фиктивную строку «IS Started», и включил onStartCommand() в IntentService, который считывает фиктивные SharedPreferences и отображает сохраненную строку в Toast:

    public int onStartCommand(Intent intent, int flags, int startId) {
        SharedPreferences settings2 = getSharedPreferences("IS", 0);
        String IS = settings2.getString("IS","");
        Toast.makeText(this, "" + IS, Toast.LENGTH_SHORT).show();
        return super.onStartCommand(intent,flags,startId);
    }
    

Я также добавил фиктивную запись в SharedPrefs в onIntentHandle следующим образом:

    @Override
    protected void onHandleIntent(Intent intent) {
        SharedPreferences settings = getSharedPreferences("IS", 0);
        SharedPreferences.Editor editor = settings.edit();
        editor.putString("IS","IS Started");
        editor.commit();
    }
  1. Затем я дважды вызвал службу: в первый раз, потому что фиктивный SharedPref будет пустым, поскольку он вызывается перед onHandleIntent(), и у onHandleIntent() есть шанс записать фиктивную строку. Второй раз (теперь, когда onHandleIntent() что-то написал) для onStartCommand( ), чтобы прочитать содержимое фиктивной строки и отобразить его.

РЕЗУЛЬТАТ: Toast отображает «IS STARTed», что означает, что вызывается onHandleIntent().

НО Затем, чтобы определить проблему с обоями, я поместил Toast прямо в onHandleIntent(), чтобы посмотреть, работает ли он следующим образом:

    @Override
    protected void onHandleIntent(Intent intent) {
        Toast.makeText(this, "onHandleWorks", Toast.LENGTH_SHORT).show();
    }

РЕЗУЛЬТАТ: Он не показал!

Итак, почему onHandleIntent() вызывается и распознает только НЕКОТОРЫЕ команды?

ИЗМЕНИТЬ 3

Код внутри onHandleIntent() - в настоящее время как есть:

    public class intentClass extends IntentService {

public intentClass() {
    super("intentClass");
}

    @Override
    protected void onHandleIntent(Intent workIntent) {
    String imagepath = workIntent.getStringExtra("String");
    DisplayMetrics displayMetrics = new DisplayMetrics();
    WindowManager hi = ((WindowManager) getBaseContext().getSystemService(Context.WINDOW_SERVICE));
    int height = displayMetrics.heightPixels;
    int width = displayMetrics.widthPixels << 2;

    // the problem is here - the above command doesn't retrieve the Display size

    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    Bitmap decodedSampleBitmap = BitmapFactory.decodeFile(imagepath, options);
    options.inSampleSize = 4; // this is what needs to be calculated.
    options.inJustDecodeBounds = false;
    decodedSampleBitmap = BitmapFactory.decodeFile(imagepath, options);
    WallpaperManager wm = WallpaperManager.getInstance(this);
    try {
        wm.setBitmap(decodedSampleBitmap);
    } catch (IOException e) {
    }
}
}

Как получить показатели отображения вне активности, когда активность не распространяется на IntentService?


person KickAss    schedule 02.04.2013    source источник


Ответы (2)


Вы пропускаете одну строку в своем коде, которая

DisplayMetrics displayMetrics = new DisplayMetrics();    
WindowManager hi = ((WindowManager) getBaseContext().getSystemService(Context.WINDOW_SERVICE));
hi.getDefaultDisplay().getMetrics(displayMetrics);

это основная причина того, что размер вашей выборки был неправильным. теперь вы можете использовать свой метод для расчета размера выборки вместо использования sampleSize = 4;

Надеюсь, теперь ваша проблема решена :)

person M.J    schedule 04.04.2013

Если намерениеService меняет ваши обои на какой-то случайный сплошной цвет, проблема может быть связана с растровым изображением. Отладьте и проверьте, генерирует ли код правильное растровое изображение или нет. Проверьте путь растрового изображения, высоту и ширину.

РЕДАКТИРОВАТЬ:

public class intentService extends IntentService {

Context context;
private String res;

public intentService() {
    super("intentService");

}
@Override
protected void onHandleIntent(Intent workIntent) {
    String imagepath = workIntent.getExtras().getString("img");

    DisplayMetrics displayMetrics = new DisplayMetrics();
    WindowManager hi = ((WindowManager) getBaseContext().getSystemService(Context.WINDOW_SERVICE));
    int height = displayMetrics.heightPixels;
    int width = displayMetrics.widthPixels << 2;
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    Bitmap decodedSampleBitmap = BitmapFactory.decodeFile(imagepath, options);
    options.inSampleSize = 4;
    options.inJustDecodeBounds = false;
    decodedSampleBitmap = BitmapFactory.decodeFile(imagepath, options);
    WallpaperManager wm = WallpaperManager.getInstance(this);
    try {
        wm.setBitmap(decodedSampleBitmap);
    } catch (IOException e) {
    }
}

}

person M.J    schedule 02.04.2013
comment
Я попробовал ваш код, и он отлично работал от службы намерений и активности. - person M.J; 02.04.2013
comment
Вам не нужен метод onStartCommand() для достижения этого. Я скопировал и вставил ваш код в фиктивный проект и выбрал изображение с SD-карты, оно работало отлично. Пожалуйста, проверьте код EDIT, единственное, что у меня есть, это options.inSampleBitmap = 4 может быть что-то становится не так в расчете выборки. - person M.J; 02.04.2013
comment
Большое вам спасибо :) вы правы, изменение inSampleBitmap на 4 исправило это. Что-то не так с методом расчета для него. Еще раз большое спасибо :) Я застрял на этом в течение 2 дней! - person KickAss; 02.04.2013
comment
Не за что, рад помочь. :) - person M.J; 03.04.2013
comment
У меня новый вопрос. Если я хочу добавить метод calculateInSample к основному методу onHandle, перед параметрами options.inSampleSize = 4; и вычислить его там, как бы я изменил inCalculateMethod? Я пытался это сделать, но не смог заставить его работать. См. РЕДАКТИРОВАТЬ 3 :) - person KickAss; 03.04.2013