2010-09-09 3 views
5

Я пишу живые обои, которые создают эффект на фоне. Я хочу, чтобы пользователь мог выбрать фон с любого из системных обоев и фотографий камеры. Я хотел бы, чтобы пользователь мог нажать кнопку в меню «Настройки», отобразить список параметров так же, как установить обои с главного экрана, минус параметры «Живые обои». После того, как пользователь выполнит выбор и отобразит фактическое изображение, я загружу его на свой холст.Выбор фона для Live Wallpaper

Как это сделать?

Я не могу найти API для получения списка обоев.

Мне удалось составить список поставщиков обоев с использованием намерений. Затем я получаю список поставщиков живых обоев, также используя Intents и удаляю их из своего первого списка. Это дает мне список поставщиков обоев, которые не живут.

Теперь что? Есть ли другие способы сделать это, что мне не хватает?

Пожалуйста, помогите.

ответ

25

Я делаю это, помещая предпочтение в настройки xml как это (мой - flash_setting.xml);

<Preference 
    android:key="image_custom" 
    android:title="Choose Background" 
    android:summary="Select a Custom Image" 
    /> 

Я создал пользовательский класс, чтобы взять получить OnPreferenceClick Слушатель и следить за пользователем щелкая предпочтение как так (это вызов mySettings.java) (обратите внимание, что процедура getRealPathFromURI не моя и была найденные здесь в другом месте);


Ваш класс должен начать путем расширения PreferenceActivity и реализации изменений слушателя Sharedpreference

public class flashSettings extends PreferenceActivityimplements SharedPreferences.OnSharedPreferenceChangeListener {  

Ссылки на имя предпочтения и зарегистрировать слушатель

@Override 
protected void onCreate(Bundle icicle) { 
    super.onCreate(icicle); 
    getPreferenceManager().setSharedPreferencesName(
      fingerflashpro.SHARED_PREFS_NAME); 
    addPreferencesFromResource(R.xml.flash_settings);  getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(
      this); 

Далее мы установим на прослушиватель предпочтений для прослушивания «image_custom». Когда он будет нажат, мы начнем новое намерение отобразить сборщик фотографий. Мы начинаем с StartActivityForResult, чтобы мы могли вернуть URI изображения из намерения.

getPreferenceManager().findPreference("image_custom").setOnPreferenceClickListener(new OnPreferenceClickListener() 
{ 
    @Override 
    public boolean onPreferenceClick(Preference preference) 
    { 
     Display display = getWindowManager().getDefaultDisplay(); 
     int width = display.getWidth(); 
     int height = display.getHeight(); 
     Toast.makeText(getBaseContext(), "Select Image - " + (width) + " x " + height , Toast.LENGTH_LONG).show(); 
     Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); 
     photoPickerIntent.setType("image/*"); 
     startActivityForResult(photoPickerIntent, 1); 
     return true; 
    } 
});} 

Далее мы ожидаем, что действие вернет результат, и мы проанализируем URI на реальном пути.

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
super.onActivityResult(requestCode, resultCode, data); 
if (requestCode == 1) { 
if (resultCode == Activity.RESULT_OK) { 
    Uri selectedImage = data.getData(); 
    String RealPath; 
    SharedPreferences customSharedPreference = getSharedPreferences(fingerflashpro.SHARED_PREFS_NAME, Context.MODE_PRIVATE); 
    SharedPreferences.Editor editor = customSharedPreference.edit(); 
    RealPath = getRealPathFromURI (selectedImage); 
    editor.putString("image_custom", RealPath); 
    editor.commit(); 
}} 

Следующий фрагмент кода был обнаружен на этом сайте (по PercyPercy на this thread), и я только в том числе его для полноты картины. Однако он работает отлично.

public String getRealPathFromURI(Uri contentUri) {   
String [] proj={MediaColumns.DATA}; 
Cursor cursor = managedQuery(contentUri, 
     proj, // Which columns to return 
     null,  // WHERE clause; which rows to return (all rows) 
     null,  // WHERE clause selection arguments (none) 
     null); // Order-by clause (ascending by name) 
int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA); 
cursor.moveToFirst(); 
return cursor.getString(column_index);} 

Удостоверьтесь, что мы реализуем требуемые Переопределения;

@Override 
protected void onResume() { 
    super.onResume(); 
} 

@Override 
protected void onDestroy() { 
    getPreferenceManager().getSharedPreferences(). 
     unregisterOnSharedPreferenceChangeListener(this); 
    super.onDestroy(); 
} 

@Override 
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, 
     String key) { 
}} 

Затем в основной деятельности обои службы вы можете извлечь путь изображения из ваших общих предпочтений.

