【问题标题】:Passing an image between two apps在两个应用程序之间传递图像
【发布时间】:2018-05-07 11:55:26
【问题描述】:

我有两个应用程序,应用程序 A 和应用程序 B。当我按下应用程序 A 中的按钮时,将调用应用程序 B。在应用程序 B 中,它具有相机活动和其他一些图像处理选项,例如裁剪、调整亮度和对比度。图像处理后,我需要将图像传递给 App A。但是,图像不应该保存在 sd 卡中。

我尝试了什么:使用图像到 base64 字符串

第 1 步:我使用此代码调用了 AppB

Intent i = new 
Intent("com.appb.ImageProcessingActivity");
            startActivityForResult(i, 100);

Step2: 在 App B 中,经过图像处理,我将图像转换为 base64 字符串并使用此代码将其发送回 App A。 (图像处理后,图像大小将

Intent data = new Intent();
data.putExtra("outputImage", base64ImageString);
setResult(RESULT_OK, data);
finish();

Step3:在App A中,我将使用此代码获取图像详细信息

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode==100 && resultCode==RESULT_OK){

        String outputImage = data.getStringExtra("base64ImageString");
        byte[] decodedString = Base64.decode(outputImage, Base64.DEFAULT);
        Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
        imageView.setImageBitmap(decodedByte);

    }
}

但我无法从 App B 到 App A 接收 base64 字符串。它显示以下错误(注意:我可以使用此方法发送普通字符串)

JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 1058260)

不接受此答案

在App B中,将图片保存在sd卡中并将图片路径发送给App B,然后在App A中将图片路径转换为base64,然后删除sd卡图片。

【问题讨论】:

  • 去掉base64的东西,发回照片JPEG的byte[]。这仍然需要相当小,但它自然会比 JPEG 的 base64 编码小得多。
  • 同意@CommonsWare 观点。请试一试。
  • 感谢您的回复。我也试过 byte[] 。但是,我仍然面临同样的问题。 ByteArrayOutputStream 流 = 新的 ByteArrayOutputStream(); outputBitmap.compress(Bitmap.CompressFormat.PNG, 100, 流); byte[] food = stream.toByteArray();
  • 如果您想在某些应用程序之间进行交换并且不想将图像存储在光盘上,ContentProvider 可能会有所帮助:stackoverflow.com/questions/29700680/…

标签: android android-intent


【解决方案1】:

首先,它们被称为活动而不是“应用程序”。

其次,您收到了该错误,因为图像太大而无法在这样的活动之间传递。如果您仔细查看 logcat,您可能会在“TransactionTooLargeException”的某个地方发现此错误。

为了避免这种情况并使您的应用程序运行得更快,您应该将图像保存为外部缓存目录中的文件,并将其路径传递给第二个活动,然后加载它。并且不要担心图像将只是暂时保存,因为它在缓存目录中。

【讨论】:

  • 嗨。它们只是两个不同的独立应用程序。
  • 谢谢,我试试这个
  • 嗯我的错误。无论如何,我推荐我的方法,因为我遇到了与您类似的问题,并且通过应用此方法,您将考虑任何设备拍摄的任何图像大小。希望对你有帮助
【解决方案2】:

试试这个代码:

在活动中添加这一行 onActivityResult()

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
String str = data.getStringExtra("image");
filePath = Uri.parse(str);
}

使用 getIntent() 尝试在 onActivityResult() 中使用 data.getStringExtra()

对你有帮助

【讨论】:

  • AppB 本身发生错误。我不能回到 AppA
  • 这是 logcat 中的错误。 JavaBinder:!!! Binder 交易失败!!! (包裹大小=1058260)
  • 当在 putExtra 中添加 base64 字符串时。例如,data.putExtra("outputImage", base64ImageString); .如果我输入普通字符串,那么它工作正常。
  • 等我检查一下
  • 当然。请检查
【解决方案3】:

