2010-09-09 37 views
5

Tôi đang viết hình nền động tạo hiệu ứng trên nền. Tôi muốn người dùng có thể chọn nền từ bất kỳ hình nền hệ thống và ảnh máy ảnh nào. Những gì tôi muốn là để người dùng có thể nhấn một nút trong menu Cài đặt, có danh sách các tùy chọn hiển thị giống như cài đặt hình nền từ màn hình chính, trừ các tùy chọn Hình nền động. Khi người dùng điều hướng các lựa chọn và chọn một hình ảnh thực sự tôi sẽ tải nó vào khung hình của tôi.Chọn nền cho Hình nền động

Làm cách nào để thực hiện việc này?

Tôi không thể tìm thấy API ở bất kỳ đâu để nhận danh sách hình nền.

Tôi đã có thể đưa ra danh sách nhà cung cấp hình nền sử dụng Mục đích. Sau đó tôi nhận được một danh sách các nhà cung cấp hình nền sống cũng sử dụng Intent và loại bỏ những người từ danh sách đầu tiên của tôi. Việc cung cấp cho tôi danh sách các nhà cung cấp hình nền không hoạt động.

Bây giờ làm gì? Có cách nào khác để làm điều này mà tôi đang thiếu?

Vui lòng trợ giúp.

Trả lời

25

Tôi làm điều này bằng cách đặt tùy chọn vào Cài đặt xml như thế này (tôi là flash_setting.xml);

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

Tôi tạo ra một lớp tùy chỉnh để lấy được những OnPreferenceClick Listener và xem cho người sử dụng nhấn vào sở thích như vậy (đây là cuộc gọi mySettings.java) (xin lưu ý rằng thói quen getRealPathFromURI không phải của tôi và là tìm thấy ở nơi khác trên đây);


lớp học của bạn nên bắt đầu bằng cách mở rộng PreferenceActivity và thực hiện sự thay đổi người nghe Sharedpreference

public class flashSettings extends PreferenceActivityimplements SharedPreferences.OnSharedPreferenceChangeListener {  

Liên kết với các tên sở thích và đăng ký listener

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

Tiếp theo chúng ta sẽ thiết lập trên người nghe tùy chọn để nghe 'image_custom'. Khi nó được nhấp, chúng tôi sẽ bắt đầu một ý định mới để hiển thị bộ chọn ảnh. Chúng ta bắt đầu với một StartActivityForResult để chúng ta có thể lấy lại URI của hình ảnh từ mục đích.

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; 
    } 
});} 

Tiếp theo chúng tôi đợi hoạt động trả lại kết quả và chúng tôi phân tích URI thành đường dẫn thực.

@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(); 
}} 

Các đoạn mã sau đây đã được tìm thấy trên trang web này (bằng cách PercyPercy trên this thread) và tôi chỉ bao gồm nó cho đầy đủ. Tuy nhiên, nó hoạt động hoàn hảo.

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);} 

Đảm bảo chúng tôi triển khai Phần ghi đè bắt buộc;

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

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

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

Sau đó, trong hoạt động dịch vụ giấy dán tường chính của bạn, bạn có thể trích xuất các đường dẫn của hình ảnh từ sở thích chia sẻ của bạn.

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

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

Đây là một thói quen khá thô sơ để tải hình ảnh.Tôi đã cố gắng để đặt trong một số lỗi bẫy chỉ trong trường hợp tập tin bị xóa, đổi tên hoặc thẻ SD được gắn kết (do đó bạn bị mất hình ảnh của bạn). Tôi cũng đã cố gắng để đưa vào một số kiểm tra thô cho định hướng thiết bị. Tôi chắc rằng bạn có thể làm tốt hơn.

Cũng có một số kiểm tra mẫu để bạn không vượt quá ngân sách VM. Đây là phần quan trọng nhất của mã này để ngăn chặn lực đóng và chắc chắn nên được bao gồm.

Tôi cũng gọi thường trình này khi hướng của điện thoại được thay đổi sao cho nền được thay đổi kích cỡ mỗi lần.

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 = ""; 
    } 

Tôi hy vọng điều này sẽ hữu ích. Nó đã cho tôi một tuổi tuyệt đối để đi lên với tất cả những điều này và tôi biết vẫn còn một số khu vực tôi có thể tinh chỉnh nhưng ít nhất nó sẽ giúp bạn đi.

Nếu có ai có đề xuất làm cho mã này tốt hơn thì tôi là tất cả tai.

+0

Điều này cung cấp cùng một danh sách các hình nền mà người dùng thấy từ màn hình chủ? Đó là thứ mà tôi muốn. Người dùng cần có thể chọn từ hình nền hệ thống và hình nền do các ứng dụng khác cung cấp mà không có hình nền động. – DarthNoodles

+0

Điều này cho phép bạn duyệt mọi hình ảnh trên thẻ SD của bạn. Nếu bạn tải xuống miễn phí Droid X Livewallpaper bởi wabbittdevs, đây chính xác là những gì bạn sẽ trải nghiệm. Đó là nơi mã ở trên được lấy từ. – Dean

+0

Tôi đã tải xuống và kiểm tra. Đó không phải là điều tôi muốn. Ở màn hình chính trên thiết bị của bạn, bấm 'menu' và chọn 'hình nền'. Đây là danh sách mà tôi muốn người dùng có, trừ Hình nền động. Trên thiết bị của tôi, tôi có Live Wallpaper, Photos và HTC Wallpapers. Trình giả lập cung cấp cho bạn Hình nền động, Ảnh và Hình nền, cùng với mục nhập "Hình nền" do mẫu Nhà cung cấp. Đây là những hoạt động thỏa mãn ý định ACTION_SET_WALLPAPER. Có vẻ như những gì tôi muốn không thể dễ dàng được thực hiện với API như nó được. – DarthNoodles

0

Không, đó là cách tốt nhất để thực hiện. Mọi thứ phản hồi android.intent.action.SET_WALLPAPER sẽ là nhà cung cấp hình nền có dạng này hoặc dạng khác. Vấn đề là cung cấp cho họ danh sách đó sẽ kiểm soát của bạn ra khỏi phương trình. Về cơ bản có họ chọn một cái gì đó từ nhà cung cấp khác sẽ bỏ đặt Live Wallpaper của bạn. Bạn có thể có thể nhận được xung quanh điều này với một số cài đặt Manifest sáng tạo và hoặc một số cuộc gọi loại "startActivityForResult".

Sau khi họ chọn một cái gì đó dù đó là một vấn đề đơn giản của một cái gì đó như thế này trong WallpaperService.Engine của bạn:

@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); 
     } 
    } 
}