代码之家  ›  专栏  ›  技术社区  ›  DarthNoodles

为现场壁纸选择背景

  •  5
  • DarthNoodles  · 技术社区  · 14 年前

    我在写一张在背景上创造效果的现场壁纸。我希望用户能够选择从任何系统壁纸和相机照片的背景。我想让用户能够按下设置菜单中的一个按钮,显示选项列表,就像从主屏幕设置壁纸一样,减去实时壁纸选项。一旦用户浏览了这些选择并选择了一个实际的图像,我就会将它加载到我的画布上。

    我在任何地方都找不到获取墙纸列表的API。

    现在怎么办?有没有其他方法让我错过了呢?

    请帮忙。

    2 回复  |  直到 14 年前
        1
  •  25
  •   Community CDub    8 年前

    为此,我将一个首选项放入设置xml中,如下所示(我的首选项是flash_设置.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\u custom”。单击它时,我们将启动一个新的意图来显示照片选择器。我们从StartActivityForResult开始,这样就可以从intent中获取图像的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(); 
    }}
    

    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卡挂载(因此你失去你的形象)。我还尝试对设备的方向进行一些粗略的检查。我相信你能做得更好。

    当手机的方向改变时,我也会调用这个例程,以便每次调整背景的大小。

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

    我希望这有帮助。我花了我一个绝对的年龄来想出这一切,我知道还有一些领域,我可以完善,但至少它应该让你去。

    如果有人对改进这段代码有什么建议的话,我洗耳恭听。

        2
  •  0
  •   Justin Buser    12 年前

    不,这是最好的办法。任何有反应的东西android.intent.action操作.SET\u墙纸将是一种或另一种形式的墙纸提供商。问题是给他们这个列表会让你失去控制。从本质上说,让他们从另一个供应商选择的东西将取消你的生活壁纸。您可能可以通过一些创造性的清单设置或一些“startActivityForResult”类型调用来解决这个问题。

    在他们选择了某样东西之后,尽管在你的生活中这样的事情很简单服务。引擎:

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