Освой Android играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Метод setWallpaper() (устар.)
WallpaperManager
Очистить обои
Изменение существующих обоев
Чтобы поместить изображение своего любимого кота в качестве обоев главного экрана, нужно проделать три вещи:
В старых версиях Android был метод getApplicationContext().setWallpaper(bitmap), который сейчас объявлен устаревшим. Раньше здесь был код для этого примера. Но я его удалил. Но с другой стороны, он работал по другому принципу и не растягивал картинку, как это происходит сейчас (см. примеры ниже).
Теперь рассмотрим современный вариант установки обоев. За смену обоев отвечает класс WallpaperManager. Алгоритм остался прежним - спрашиваем разрешение у кота, устанавливаем необходимое разрешение (не путать с разрешением, которое было получено от кота) в манифесте и пишем код для нажатия кнопки.
Установим необходимое разрешение в манифесте:
<uses-permission android:name="android.permission.SET_WALLPAPER" />
В папку res/raw поместите изображение, которое хотите добавить в качестве обоев. Добавим на экран активности кнопку, с помощью которой будем устанавливать новые обои.
val button: Button = findViewById(R.id.button)
button.setOnClickListener {
val wallpaperManager = WallpaperManager.getInstance(this)
wallpaperManager.setResource(R.raw.cat)
}
Если необходимо очистить установленные обои и вернуться к системным обоям по умолчанию, то вызывайте метод clear() или clearWallpaper.
wallpaperManager.clear()
В официальной документации Google нашёл интересный пример изменения текущих обоев при помощи цветовых фильтров. Возьмём за основу предыдущий пример и добавим ещё одну кнопку, которая будет в случайном порядке выбирать цветовой фильтр и напишем код:
package ru.alexanderklimov.wallpaper;
import android.app.WallpaperManager;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
final static private int[] mColors = {Color.BLUE, Color.GREEN, Color.RED,
Color.LTGRAY, Color.MAGENTA, Color.CYAN, Color.YELLOW, Color.WHITE};
private WallpaperManager mWallpaperManager;
private Drawable mWallpaperDrawable;
private ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWallpaperManager = WallpaperManager
.getInstance(getApplicationContext());
mWallpaperDrawable = mWallpaperManager.getDrawable();
mImageView = (ImageView) findViewById(R.id.imageView);
mImageView.setDrawingCacheEnabled(true);
// выводим картинку обоев в свой ImageView
mImageView.setImageDrawable(mWallpaperDrawable);
}
// Щелчок первой кнопки для выбора эффекта
public void onRandomClick(View v) {
int color = (int) Math.floor(Math.random() * mColors.length);
mWallpaperDrawable.setColorFilter(mColors[color],
PorterDuff.Mode.MULTIPLY);
mImageView.setImageDrawable(mWallpaperDrawable);
mImageView.invalidate();
}
// Щелчок второй кнопки для установки обоев
public void onClick(View v) {
try {
mWallpaperManager.setBitmap(mImageView.getDrawingCache());
} catch (IOException e) {
e.printStackTrace();
}
}
}
Обратите внимание, что в данном примере в ImageView загружаются текущие обои через метод getDrawable(), в нашем случае это были обои от предыдущего примера. Нажав несколько раз на кнопку для выбора фильтра, я остановился на зелёном варианте. По-моему получилось симпатично.
Нашёл в интернете пример вызова намерения для установки обоев.
Intent intent = new Intent(Intent.ACTION_ATTACH_DATA);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setDataAndType(uri, "image/*");
intent.putExtra("mimeType", "image/*");
this.startActivity(Intent.createChooser(intent, "Set as:"));
Для примера нужно откуда-то получить Uri и вставить в пример. В таком варианте не пробовал.
Напишем другой вариант с учётом версий устройства.
package ru.alexanderklimov.as14;
import android.app.Activity;
import android.app.WallpaperManager;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
import java.io.FileNotFoundException;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
private static final int RQS_OPEN_IMAGE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick(View v) {
Intent intent = new Intent();
if (Build.VERSION.SDK_INT >=
Build.VERSION_CODES.KITKAT) {
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
} else {
intent.setAction(Intent.ACTION_GET_CONTENT);
}
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, RQS_OPEN_IMAGE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == RQS_OPEN_IMAGE) {
Uri wallpaperUri = data.getData();
Toast.makeText(this, wallpaperUri.toString(), Toast.LENGTH_LONG).show();
Bitmap newBitmap = loadBitmap(wallpaperUri);
changeWallpaper(newBitmap);
}
}
}
private Bitmap loadBitmap(Uri uri) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(
getBaseContext().getContentResolver().openInputStream(uri));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return bitmap;
}
private void changeWallpaper(Bitmap bitmap){
if(bitmap != null){
WallpaperManager wallpaperManager =
WallpaperManager.getInstance(getApplicationContext());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if(wallpaperManager.isWallpaperSupported()){
try {
wallpaperManager.setBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}else{
Toast.makeText(MainActivity.this,
"Смена обоев не поддерживается",
Toast.LENGTH_LONG).show();
}
}else{
try {
wallpaperManager.setBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
}
}else{
Toast.makeText(MainActivity.this, "Нет картинки", Toast.LENGTH_LONG).show();
}
}
}
На относительно новых устройствах мы используем новое действие для намерения ACTION_OPEN_DOCUMENT. С его помощью можно выбрать картинку из разных мест. Выбранное изображение через Uri возвращается назад в приложение.
Обратите внимание, что в Android 6 появился новый метод isWallpaperSupported().