Set Imageview as wallpaper with a Button

2.9k views Asked by At

I have a problem with my code, I want to set an image from an ImageView as the wallpaper, I have a gallery and when I press an image from there the ImageView changes, so I don't know where to put the code for onClick to my button.

This is my code:

public class MainActivity extends Activity{

    final Integer[] mThumbIds = {
            R.drawable.a_compressed, R.drawable.b_compressed,
            R.drawable.c_compressed, R.drawable.d_compressed,
           };
    final Integer[] mFullSizeIds = {
            R.drawable.a, R.drawable.b,
            R.drawable.c, R.drawable.d,
           };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Gallery galeria = (Gallery) findViewById(R.id.gallery);
        galeria.setAdapter(new ImageAdapter(this));
        galeria.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
                ImageView laimagen = (ImageView) findViewById(wallpaper);
                laimagen.setImageResource(mFullSizeIds[position]);
            }
        });
    }


    public class ImageAdapter extends BaseAdapter {
        private Context mContext;

        public ImageAdapter(MainActivity inicio) {
            mContext = inicio;
        }

        public int getCount() {
            return mThumbIds.length;
        }

        public Object getItem(int position) {
             return null;
        }

        public long getItemId(int position) {
             return mFullSizeIds[position];
        }

        // create a new ImageView for each item referenced by the Adapter
        public View getView(int position, View convertView, ViewGroup parent) {

            ImageView  imageView = new ImageView(mContext);
            imageView.setImageResource(mThumbIds[position]);
            imageView.setLayoutParams(new Gallery.LayoutParams(180, 170));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            return imageView;

        }
    }
}

I tried this but it did not work

private void onClick() {
    Bitmap bitmap;
    bitmap = BitmapFactory.decodeResource(getResources(),mFullSizeIds[position]);

    try {
        getApplicationContext().setWallpaper(bitmap);
        Toast.makeText(MainActivity.this, "Wallpaper set", Toast.LENGTH_LONG).show();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

This is my layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
android:background="#222222"
android:orientation="vertical">


<ImageView android:id="@id/wallpaper"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:scaleType="centerInside"
    android:layout_weight="1.0"
    android:src="@drawable/a" />

<Gallery android:id="@id/gallery"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />

<Button android:layout_gravity="center_horizontal"
    android:id="@id/set"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/SetWallpaper"
    android:background="@color/Esmeralda"
    android:textColor="@color/Clouds"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />

</LinearLayout>
2

There are 2 answers

2
Mukesh Rana On BEST ANSWER

First of all you should take an int variable which specifies basically the index of drawableIds present in your mFullSizeIds[] and intialise it to -1 intitially like this

private int index=-1;

and in your galeria.setOnItemClickListener(), assign the position to your index variable like this.

 galeria.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
            index=position;
            laimagen.setImageResource(mFullSizeIds[position]);
        }
    });

and then in your Button click, do something like this

private void onClick() {

  try {
       WallpaperManager wallpaperManager = WallpaperManager.getInstance(MainActivity .this); 
       Drawable drawable = getResources().getDrawable(mFullSizeIds[index]);// here index is position of selected drawable in your mFullSizeIds[] that you have set in galeria.setOnItemClickListener()
            Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
            wallpaperManager.setBitmap(bitmap);
    } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
    }
}

your onCreate() will look like this

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ImageView laimagen = (ImageView) findViewById(R.id.wallpaper);
    Gallery galeria = (Gallery) findViewById(R.id.gallery);
    galeria.setAdapter(new ImageAdapter(this));
    galeria.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
              index=position;
              laimagen.setImageResource(mFullSizeIds[position]);
        }
    });
    Button setButton=(Button)findViewById(R.id.set);
     setButton.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                onClick();
            }
        });
}
1
krishnan muthiah pillai On

Here the sample code for wallpaper

public class WallpaperMainActivity extends Activity {

private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;


@SuppressWarnings("deprecation")
private final GestureDetector detector = new GestureDetector(new SwipeGestureDetector());

/** A list containing the resource identifiers for all of our selectable backgrounds */
private static final List<Integer> backgrounds = new ArrayList<Integer>();
/** The total number of backgrounds in the list */
private static final int TOTAL_IMAGES;
/** Instantiate the list statically, so this will be done once on app load, also 
  calculate the total number of backgrounds */
static {
    backgrounds.add(R.drawable.background1);
    backgrounds.add(R.drawable.background2);
    backgrounds.add(R.drawable.background3);
    backgrounds.add(R.drawable.background4);
    backgrounds.add(R.drawable.background5);
    backgrounds.add(R.drawable.background6);
    backgrounds.add(R.drawable.background7);
    backgrounds.add(R.drawable.background8);
    backgrounds.add(R.drawable.background9);
    backgrounds.add(R.drawable.background10);

    // We -1 as lists are zero indexed (0-2 is a size of 3) - we'll mke use of this to 
   implement a browsing loop
    TOTAL_IMAGES = (backgrounds.size() - 1);
  }
/** the state of what wallpaper is currently being previewed */
private int currentPosition = 0;
/** our image wallpaper preview */
private ImageView backgroundPreview;
/** A helper class that will do the heavy work of decoding images and actually setting 
the wallpaper */
private HeavyLifter chuckNorris;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_wallpaper_main);
    backgroundPreview = (ImageView) findViewById(R.id.backgroundPreview);
    backgroundPreview.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(final View view, final MotionEvent event) {

            detector.onTouchEvent(event);
            return true;
        }
    });
    // Set the default image to be shown to start with
    changePreviewImage(currentPosition);
    // Load are heavy lifter (goes and does work on another thread), to get a response 
    after the lifters thread
    // has finished we pass in a Handler that will be notified when it completes
    chuckNorris = new HeavyLifter(this, chuckFinishedHandler);

}

