问题
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
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();
}
- 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?
回答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 :)
回答2:
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) {
}
}
}
来源:https://stackoverflow.com/questions/15756253/onhandleintent-wallpaper-change-not-working-correctly