@Override 
    public void onSharedPreferenceChanged(SharedPreferences prefs, 
      String key) { 

     imageBg = prefs.getString("image_custom", "Bad Image"); 
      getBackground();} 

Здесь вы можете скачать абсолютно бесплатно.Я попытался помешать захвату ошибок на случай, если файл будет удален, переименован или SD-карта будет смонтирована (следовательно, вы потеряете изображение). Я также попытался установить некоторые грубые проверки ориентации устройства. Я уверен, что вы можете сделать лучше.

Существует также проверка Samplesize, поэтому вы не превышаете бюджет VM. Это самая важная часть этого кода, чтобы предотвратить закрытие сил и, безусловно, должно быть включено.

Я также называю эту процедуру, когда ориентация телефона изменяется, так что каждый раз изменяется размер фона.

void getBackground() { 
     if (this.cvwidth == 0 || this.cvheight == 0 || this.visibleWidth == 0) { 
       this.cvwidth = 480; 
       this.cvheight = 854; 
       this.visibleWidth = 480;} 
     if(new File(imageBg).exists()) { 
       int SampleSize = 1; 
      do { 
       BitmapFactory.Options options = new BitmapFactory.Options(); 
       options.inJustDecodeBounds = true; 
       bg = BitmapFactory.decodeFile(imageBg, options); 
       SampleSize = (int) (Math.ceil(options.outWidth/(this.visibleWidth * 2))*2); 
       options.inJustDecodeBounds = false; 
       try {options.inSampleSize = SampleSize; 
        bg = BitmapFactory.decodeFile(imageBg, options);} 
        catch (OutOfMemoryError e) { 
         SampleSize = SampleSize * 2; 
         } 
       } while (bg == null); 

      bg = Bitmap.createScaledBitmap(bg, this.cvwidth/2, this.cvheight, true);} 
     else {bg = BitmapFactory.decodeResource(getResources(), R.drawable.bg); 
      bg = Bitmap.createScaledBitmap(bg, this.cvwidth/2, this.cvheight, true);} 
     LoadText = ""; 
    } 

Надеюсь, это поможет. Мне потребовался абсолютный возраст, чтобы придумать все это, и я знаю, что есть еще некоторые области, которые я могу улучшить, но по крайней мере это должно заставить вас идти.

Если у кого-то есть предложения по улучшению этого кода, я все уши.

+0

это Предусматривает ли тот же список обоев, которые пользователь видит на главном экране? Это то, что я хочу. Пользователь должен иметь возможность выбирать из системных обоев и обоев, предоставляемых другими приложениями, без живых обоев. – DarthNoodles

+0

Это позволяет просматривать каждое изображение на SD-карте. Если вы загрузите бесплатную Droid X Livewallpaper от wabbittdevs, это именно то, что вы испытаете. Вот откуда берется код выше. – Dean

+0

Я скачал и проверил его. Это не то, чего я хочу. На главном экране вашего устройства нажмите «меню» и выберите «обои». Это список, который я хочу, чтобы пользователь имел, минус Live Wallpapers. На моем устройстве я получаю Live Wallpaper, Photos и HTC Wallpapers. Эмулятор дает вам живые обои, фотографии и обои, а также запись «Обои», предоставленную образцом «Главная». Это действия, которые соответствуют намерению ACTION_SET_WALLPAPER. Похоже, что то, что я хочу, нелегко сделать с API как есть. – DarthNoodles

0

Нет, это самый лучший способ сделать это. Все, что реагирует на android.intent.action.SET_WALLPAPER, будет поставщиком обоев той или иной формы. Проблема в том, что предоставление им этого списка приведет к выходу из уравнения. По существу, если они выбрали что-то из другого провайдера, вы не сможете настроить свои Live Wallpaper. Вероятно, вы можете обойти это с помощью каких-то творческих настроек манифеста и некоторых вызовов типа «startActivityForResult».

После того, как выбрать что-то, хотя это простой вопрос, что-то вроде этого в вашем WallpaperService.Engine:

@Override 
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) 
{ 
    super.onSurfaceChanged(holder, format, width, height); 
    if(isVisible()) 
    { 
    mSurfaceHolder = holder; 
    final Drawable drawable = WallpaperManager.getInstance(getBaseContext()).getFastDrawable(); 
    mSurfaceHolder.setFormat(RenderThread.pixFormat); 
    Canvas c = mSurfaceHolder.lockCanvas(); 
    if(c != null) 
     { 
      drawable.draw(c); 
      mSurfaceHolder.unlockCanvasAndPost(c); 
     } 
    } 
} 
Смежные вопросы