onHandleIntent() - Wallpaper change not working correctly
Asked Answered
E

2

0

I am using the IntentService to change wallpaper in the background. Using the code below inside the main Activity class the wallpaper changes to an image correctly, but when the code is added to the onHandleItent() the background changes to a different solid color each time. Is this a memory issue or what?

Code inside Activity class - works correctly:

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

Code inside onHandleIntent() - DOES NOT work correctly:

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

any ideas?

EDIT 2 - THE PROBLEM (Unsolved)

It turns out something is wrong with the onHandleIntent() itself.

To test it, I did

  1. I added a SharedPreferences to the onHandleIntent() to write a dummie string "IS Started" and included the onStartCommand() to the IntentService which reads the dummie SharedPreferences and displays the saved string in a 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);
    }
    

I also added a dummie write to SharedPrefs in the onIntentHandle like this:

    @Override
    protected void onHandleIntent(Intent intent) {
        SharedPreferences settings = getSharedPreferences("IS", 0);
        SharedPreferences.Editor editor = settings.edit();
        editor.putString("IS","IS Started");
        editor.commit();
    }
  1. I then called the service twice: first time becuase dummy SharedPref will be empty as it gets called before onHandleIntent() and a chance for onHandleIntent() to write the dummie string Second time (now that onHandleIntent() has written something) for onStartCommand() to read the contents of dummie string and display them.

RESULT: Toast displayed "IS STarted" meaning onHandleIntent() is being called.

BUT Then to identify the wallpaper issue I put a Toast directly inside onHandleIntent() to see if it works like this:

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

RESULT: It didn't show!

So Why is onHandleIntent() being called and only recognising SOME commands?

EDIT 3

Code inside onHandleIntent() - Currently as it is:

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

How do I get the display metrics outside activity when activity is not extended to IntentService?

Effectual answered 2/4, 2013 at 4:42 Comment(0)
E
1

Your are skipping one line in your code which is

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

this is the main reason that your sample size was getting wrong. now you can use your method to calculate the sample size instead of using sampleSize = 4;

Hope so your problem is solved now :)

Encircle answered 4/4, 2013 at 15:7 Comment(0)
E
1

If intentService is changing your wallpaper to some random solid colour then problem could be with the bitmap. Debug and check if code is generating right bitmap or not. Check bitmap path ,height and width as well.

EDIT:

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

}

Encircle answered 2/4, 2013 at 5:34 Comment(4)
I tried your code and it was working fine from intent service and activity.Encircle
You dont need onStartCommand() method to achieve this.i copied and pasted your code in dummy project and chose an image from SD card it was working perfectly fine.Please check EDIT code the only thing i have change is options.inSampleBitmap = 4 may be something is getting wrong in calculating the sample.Encircle
Thank you so much :) you are right, changing the inSampleBitmap to 4 fixed it. Something is wrong with the calculating method for it. Thank you so much again :) I've been stuck on this for 2 days!Effectual
I have a new question. If I want to add the calculateInSample method to the main onHandle method- before the "options.inSampleSize = 4;" and calculate it there, how would I change the inCalculateMethod? I tried to do it, but I couldn't get it to work. See EDIT 3 :)Effectual
E
1

Your are skipping one line in your code which is

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

this is the main reason that your sample size was getting wrong. now you can use your method to calculate the sample size instead of using sampleSize = 4;

Hope so your problem is solved now :)

Encircle answered 4/4, 2013 at 15:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.