0

ok so im trying capture the webview on button click, of the web page that is being displayed on my webview activity and save it to the sd card.

i have in my manifest the right permission to write external storage and all webview features are working just great, just when i attempt to capture the image.

 public void onClick(View v) {
    switch(v.getId()) {

            case R.id.button1:
                WebViewClientDemoActivity.web.goBack(); 
                break;

        case R.id.button2:
                WebViewClientDemoActivity.web.goForward();
                break;

            case R.id.button3:
                WebViewClientDemoActivity.web.capturePicture();
                //Capture Picture
            Picture picture = WebViewClientDemoActivity.web.capturePicture();
            //Create a new canvas
            Canvas mCanvas = new Canvas();
            //Draw the Picture into the Canvas
            picture.draw(mCanvas);
            //Create a Bitmap
            Bitmap sreenshot = Bitmap.createBitmap(picture.getWidth(),
            picture.getHeight(),Config.ARGB_8888);
            //copy the content fron Canvas to Bitmap
            //mCanvas.drawBitmap(mBitmapScreenshot, 0, 0, null);
            mCanvas.drawBitmap(sreenshot, 0, 0, null);
            //Save the Bitmap to local filesystem
            if(sreenshot != null) {
                   ByteArrayOutputStream mByteArrayOpStream = new
            ByteArrayOutputStream();
                    sreenshot.compress(Bitmap.CompressFormat.JPEG, 90,
            mByteArrayOpStream);

                try {
                    File folder = new File(Environment.getExternalStorageDirectory().toString()+"/Enlighten/Images");
                    folder.mkdirs();
                    // create a File object for the parent directory
                    File outputFile = new File(folder, "enlighten.jpg");
                    // now attach the OutputStream to the file object, instead of a String representation
                    FileOutputStream fos = new FileOutputStream(outputFile);
                    fos.write(mByteArrayOpStream.toByteArray());
                    fos.close();
                    Toast.makeText(WebViewClientDemoActivity.this, "File Created", Toast.LENGTH_SHORT).show();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                    Toast.makeText(WebViewClientDemoActivity.this, "File Not Found", Toast.LENGTH_SHORT).show();
                } catch (IOException e) {
                    e.printStackTrace();
                }               

Im getting this error message. (UPDATED)

10-15 11:33:10.336: W/System.err(20577): java.io.FileNotFoundException: /mnt/sdcard/Enlighten/Images/enlighten.jpg: open failed: ENOENT (No such file or directory)
10-15 11:33:10.336: W/System.err(20577):    at libcore.io.IoBridge.open(IoBridge.java:406)
10-15 11:33:10.336: W/System.err(20577):    at java.io.FileOutputStream.<init>(FileOutputStream.java:88)
10-15 11:33:10.336: W/System.err(20577):    at java.io.FileOutputStream.<init>(FileOutputStream.java:73)
10-15 11:33:10.336: W/System.err(20577):    at com.jaisonbrooks.enlighten.WebViewClientDemoActivity.onClick(WebViewClientDemoActivity.java:374)
10-15 11:33:10.336: W/System.err(20577):    at android.view.View.performClick(View.java:3565)
10-15 11:33:10.336: W/System.err(20577):    at android.view.View$PerformClick.run(View.java:14165)
10-15 11:33:10.336: W/System.err(20577):    at android.os.Handler.handleCallback(Handler.java:605)
10-15 11:33:10.336: W/System.err(20577):    at android.os.Handler.dispatchMessage(Handler.java:92)
10-15 11:33:10.336: W/System.err(20577):    at android.os.Looper.loop(Looper.java:137)
10-15 11:33:10.336: W/System.err(20577):    at android.app.ActivityThread.main(ActivityThread.java:4517)
10-15 11:33:10.336: W/System.err(20577):    at java.lang.reflect.Method.invokeNative(Native Method)
10-15 11:33:10.346: W/System.err(20577):    at java.lang.reflect.Method.invoke(Method.java:511)
10-15 11:33:10.346: W/System.err(20577):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
10-15 11:33:10.346: W/System.err(20577):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
10-15 11:33:10.346: W/System.err(20577):    at dalvik.system.NativeStart.main(Native Method)
10-15 11:33:10.346: W/System.err(20577): Caused by: libcore.io.ErrnoException: open failed: ENOENT (No such file or directory)
10-15 11:33:10.346: W/System.err(20577):    at libcore.io.Posix.open(Native Method)
10-15 11:33:10.346: W/System.err(20577):    at libcore.io.BlockGuardOs.open(BlockGuardOs.java:110)
10-15 11:33:10.346: W/System.err(20577):    at libcore.io.IoBridge.open(IoBridge.java:390)
seaplain
  • 771
  • 7
  • 25
Jaison Brooks
  • 5,816
  • 7
  • 43
  • 79

2 Answers2

2

The openFileOutput() expects just the file name, without path separators, because it assumes that the file will be created in the app's private data area (if my memory doesn't cheat me then it should be /data/data/[your app package name]/files/).

To create a file on sdcard you can use FileOutputStream directly, see here for an example.

And another advice is that don't use hardcoded path like /mnt/sdcard because the absolute path of sdcard may vary on different devices, instead you should use Environment.getExternalStorageDirectory()

Community
  • 1
  • 1
Ziteng Chen
  • 1,959
  • 13
  • 13
  • Im trying to plug some of that stuff into my code, @Ziteng Chen – Jaison Brooks Oct 15 '12 at 15:20
  • i have updated my code above with what i was able to find and figure out what would work. Still having a issue with the error saying no direct or file exists. what am i missing? – Jaison Brooks Oct 15 '12 at 17:35
  • I tried your code on two devices, one with Android 2.1 and real removable sdcard, and another one with Android 4.0 and internal eMMC card, on both of them it works OK (I'm not sure about the screenshot part, but the jpg file can be saved successfully). So my question is do you really use the permission correctly? Note that the uses-permission tag should be in parallel with the application tag, not inside of it (" ..." – Ziteng Chen Oct 16 '12 at 05:06
1

I resolved my issue with this code so it screen captures from inside the menu

public boolean onOptionsItemSelected (MenuItem item){ 
        // Called when you tap a menu item
            switch (item.getItemId()){
            case R.id.settings_capture:
                item.setIcon(R.drawable.capture);                   
                //Resize the webview to the height of the webpage
                int pageHeight = web.getContentHeight();
                LayoutParams browserParams = web.getLayoutParams();
                web.setLayoutParams(new     LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, pageHeight));

                //Capture the webview as a bitmap
                web.setDrawingCacheEnabled(true);
                Bitmap bitmap =    Bitmap.createBitmap(web.getDrawingCache());
                web.setDrawingCacheEnabled(false);

                //Create the filename to use
                String randomFilenamepart = String.valueOf(new   SecureRandom().nextInt(1000000));
                String filename =   Environment.getExternalStorageDirectory().toString() + "/Enlighten_Mobile_" +   randomFilenamepart + ".jpg";

                File imageFile = new File(filename);
                //Stream the file out to external storage as a JPEG
                OutputStream fout = null;
                try {
                    fout = new FileOutputStream(imageFile);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fout);
                    fout.flush();
                    fout.close();
                    Toast.makeText(WebViewClientDemoActivity.this,   "Screen Capture Saved!\n\nImage Saved at location : /sdcard\n\nSaved As:   Enlighten_Mobile_xxxxx.jpg", Toast.LENGTH_LONG).show();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                    Toast.makeText(WebViewClientDemoActivity.this,   "Problem with Capturing Image or Location to Store Image", Toast.LENGTH_SHORT).show();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    web.setLayoutParams(browserParams);
                }
                return true;
Jaison Brooks
  • 5,816
  • 7
  • 43
  • 79