Robię to poprzez umieszczenie preferencji w ustawieniach xml w ten sposób (mój jest flash_setting.xml);
<Preference
android:key="image_custom"
android:title="Choose Background"
android:summary="Select a Custom Image"
/>
Stworzyłem klasę niestandardową wziąć uzyskać OnPreferenceClick słuchaczem i oglądania dla użytkownika kliknięcie preferencje jako tak (jest to wezwanie mySettings.java) (proszę pamiętać, że rutynowe getRealPathFromURI nie jest moja i była znaleźć gdzie indziej tutaj);
Twoja klasa powinna rozpocząć poprzez rozszerzenie PreferenceActivity i wdrażaniu zmian słuchacza Sharedpreference
public class flashSettings extends PreferenceActivityimplements SharedPreferences.OnSharedPreferenceChangeListener {
link do nazwy preferencji i zarejestrować słuchacza
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
getPreferenceManager().setSharedPreferencesName(
fingerflashpro.SHARED_PREFS_NAME);
addPreferencesFromResource(R.xml.flash_settings); getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(
this);
Dalej będziemy ustawić na słuchacza preferencji do słuchania "image_custom". Po kliknięciu rozpoczniemy nowy zamiar wyświetlenia selektora zdjęć. Zaczynamy od StartActivityForResult, abyśmy mogli odzyskać URI obrazu z zamierzenia.
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;
}
});}
Następnie czekamy na działanie, aby zwrócić wynik i parsujemy URI do prawdziwej ścieżki.
@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();
}}
Poniższy fragment kodu został odnaleziony na tym miejscu (przez PercyPercy na this thread), a ja w tym nie tylko pod względem kompletności. Działa to jednak doskonale.
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);}
Upewnij się, że implementujemy wymagane przesłonięcia;
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onDestroy() {
getPreferenceManager().getSharedPreferences().
unregisterOnSharedPreferenceChangeListener(this);
super.onDestroy();
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
}}
Następnie w swojej głównej działalności usługowej tapety można wyodrębnić ścieżkę obrazu z udostępnionych preferencji.
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs,
String key) {
imageBg = prefs.getString("image_custom", "Bad Image");
getBackground();}
Oto dość nieoczyszczona procedura ładowania obrazu.Próbowałem wprowadzić pułapkę błędów na wypadek, gdyby plik został usunięty, zmieniono jego nazwę lub karta SD zostanie zamontowana (stąd utracisz swój obraz). Próbowałem również wprowadzić kilka prostych sprawdzeń orientacji urządzenia. Jestem pewien, że możesz zrobić to lepiej.
Istnieje również kilka sprawdzeń Samplesize, aby nie przekraczać budżetu maszyny wirtualnej. Jest to najważniejsza część tego kodu, aby zapobiec przymykaniu sił i zdecydowanie należy ją uwzględnić.
Zadzwonię również do tej procedury, gdy orientacja telefonu zostanie zmieniona, tak aby tło zmieniało się za każdym razem.
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 = "";
}
Mam nadzieję, że to pomoże. Zajęło mi to wiek absolutny, aby wymyślić to wszystko i wiem, że nadal istnieją pewne obszary, które mogę udoskonalić, ale przynajmniej powinienem zacząć.
Jeśli ktoś ma sugestie, jak ulepszyć ten kod, to ja mam uszy.
Czy to zapewnić taką samą listę tapet, które użytkownik widzi na ekranie głównym? To jest to czego chcę. Użytkownik musi mieć możliwość wybrania z systemu tapet i tapet dostarczonych przez inne aplikacje, bez żywych tapet. – DarthNoodles
Umożliwia to przeglądanie każdego obrazu na karcie SD. Jeśli pobierzesz darmowy Droid X Livewallpaper od wabbittdevs, to właśnie to poczujesz. To stąd pochodzi powyższy kod. – Dean
Pobrałem i sprawdziłem. Nie tego chcę. Na ekranie głównym urządzenia naciśnij "menu" i wybierz "tapetę". Oto lista, którą chcę mieć użytkownik, bez animowanych tapet. Na moim urządzeniu otrzymuję na żywo tapety, zdjęcia i tapety HTC. Emulator wyświetla na żywo tapetę, zdjęcia i tapety oraz pozycję "Tapeta" dostarczoną przez próbkę Home. Są to działania, które spełniają intencje ACTION_SET_WALLPAPER. Wygląda na to, że tego, czego chcę, nie można łatwo zrobić za pomocą interfejsu API. – DarthNoodles