【问题标题】:Intent for selecting wallpaper with wallpaper region highlighting用于选择具有突出显示壁纸区域的壁纸的意图
【发布时间】:2012-02-08 05:29:26
【问题描述】:

我想知道是否可以创建一个 Intent 使图库裁剪器显示壁纸突出显示。此功能已在 Honeycomb 中引入。要了解我要查找的内容,请查看图片上的平板电脑(三个蓝色矩形)。

我查看了 ICS 图库应用的source code,但找不到我要找的东西。

【问题讨论】:

    标签: android android-intent android-gallery


    【解决方案1】:

    我想知道是否可以创建一个 Intent 使 图库裁剪器显示壁纸突出显示。

    假设您希望您的应用在所有 Android 设备上都能正常运行,答案是否定的。裁剪活动和突出显示的裁剪视图都不是公共 API 的一部分;两者都在 Gallery 3D 应用程序内部。换句话说,您可以在世界上花费所有时间尝试找到Intent 操作以使其神奇地为您工作,但事实是某些设备根本不支持它。例如,许多设备,如 HTC Sense 和三星 Galaxy,都有定制的 Android 版本,它们有自己的画廊应用程序。由于这些图库应用程序特定于设计它们的公司,因此这些设备不一定有 CropImage 类供您启动。

    话虽如此,为了保证您的应用程序可以在所有设备上运行,您必须将裁剪代码直接合并到您的项目中。如果由于某种原因你找到了一种使用 Intent 启动裁剪活动的方法,你应该至少测试一下 com.android.gallery3d 包是否存在,并以某种方式处理它。

    我在下面提供了一个解决方法,它可以帮助您将 Android 代码合并到您的项目中。我目前无法访问运行 Honeycomb/ICS 的平板电脑,因此我无法更具体地说明如何让它在较新版本的 Android 上运行,但我想它涉及类似的分析和一些复制和粘贴来自com.android.gallery3d 包。


    在 Android 2.x 上重用“Crop Activity”

    我在我的 Nexus One 上对此进行了测试,就在弹出软“裁剪矩形”之前,我得到了以下 logcat 输出:

    I/ActivityManager(   94): Starting: Intent { 
        act=android.intent.action.CHOOSER 
        cmp=android/com.android.internal.app.ChooserActivity (has extras) } from pid 558
    I/ActivityManager(   94): Starting: Intent { 
        act=android.intent.action.ATTACH_DATA 
        dat=content://media/external/images/media/648 
        typ=image/jpeg 
        flg=0x3000001 
        cmp=com.google.android.gallery3d/com.cooliris.media.Photographs (has extras) } from pid 558
    I/ActivityManager(   94): Starting: Intent { 
        dat=content://media/external/images/media/648 
        cmp=com.google.android.gallery3d/com.cooliris.media.CropImage (has extras) } from pid 558
    

    所以据我所知,执行此操作时发生的事件顺序如下:

    1. 您导航到图库中的图像并选择“设置为...”。弹出ActivityChooser,然后选择“壁纸”。
    2. 这个选择会触发一个Intent,动作ATTACH_DATA和组件com.cooliris.media.Photographs,这是Android框架中的一个类,用作相机应用程序的“壁纸选择器”;它只是重定向到标准选择动作。由于我们给Intent一个URI指定了设置为壁纸的图片,这个类不可避免地会执行下面的代码(见类的onResume方法):

      Intent intent = new Intent();   
      intent.setClass(this, CropImage.class);
      intent.setData(imageToUse);
      formatIntent(intent);
      startActivityForResult(intent, CROP_DONE);
      
    3. 这会触发另一个Intent 来启动CropImage 活动...这是您使用软矩形指定裁剪区域的地方。当您指定裁剪时,结果将设置为RESULT_OKrequestCode = CROP_DONEPhotographs Activity 切换这两个常量,然后相应地设置壁纸(参见Photographs 类的onActivityResult 方法)。

    不幸的是,无论出于何种原因,Android 团队决定从 API 4 (Android v1.6) 开始从 SDK 中删除这些功能...因此,如果您想触发 Intent 来执行这些确切的事件序列,它需要您筛选com.cooliris.media 包,并将相关类复制并粘贴到您的项目中。以我过去的经验,这样做往往比它的价值更麻烦(除非它是执行一个相对简单的动作),但它绝对是可能的。

    这里有一个nice tutorial,关于如何简化流程...它要求您将12 Java classes 复制并粘贴到您的项目中,而不是整个com.cooliris.media 包。这些类一起应该足以正确启动CropImage Activity,但是您必须根据CropImage Activity 的结果手动设置墙纸。

    另请注意,提供的示例代码假定您希望在相机拍摄照片后立即进行裁剪。例如,为了使用从图库中预先选择的图像启动CropImage Activity,您可以调用,

    Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(i, ACTIVITY_SELECT_IMAGE);
    

    然后在onActivityResult 中(如果requestCode == ACTIVITY_SELECT_IMAGEresultCode == RESULT_OK),使用onActivityResult 的第三个参数中给出的Uri 数据启动CropImage 活动(有关示例,请参见示例代码如何启动活动)。

    如果有的话,希望这能帮助您指明正确的方向。如果您想让我澄清任何事情,请告诉我进展情况并发表评论。

    【讨论】:

    • Alex,“不错的教程”的链接已失效。你能更新一下吗?谢谢。
    【解决方案2】:

    这会有所帮助:

    public class CropSelectedImageActivity extends Activity {
    
        @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
                photoPickerIntent.setType("image/*");
                startActivityForResult(photoPickerIntent, 1);
    }
    
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
                super.onActivityResult(requestCode, resultCode, data);
                if (resultCode == RESULT_OK) {
                        final Bundle extras = data.getExtras();
                        Uri photoUri = data.getData();
                        if (photoUri != null) {
                                Intent intent = new Intent("com.android.camera.action.CROP");
                        //intent.setClassName("com.android.camera", "com.android.camera.CropImage");
    
                        intent.setData(photoUri);
                        intent.putExtra("outputX", 96);
                        intent.putExtra("outputY", 96);
                        intent.putExtra("aspectX", 1);
                        intent.putExtra("aspectY", 1);
                        intent.putExtra("scale", true);
                        intent.putExtra("return-data", true);            
                        startActivityForResult(intent, 1);
                        }
                }
        }
    }
    

    取自:ImageCropper

    【讨论】:

      【解决方案3】:

      我没试过,但如果你看看here

               Bundle newExtras = new Bundle();
               // maybe that here - for more options see your source code link
               newExtras.putString("circleCrop", "true");
               Intent cropIntent = new Intent();
               // Uri would be something from MediaStore.Images.Media.EXTERNAL_CONTENT_URI
               cropIntent.setData(img.fullSizeImageUri());
               // edit: it's inside com.android.gallery in case that is even installed.
               // should work if you replace that with setClassName("com.android.gallery", "com.android.camera.CropImage")
               cropIntent.setClass(this, CropImage.class);
               cropIntent.putExtras(newExtras);
               startActivityForResult(cropIntent, CROP_MSG);
      

      那么这可能对你有用。

      可能通过选择意图:

      Intent i = new Intent(Intent.ACTION_PICK);
      i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
      startActivity(i);
      

      【讨论】:

      • 使用cropIntent.setClassName("com.android.camera", "com.android.camera.CropImage"); 时,我得到一个ActivityNotFoundException。此外,我一直在寻找对正常图像拾取意图 (Intent.ACTION_PICK) 的改编,尽管我现在意识到问题在这方面并不清楚。
      • 您找到的代码来自“图库”应用。还有一个“Gallery2”和来自 Google 的封闭源代码版本。所以也许这完全是我们正在查看的错误源代码。此外,据我所知,它应该是cropIntent.setClassName("com.android.gallery", "com.android.camera.CropImage")。对于Intent.ACTION_PICK,请参阅更新的答案。未经测试,但它可能会起作用。
      【解决方案4】:

      就这样做吧!

      Intent intent = new Intent(Intent.ACTION_ATTACH_DATA).setDataAndType(contentUri,  "image/jpeg")
          .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
          .putExtra("mimeType", "image/jpeg");
      startActivity(Intent.createChooser(intent, getString(R.string.set_as)));
      

      其中“image/jpeg”是图像 mimeType, contentUri 是图片的uri

      【讨论】:

        【解决方案5】:

        有一个不错的库,它基于 ICS 的裁剪屏幕(来自图库应用)here

        您可以根据需要对其进行修改,以选择要裁剪的部分。

        代码基于 Android 的 Gallery 应用程序(链接 here),位于 "/com/android/camera/gallery" 下,而最重要的类是 "/com/android/camera/" 中的 "CropImage" 。即使库丢失(Google 的代码始终可用),它也可供所有人使用,如下所示:

        git clone https://android.googlesource.com/platform/packages/apps/Gallery3D/
        

        (即使这个不可用,我相信还会有其他的)

        相对于其他解决方案的优势:

        • 独立
        • 可定制
        • 由于 ROM 中的更改而无法崩溃。其他解决方案假定存在确切的类和应用。
        • 开源。
        • 真正的实现,而不是启动另一个应用的意图。
        • 强烈不推荐其他解决方案,只是因为使用了非官方意图,如here 所写。这是由 StackOverflow 知名用户“CommonsWare”撰写的,他是一位非常受人尊敬的用户,您可以在许多与 Android 相关的主题中依靠他。

        同样,最推荐的裁剪图像仍然是第三方库。不使用意图的变通方法。

        【讨论】:

        • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
        • @chr 有时候,因为代码太大太复杂,还有除了Java以外的其他类型的文件,这里不可能贴出来,最好提供一个真实的github链接。该代码是开源的,基于Android的代码。这里的其他解决方案,即使它们很短,也很危险,因为它们对设备上的现有应用程序有假设。如果设备没有它们,则不允许裁剪。这里的解决方案实际上在可能不存在的应用程序上实现了。他们甚至没有检查它是否存在,所以应用程序可能会崩溃。
        • @chr 因此,在可能崩溃且根本无法定制的东西与可以工作、开源并基于 Google 代码的东西之间,我认为我的解决方案更好。也许如果 StackOverflow 允许我上传一个完整的项目,我会,但我不能
        【解决方案6】:

        试试这个

            // Set Home wallpaper the image
        public void setHomeWallpaper () {
                        BitmapDrawable bitmapDrawable = ((BitmapDrawable) imageView.getDrawable());
                        Bitmap bitmap = bitmapDrawable.getBitmap();
                        String bitmapPath = Images.Media.insertImage(getContentResolver(), bitmap, "", null);
                        Uri bitmapUri = Uri.parse(bitmapPath);
                        Intent intent = new Intent(Intent.ACTION_ATTACH_DATA).setDataAndType(bitmapUri,  "image/jpeg")
                                .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                                .putExtra("mimeType", "image/jpeg");
                        startActivity(Intent.createChooser(intent, getString(R.string.background)));
                        Toast.makeText(PicassoDisplayImageAdapter.this, "قم بإختيار التطبيق المناسب لتعيين الصورة", Toast.LENGTH_SHORT).show();
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-07-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多