从 Android 2 开始,每个应用程序都有足够的 RAM 来存储一张相机图像,而不足以存储两张相机图像。我认为这是不可能的,但是您可以在清单中尝试android:largeHeap="true",但是我认为它也不会起作用。

好吧,作为最后的手段,您可能会创建一个服务(在您的一个应用程序中,可能在一个单独的进程中)并向该服务发送图像字节或从该服务发送图像字节。但你确定这值得麻烦吗?问题是系统可能决定终止在堆中有相机图像的两个应用程序之一。

或者,您可能可以创建一个 ContentProvider 并将您的图像存储在那里。谷歌给了我像Share an image with a content provider in Android app这样的页面

还有一个非常疯狂的想法:将图像分割成可以通过 Intent 传递的大小的片段,然后将其传递给多个 Intent :)

【讨论】:

  • largeHeap 属性是否会增加最大值?捆绑大小也一样?本主题与堆内存问题无关。
  • android:largeHeap="true" 对我没有帮助
  • ContentProvider 帮不了我,因为我只需要通过意图调用应用 B
【解决方案4】:
Bundle extras = new Bundle();
extras.putParcelable("Bitmap", bmp);
intent.putExtras(extras);
startActivity(intent);

发送申请-

Button sendImage = (Button) findViewById(R.id.button2);
        sendImage.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(
                        Intent.createChooser(intent, "Select Picture"),
                        SELECT_PICTURE);
            }
        });

    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            if (requestCode == SELECT_PICTURE) {
                Uri selectedImageUri = data.getData();
                selectedImagePath = getPath(selectedImageUri);
                System.out.println("Image Path : " + selectedImagePath);
                img.setImageURI(selectedImageUri);
                sendImage(selectedImageUri);
            }
        }
    }

    void sendImage(Uri selectedImageUri) {
        Intent shareIntent = new Intent();
        shareIntent.setAction(Intent.ACTION_SEND);
        shareIntent.putExtra(Intent.EXTRA_STREAM, selectedImageUri);
        shareIntent.setType("image/*");
        startActivity(Intent.createChooser(shareIntent, "Send Image"));
    }

    public String getPath(Uri uri) {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = managedQuery(uri, projection, null, null, null);
        int column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

收到申请

private Bitmap bitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        LinearLayout linearlyt = new LinearLayout(this);

        Intent intent = getIntent();
        String action = intent.getAction();
        String type = intent.getType();
        TextView tv = new TextView(this);
        linearlyt .addView(tv);
        linearlyt .setOrientation(LinearLayout.VERTICAL);
        if (Intent.ACTION_SEND.equals(action) && type != null) {
            if ("text/plain".equals(type)) {

                tv.setText(intent.getExtras().getString(Intent.EXTRA_TEXT));
                tv.append("\n" + (intent.getExtras().getString("MyKey")));

            } else if (type.startsWith("image/")) {
                if (bitmap != null) {
                    bitmap.recycle();
                }
                ImageView img = new ImageView(this);
                Bundle bundle = intent.getExtras();
                Uri uri = (Uri) bundle.get(Intent.EXTRA_STREAM);
                img.setImageURI(uri);
                linearlyt .addView(img);
        }

        } else {
            // Handle other intents, such as being started from the home screen
        }
        setContentView(linearlyt);
    }

【讨论】:

  • 感谢您的努力。 AppA 和 AppB 是两个独立的应用程序。所以,我使用了 startActivityForResult,而不是 startActivity。你能确认你的答案@Dhanshri
  • 无论如何,我试过这个,这段代码可能适用于两个活动之间。但是,它不适用于两个应用程序之间
  • 我尝试将图像发送到其他应用程序。请检查一次@Vignes
  • 你传递的是图片URI,URI图片实际上只存储在sd卡中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-11
  • 1970-01-01
  • 2012-02-12
  • 1970-01-01
  • 2011-12-21
相关资源
最近更新 更多