8

I've seen the following Link and it does take a screenshot with the top answer

However, what I want is for the app to take a screenshot of the Alert Dialog that I am displaying to the user, the above solution and below code only takes a screenshot of what is currently behind the alert dialog and therefore no good

Here is the code being used in case anyone hasn't gone through the link provided

Date now = new Date();
    android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);

    try {
        // image naming and path  to include sd card  appending name you choose for file
        String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg";

        // create bitmap screen capture
        View v1 = getWindow().getDecorView().getRootView();
        v1.setDrawingCacheEnabled(true);
        Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
        v1.setDrawingCacheEnabled(false);

        File imageFile = new File(mPath);

        FileOutputStream outputStream = new FileOutputStream(imageFile);
        int quality = 100;
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
        outputStream.flush();
        outputStream.close();

        openScreenshot(imageFile);
    } catch (Throwable e) {
        // Several error may come out with file handling or OOM
        e.printStackTrace();
    }

EDIT: code for dialog as requested

public void showCalc(String title, String message) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setCancelable(true);
    builder.setTitle(title);
    builder.setMessage(message);
    builder.setPositiveButton("Capture + Open",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    //Remove Values From Inventory
                    captureScreenAndOpen();

                }
            });

    builder.setNegativeButton("Capture",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    captureScreen();
                    Context context = getApplicationContext();
                    Toast.makeText(context, "Screenshot Captured", Toast.LENGTH_LONG).show();
                }
            });

    builder.setNeutralButton("Return", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
        }
    });
    builder.show();
}

FURTHER EDIT:

Here you will see two screenshots, the first is showing the saved screenshot when everything is saved in the screenshot from the dialog, you'll notice at the bottom there is a bit of text which is always present at the bottom.

Screenshot1

The second screenshot is where there is so much text in the dialog the dialog is scrollable so that you can see all the data, you'll notice that the bottom string in the first screenshot is not present

Screenshot2

If possible I'd like it that all the data is displayed, I'm not sure though if a screenshot function would be able to do this or an alternative method

Community
  • 1
  • 1
Sjharrison
  • 729
  • 3
  • 16
  • 39

3 Answers3

8

Developed on Android 5 emulator and its working. Took Your dialog code and screenshot code from the link you have provided.

This is your AlertDialog

public void showCalc(String title, String message) {
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setCancelable(true);
    builder.setTitle(title);
    builder.setMessage(message);
    builder.setPositiveButton("Capture + Open",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    //Remove Values From Inventory
                    captureScreenAndOpen();
                }
            });

    builder.setNegativeButton("Capture",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    AlertDialog dialog2 =AlertDialog.class.cast(dialog);
                    takeScreenshot(dialog2);
                    Context context = getApplicationContext();
                    Toast.makeText(context, "Screenshot Captured", Toast.LENGTH_LONG).show();
                }
            });

    builder.setNeutralButton("Return", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
        }
    });
    builder.show();
}

This is screenshot code

private void takeScreenshot(AlertDialog dialog) {
    Date now = new Date();
    android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);

    try {
        // image naming and path  to include sd card  appending name you choose for file
        String mPath = "/data/data/com.rohit.test/test.jpg"; // use your desired path

        // create bitmap screen capture
        View v1 = dialog.getWindow().getDecorView().getRootView();

        v1.setDrawingCacheEnabled(true);
        Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
        v1.setDrawingCacheEnabled(false);

        File imageFile = new File(mPath);

        FileOutputStream outputStream = new FileOutputStream(imageFile);
        int quality = 100;
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
        outputStream.flush();
        outputStream.close();

    } catch (Throwable e) {
        // Several error may come out with file handling or OOM
        e.printStackTrace();
    }
}

Screenshot taken

enter image description here

Note1: You can generalize the method takeScreenshot if you change the argument type to View and move dialog.getWindow().getDecorView().getRootView(); to dialog code from where this method is called.

Note2: Saw you updated question. I don't think you can get whole data in screenshot when some of them are hidden. Think it as like a normal screenshot (on computer or even phone). You take picture of only what you can see.

Rohit5k2
  • 17,948
  • 8
  • 45
  • 57
  • Thank you, this code is now working great, well almost... Sometimes the message box is scroll able to fit everything in, this is probably a step too far, but do you know of a way that the screenshot could save everything in the dialog and not just what's in view? – Sjharrison Feb 16 '16 at 12:27
  • The view I have used here in this code is complete dialog. So whatever will be on the dialog will be captured. – Rohit5k2 Feb 16 '16 at 12:28
  • @Sjharrison: Saw you updated question. I don't think you can get whole data in screenshot when some of them are hidden. Think it like a normal screenshot. You take picture of only what you can see. – Rohit5k2 Feb 16 '16 at 12:39
  • I thought that would be the answer, the only alternative i can think of is that when they press 'Capture' it takes a screenshot, and then leaves the dialog up instead of closing, however, the only way of doing that i can think of is to recall the code? – Sjharrison Feb 16 '16 at 12:43
  • I guess that is the only solution but frankly I am not sure. May be you post another question for this particular thing. I am sure someone will confirm or give a solution. – Rohit5k2 Feb 16 '16 at 12:45
  • 1
    I've found a post about stopping the dialog disappearing , so will use that, thank you very much for your help with this, glad you found it fun creating the solution for me :) – Sjharrison Feb 16 '16 at 12:49
3

Try out this library:

https://github.com/jraska/Falcon

it can capture dialogs to your screenshot.

Strider
  • 4,452
  • 3
  • 24
  • 35
1

1. My dear friend You Are doing one thing wrong by which you are not able to take the screenshot of Dialog box.

View v1 = getWindow().getDecorView().getRootView();

You are capturing the whole screen which is beneath your AlertDialog

You may use these methods to get your things done by sending the view of your dialog box to this method

Get Bitmap From A view

    public static Bitmap loadView(View v) {
    Bitmap b = Bitmap.createBitmap(width , height, Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(b);
    v.layout(0, 0, v.getWidth(), v.getHeight());
    v.draw(c);
    return b;
}

Saving Your Bitmap

    void saveFile(Bitmap bitmap) {
    String extr = Environment.getExternalStorageDirectory().toString() +   File.separator + "Folder";
    String fileName = new SimpleDateFormat("yyyyMMddhhmm'_bitmap.jpg'", Locale.US).format(new Date());
    File myPath = new File(extr, fileName);
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(myPath);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
        fos.flush();
        fos.close();
        MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, "Screen", "screen");
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Harsh Sharma
  • 898
  • 1
  • 14
  • 30
  • I have changed my code to add in what you have suggested, however in my dialog i call the methods however they are asking for perimeters, any idea what these would be? – Sjharrison Feb 16 '16 at 11:55
  • @Sjharrison what kind of parameters are you talking about can you provide your sample code – Harsh Sharma Feb 16 '16 at 12:02
  • if you look at my code above for the dialog i have basically created a new dialog 'sendDialogToView();' which is your 'get bitmap from a view' code and 'captureScreenAndOpen();' is your Saving Your Bitmap code – Sjharrison Feb 16 '16 at 12:05
  • @Sjharrison you just have to pass alertdialog view to the loadView() and it will return you a bitmap and after that pass that bitmap to saveFile() that's it and remove height and width from the method in parameters – Harsh Sharma Feb 16 '16 at 12:10