选择背景动态壁纸 [英] Choosing background for Live Wallpaper

查看:325
本文介绍了选择背景动态壁纸的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个动态壁纸,创造了一个背景的效果。我希望用户能够从任何系统壁纸和相机中的照片的选择的背景。我想是让用户能够以preSS在设置菜单的按钮,有选项列表中显示出来,就像从主屏幕设置壁纸,减去动态壁纸的选项。一旦用户浏览的选择和挑选的实际形象我会加载到我的画布。

我如何做到这一点?

我找不到一个API的任何地方获取的壁纸列表。

我已经能够拿出使用意图的墙纸供应商的名单。然后我得到活的壁纸供应商的名单也使用意图和删除那些从我的第一个列表。在给我的壁纸供应商未住的清单。

现在是什么?是否有其他方法可以做到这一点,我很想念?

请帮忙。

解决方案

我通过把一个preference到XML设定,因为这(我的是flash_setting.xml);

 < preference
    机器人:关键=image_custom
    机器人:标题=选择背景
    机器人:总结=选择自定义图像
     />
 

我创建了一个自定义类取获得在preferenceClick监听和监视点击preference为使用户(这是调用mySettings.java)(请注意,getRealPathFromURI程序不矿山和在别处找到了在这里);


您的类应该通过扩展preferenceActivity贯彻共享preference变化监听启动

 公共类flashSettings扩展preferenceActivityimplements共享preferences.OnShared preferenceChangeListener {
 

链接到preference名称并注册该监听器

  @覆盖
保护无效的onCreate(包冰柱){
    super.onCreate(冰柱);
    获得preferenceManager()。setShared preferencesName(
            fingerflashpro.SHARED_ preFS_NAME);
    加preferencesFromResource(R.xml.flash_settings);获得preferenceManager()。getShared preferences()。registerOnShared preferenceChangeListener(
            本);
 

接下来,我们将设置在preference监听器监听image_custom。当它被点击,我们将开始一个新的意图来显示照片选择器。我们从一个StartActivityForResult,所以我们可以将图像从后面的意图的URI。

<$p$p><$c$c>get$p$pferenceManager().find$p$pference("image_custom").setOn$p$pferenceClickListener(new在preferenceClickListener() {     @覆盖     在preferenceClick(preference preference)公共布尔     {         显示显示= getWindowManager()getDefaultDisplay()。         INT宽度= display.getWidth();         INT高= display.getHeight();         Toast.makeText(getBaseContext(),选择图像 - +(宽)+X+高度,Toast.LENGTH_LONG).show();         意图photoPickerIntent =新的意图(Intent.ACTION_PICK);         photoPickerIntent.setType(图像/ *);         startActivityForResult(photoPickerIntent,1);         返回true;     } });}

接下来,我们等待活动返回结果,我们解析的URI一个真实路径。

  @覆盖
公共无效onActivityResult(INT申请code,INT结果code,意图数据){
super.onActivityResult(要求code,因此code,数据);
如果(要求code == 1){
如果(结果code == Activity.RESULT_OK){
  乌里selectedImage = data.getData();
  字符串的真实路径;
  共享preferences customShared preference = getShared preferences(fingerflashpro.SHARED_ preFS_NAME,Context.MODE_PRIVATE);
  共享preferences.Editor编辑= customShared preference.edit();
  真实路径= getRealPathFromURI(selectedImage);
  editor.putString(image_custom,真实路径);
  editor.commit();
}}
 

下面这段code被发现在这个网站(由PercyPercy的<一个href="http://stackoverflow.com/questions/3401579/android-get-filename-and-path-from-uri-from-mediastore">this螺纹),我只包括它的完整性。但它确实,很好地工作。

 公共字符串getRealPathFromURI(URI contentUri){
的String []凸出= {MediaColumns.DATA};
光标光标= managedQuery(contentUri,
        PROJ,//哪些列返回
        空,// WHERE子句;返回哪些行(所有行)
        空,// WHERE子句选择论(无)
        空值); //订单by子句(按名称升序)
INT与Column_Index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
cursor.moveToFirst();
返回cursor.getString(Column_Index中);}
 

请确保我们实现所需的覆盖;

  @覆盖
保护无效onResume(){
    super.onResume();
}

@覆盖
保护无效的onDestroy(){
    获得preferenceManager()。getShared preferences()。
       unregisterOnShared preferenceChangeListener(本);
    super.onDestroy();
}

@覆盖
公共无效onShared preferenceChanged(共享preferences共享preferences,
        字符串键){
}}
 


然后在你的主壁纸服务活动中,你可以从你的共享preferences提取图像的路径。

  @覆盖
    公共无效onShared preferenceChanged(共享preferences preFS,
            字符串键){

        imageBg = prefs.getString(image_custom,坏形象);
            的getBackground();}
 

下面是一个相当粗糙程序来加载图像。我试图把一些错误捕获以防万一文件被删除,重命名或SD卡被安装(因此你失去了你的形象)。我也试图把一些原油检查设备的方向。我敢肯定,你可以做的更好。

此外,还有一些采样大小检查,这样你就不能超过VM预算。这是这个code至prevent力关闭中最重要的组成部分,绝对应该被包括在内。

我还打电话的时候,手机的方向改变这个程序使背景得到每一次调整。

 无效的getBackground(){
        如果(this.cvwidth == 0 || this.cvheight == 0 || this.visibleWidth == 0){
               this.cvwidth = 480;
               this.cvheight = 854;
               this.visibleWidth = 480;}
        如果(新文件(imageBg).exists()){
                INT的采样大小= 1;
             做 {
                 BitmapFactory.Options选项=新BitmapFactory.Options();
                 options.inJustDe codeBounds = TRUE;
                 BG = BitmapFactory.de codeFILE(imageBg,期权);
                采样大小=(INT)(Math.ceil(options.outWidth /(this.visibleWidth * 2))* 2);
                options.inJustDe codeBounds = FALSE;
                 尝试{options.inSampleSize =采样大小;
                     BG = BitmapFactory.de codeFILE(imageBg,选件);}
                    赶上(OutOfMemoryError异常E){
                        采样大小=采样大小* 2;
                        }
                }而(BG == NULL);

           BG = Bitmap.createScaledBitmap(BG,this.cvwidth / 2,this.cvheight,真正的);}
        其他{BG = BitmapFactory.de codeResource(getResources(),R.drawable.bg);
            BG = Bitmap.createScaledBitmap(BG,this.cvwidth / 2,this.cvheight,真正的);}
        LoadText =;
    }
 

我希望这有助于。我花了一个绝对的时代来了这一切,我知道还有一些领域我可以改进,但至少它应该让你去。

如果任何人有使这code更好,然后我洗耳恭听建议。

I'm writing a live wallpaper that creates an effect over a background. I want the user to be able to choose the background from any of the system wallpapers and camera photos. What I would like is for the user to be able to press a button in the Settings menu, have the list of options show up just like setting the wallpaper from the home screen, minus the Live Wallpapers options. Once the user navigates the choices and picks an actually image I would load it to my canvas.

How do I do this?

I can't find an API anywhere for getting a list of wallpapers.

I've been able to come up with a list of wallpaper providers using Intents. I then get a list of live wallpaper providers also using Intents and remove those from my first list. The gives me a list of wallpaper providers that are not live.

Now what? Are there other ways to do this that I'm missing?

Please help.

解决方案

I do this by putting a preference into the Settings xml as this (mine is flash_setting.xml);

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

I created a custom class to take the get the OnPreferenceClick Listener and watch for the user clicking the preference as so (this is call mySettings.java) (please note that the getRealPathFromURI routine isn't mine and was found elsewhere on here);


Your class should start by extending the PreferenceActivity and implementing the Sharedpreference change listener

public class flashSettings extends PreferenceActivityimplements SharedPreferences.OnSharedPreferenceChangeListener {    

Link to the preference name and register the 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);

Next we will set the on preference listener to listen for 'image_custom'. When it is clicked we will start a new intent to display the photo picker. We start with a StartActivityForResult so we can get the URI of the image back from the intent.

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

Next we wait for the activity to return the result and we parse the URI to a real path.

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

The following piece of code was found on this site (by PercyPercy on this thread)and I'm only including it for completeness. It does however, work perfectly.

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

Make sure we implement the required Overrides;

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

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

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


Then in your main wallpaper service activity you can extract the Path of the image from your shared preferences.

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

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

Here is a fairly crude routine to load the image. I've attempted to put in some error trapping just in case the file is deleted, renamed or the SD card gets mounted (hence you lose your image). I've also attempted to put in some crude checks for the device orientation. I'm sure you can do better.

There also some Samplesize checking so you don't exceed the VM budget. This is the most important part of this code to prevent force closes and should definitely be included.

I also call this routine when the orientation of the phone is changed so that the background gets resized each time.

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

I hope this helps. It took me an absolute age to come up with all of this and I know there are still some areas I can refine but at least it should get you going.

If anyone has suggestions on making this code better then I'm all ears.

这篇关于选择背景动态壁纸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