2

I need some help here. I want to add a new feature to my app. I have a page that displays some text and I have a share button with it. Now the user can share this text with anyone, So what I want is that the user can share this text as an Image, So Instead of sharing this just like a text, I will add this new feature to also can share it as an Image.

Now I already created the Image that will include this text to be shared, What I need to do is, When the user clicks on the share button, it is should send this text to the Image a Put it into it "It will be empty and the text will be like drawing on it. And after the text adds to the Image, The user can send this image with the text.

I made some searches on Google and I found some people who say you can add Textview into the ImageView and send this text with Intent then display the text in the Textview and then share it. But of course, this will not work because the text didn't actually add to the Image and It is just a view, so the Image will share as it is "Empty".

Any suggestions for how can I make something like that?

enter image description here

Moataz
  • 495
  • 3
  • 20

3 Answers3

3

You can make use of DrawingCache. Put your image and text inside a wrapper like FrameLayout/RelativeLayout/etc and use its drawing cache to save it as a bitmap;

View view = findViewById(R.id.flWrapper);
view.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(flUser.getDrawingCache());
view.setDrawingCacheEnabled(false);

// if you want to save it to a file
File image = new File("/path/to/your/file.jpg");
try (FileOutputStream outputStream = new FileOutputStream(image)) {
    
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
    outputStream.flush();

} catch (FileNotFoundException e) {
    e.printStackTrace();
    // handle it
} catch (IOException e) {
    e.printStackTrace();
    // handle it
}

// or share the bitmap as you like
ddassa
  • 309
  • 1
  • 6
2

Wrap your image and text into a relative layout or constraint layout or a frame layout, take a screenshot of that relative or constraint or frame layout, and share it, use This Library to take a screen shot of your view.

here is some code for you

Bitmap bitmap = ScreenShott.getInstance().takeScreenShotOfJustView(yourview);
File sharedFile = FileUtility.shareImageFile(bitmap);
if (sharedFile != null) {
    Uri uri = FileProvider.getUriForFile(context, context.getPackageName().concat(".provider"), sharedFile);

    Intent intent = new ShareCompat.IntentBuilder(context)
       .setType(context.getContentResolver().getType(uri))
       .setStream(uri)
       .getIntent();
       intent.setAction(Intent.ACTION_SEND);
       intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
       intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
       startActivity(Intent.createChooser(intent, "share"));
}

FileUtility shareImageFile method

    public static File shareImageFile(Bitmap bitmap) {
    String rootDirectory = ResourceProvider.get().getContext().getExternalCacheDir() + File.separator + Environment.DIRECTORY_PICTURES + File.separator;
    File rootFile = new File(rootDirectory);
    if (!rootFile.exists()) {
        boolean make = rootFile.mkdirs();
        Log.d(TAG, "shareImageFileMakeStatus: " + make);
    }

    String imagePath = rootDirectory.concat("image_").concat(currentDate()).concat(".png");
    try {
        FileOutputStream fos = new FileOutputStream(imagePath);
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
        fos.flush();
        fos.close();
        return new File(imagePath);
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

I use external cashe dir because there is no need to get storage permission from user for this path.

file provider that you must add xml folder in your res and create a .xml file for file provider
res/xml/provide_paths.xml

<?xml version="1.0" encoding="utf-8"?>
    <paths>
        <external-path
            name="external_files"
            path="." />
    </paths>

add this provider in your manifest.xml

        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>
OneDev
  • 557
  • 3
  • 14
1

There are 3 steps to this .

  1. Create the view you want to send

  2. Convert the view to Bitmap

  3. Send it via an intent after saving it in your app or use it for your imageview

  4. Create the view you wanto to send

So create a constraint layout which has that textview which is populated by the text you want to give it from the previous activity via a `intent.getExtra("text")

Have the images and other data in the *same constraint layout which you want to send. Once yo're satisfied with how the view/viewgroup aka the constraint layout looks. we are ready to convert that to bitmap

2.Convert the viewgroup to Bitmap

v.measure(MeasureSpec.makeMeasureSpec(v.getLayoutParams().width, MeasureSpec.EXACTLY),
        MeasureSpec.makeMeasureSpec(v.getLayoutParams().height, MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());

Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.RGB_565);
Canvas c = new Canvas(b);
v.draw(c);

where v is the viewgroup you want to convert to bitmap

Viewgroup to Bitmap Stackoverflow

3.Send that bitmap as an intent

 String pathofBmp = Images.Media.insertImage(getContentResolver(), bitmap,"title", null);
    Uri bmpUri = Uri.parse(pathofBmp);
    final Intent emailIntent1 = new Intent(     android.content.Intent.ACTION_SEND);
    emailIntent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    emailIntent1.putExtra(Intent.EXTRA_STREAM, bmpUri);
    emailIntent1.setType("image/png");

and for imageview it's as simple as imageview.setSrc(bitmap)

Share Bitmap via Android Stackoverllow answer

Narendra_Nath
  • 4,578
  • 3
  • 13
  • 31