/**
 * Called from XML when the previous button is pressed
 * Decrement the current state position
 * If the position is now less than 0 loop round and show the last image (the array size)
 * @param v
 */
public void gotoPreviousImage(View v) {
    int positionToMoveTo = currentPosition;
    positionToMoveTo--;
    if(positionToMoveTo < 0){
        positionToMoveTo = TOTAL_IMAGES;
    }
    changePreviewImage(positionToMoveTo);
}

/**
 * Called from XML when the set wallpaper button is pressed
 * Thie retrieves the id of the current image from our list
 * It then asks chuck to set it as a wallpaper!
 * The chuckHandler will be called when this operation is complete
 * @param v
 */
public void setAsWallpaper(View v) {

    int resourceId = backgrounds.get(currentPosition);
    chuckNorris.setResourceAsWallpaper(resourceId);

    AlertDialog.Builder ab=new AlertDialog.Builder(WallpaperMainActivity.this);
    ab.setIcon(R.drawable.ic_launcheralert);
    ab.setTitle("Image set as Background....");
   ab.setNeutralButton("Ok",new DialogInterface.OnClickListener() {

    @Override
    public void onClick(DialogInterface dialog, int which) {
        // TODO Auto-generated method stub
    }
   } );

   ab.show();


}

/**
 * Called from XML when the next button is pressed
 * Increment the current state position
 * If the position is now greater than are array size loop round and show the first image again
 * @param v
 */
public void gotoNextImage(View v) {
    int positionToMoveTo = currentPosition;
    positionToMoveTo++;
    if(currentPosition == TOTAL_IMAGES){
        positionToMoveTo = 0;
    } 

    changePreviewImage(positionToMoveTo);
}

/**
 * Change the currently showing image on the screen
 * This is quite an expensive operation as each time the system
 * has to decode the image from our resources - alternatives are possible (a list of drawables created at app start)
 * @param pos the position in {@link MainActivity#backgrounds} to select the image from
 */
public void changePreviewImage(int pos) {
    currentPosition = pos;
    backgroundPreview.setImageResource(backgrounds.get(pos));
    Log.d("Main", "Current position: "+pos);
}

/**
 * This is the handler that is notified when are HeavyLifter is finished doing an operation
 */
private Handler chuckFinishedHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        switch(msg.what){
        case SUCCESS:
            break;
        case FAIL:
            Toast.makeText(WallpaperMainActivity.this, "Uh oh, can't do that right now", Toast.LENGTH_SHORT).show();
            break;
        default:
            super.handleMessage(msg);
        }
    }
};
   class SwipeGestureDetector extends SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            try {
                // right to left swipe
                if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {

                    int positionToMoveTo = currentPosition;
                    positionToMoveTo--;
                    if(positionToMoveTo < 0){
                        positionToMoveTo = TOTAL_IMAGES;
                    }
                    changePreviewImage(positionToMoveTo);
                    return true;
                } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {

                    // left to right swipe
                    int positionToMoveTo = currentPosition;
                    positionToMoveTo++;
                    if(currentPosition == TOTAL_IMAGES){
                        positionToMoveTo = 0;
                    } 

                    changePreviewImage(positionToMoveTo);
                    return true;
                }

            } catch (Exception e) {
                e.printStackTrace();
            }

            return false;
        }
    }   

}

Create Another new class

 public class HeavyLifter {

 public static final int SUCCESS = 0;
 public static final int FAIL = 1;

 private final Context context;
 private final Handler callback;
 private WallpaperManager manager;

 /**
 * Setup the HeavyLifter
 * @param context the context we are running in - typically an activity
 * @param callback the handler you want to be notified when we finish doing an operation
 */
  public HeavyLifter(Context context, Handler callback) {
    this.context = context;
    this.callback = callback;
    this.manager = (WallpaperManager)  
     context.getSystemService(Context.WALLPAPER_SERVICE);
 }

  /**
 * Takes a resource id of a file within our /res/drawable/ folder<br/>
 * It then spawns a new thread to do its work on<br/>
 * The reource is decoded and converted to a byte array<br/>
 * This array is passed to the system which can use it to set the phones wallpaper<br/>
 * Upon completion the callback handler is sent a message with eith {@link 
  HeavyLifter#SUCCESS} or {@link HeavyLifter#FAIL}
 * 
 * @param resourceId id of a file within our /res/drawable/ folder
 */
 public void setResourceAsWallpaper(final int resourceId) {
    new Thread() {
        @Override
        public void run() {
            try {
                manager.setBitmap(getImage(resourceId));
                callback.sendEmptyMessage(SUCCESS);
            } catch (IOException e) {
                Log.e("Main", "Cant set wallpaper");
                callback.sendEmptyMessage(FAIL);
            }
        }
    }.start();
  }

  /**
 * Decodes a resource into a bitmap, here it uses the convenience method 
'BitmapFactory.decodeResource', but you can decode
 * using alternatives these will give you more control over the size and quality of the 
 resource.
 * You may need certain size resources within each of your /hdpi/ /mdpi/ /ldpi/ folders
  in order
 * to have the quality and look you want on each different phone.
 */
private Bitmap getImage(int resourceId) {
    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, 
null);
    Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, 
manager.getDesiredMinimumWidth(), manager.getDesiredMinimumHeight(), true);
    bitmap.recycle();
    bitmap = null;
    return scaledBitmap;
 }
}

add this to your manifest

        <uses-permission android:name="android.permission.SET_WALLPAPER" />

and

        <intent-filter>
            <action android:name="android.intent.action.SET_WALLPAPER" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>