Android 为实时壁纸选择背景

Android 为实时壁纸选择背景,android,live-wallpaper,Android,Live Wallpaper,我正在写一张在背景上创造效果的现场壁纸。我希望用户能够从任何系统壁纸和相机照片中选择背景。我希望用户能够按下设置菜单中的一个按钮,显示选项列表,就像从主屏幕设置墙纸一样,减去实时墙纸选项。一旦用户浏览了选择并选择了一个实际的图像,我就会将它加载到我的画布上 我该怎么做 我在任何地方都找不到获取壁纸列表的API 我已经能够列出一个使用意图的壁纸供应商列表。然后,我得到了一份也在使用意图的实时壁纸提供商的列表,并将其从我的第一份列表中删除。给了我一个列表的墙纸供应商,不是活的 现在怎么办?有没有其他

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

我该怎么做

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

我已经能够列出一个使用意图的壁纸供应商列表。然后,我得到了一份也在使用意图的实时壁纸提供商的列表,并将其从我的第一份列表中删除。给了我一个列表的墙纸供应商,不是活的

现在怎么办?有没有其他我没有的方法


请帮助。

我这样做是通过在设置xml中添加一个首选项(我的是flash_setting.xml)

链接到首选项名称并注册侦听器

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(); 
}}
下面的代码是在这个网站上找到的(由PercyPercy在上),我只是为了完整起见才把它包括进来。然而,它确实可以完美地工作

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 = "";
    } 
我希望这有帮助。我花了一个绝对的年龄才想出这一切,我知道还有一些方面我可以改进,但至少它应该让你去


如果有人对如何改进这段代码提出建议,我会洗耳恭听。

不,这几乎是最好的方法。任何响应android.intent.action.SET_墙纸的东西都可能是某种形式的墙纸提供商。问题是,给他们这份清单会让你失去控制。从本质上说,让他们从另一家供应商那里挑选一些东西会让你的生活墙纸不稳定。您可以通过一些创造性的清单设置或一些“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 );
        }
    }
}

这是否提供了用户在主屏幕上看到的相同壁纸列表?这就是我想要的。用户需要能够从系统墙纸和其他应用程序提供的墙纸中进行选择,而无需使用实时墙纸。这可以让您浏览SD卡上的每个图像。如果你下载Wabbitddevs提供的免费Droid X Livewallpaper,这正是你将体验到的。这就是上面代码的来源。我下载并检查了它。那不是我想要的。在设备的主屏幕上,按“菜单”并选择“壁纸”。这是我希望用户拥有的列表,减去实时壁纸。在我的设备上,我可以看到实时壁纸、照片和HTC壁纸。emulator为您提供实时墙纸、照片和墙纸,以及Home示例提供的“墙纸”条目。这些都是满足意向行动的活动。看来,我想要的东西不能很容易地用API来完成。我知道你现在想要什么了。我以前从来没有解决过这样做的必要性,很抱歉,我帮不了你。我需要这样做,我必须说你的回答非常好
@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 );
        }
    }
}