SurfaceView Returns black Screen in droidreader

2019-06-02 15:15发布

问题:

I had tried alot & even search alot but i didn't found the solution about the black screen which i get by fetching the cache view on the surface view.. if is there any other way to capture the screen then let me know about this.. if i use another control & fetching the drawable cache of that control it also return null.. this is the code which i used to fetch the screen Image....

try {
    // Button btn = new Button(mActivity.getApplicationContext());
    view.buildDrawingCache();
    view.setDrawingCacheEnabled(true);
    Bitmap b = view.getDrawingCache();
    b.compress(CompressFormat.JPEG, 100, new FileOutputStream(
                    "/mnt/sdcard/documents/" + new Date().getTime() + ".JPEG"));
} catch (Exception e) {
    e.printStackTrace();
}

i had used this on the touch_up action of the surface view.....

EDIT:

public class DroidReaderActivity extends Activity {
private static final boolean LOG = false;

private static final int REQUEST_CODE_PICK_FILE = 1;
private static final int REQUEST_CODE_OPTION_DIALOG = 2;

private static final int DIALOG_GET_PASSWORD = 1;
private static final int DIALOG_ABOUT = 2;
private static final int DIALOG_GOTO_PAGE = 3;
private static final int DIALOG_WELCOME = 4;
private static final int DIALOG_ENTER_ZOOM = 5;

private static final String PREFERENCE_EULA_ACCEPTED = "eula.accepted";
private static final String PREFERENCES_EULA = "eula";

protected DroidReaderView mReaderView = null;
protected DroidReaderDocument mDocument = null;

protected Menu m_ZoomMenu;

FrameLayout fl;

private String mFilename;
private String mTemporaryFilename;
private String mPassword;

private int mPageNo;

private SQLiteDatabase db;

static DatabaseConnectionAPI db_api;

private boolean mDocumentIsOpen = false;
private boolean mLoadedDocument = false;
private boolean mWelcomeShown = false;

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
    case REQUEST_CODE_PICK_FILE:
        if (resultCode == RESULT_OK && data != null) {
            // Theoretically there could be a case where OnCreate() is called
            // again with the intent that was originally used to open the app,
            // which would revert to a previous document. Use setIntent
            // to update the intent that will be supplied back to OnCreate().
            setIntent(data);
            mTemporaryFilename = data.getDataString();
            if (mTemporaryFilename != null) {
                if (mTemporaryFilename.startsWith("file://")) {
                    mTemporaryFilename = mTemporaryFilename.substring(7);
                }
                mPassword = "";
                openDocumentWithDecodeAndLookup();
            }
        }
        break;
    case REQUEST_CODE_OPTION_DIALOG:
        readPreferences();
        tryLoadLastFile();
        break;
    }
}

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    System.out.println("ONCREATE");

    db_api = new DatabaseConnectionAPI(this);
    try {
        db_api.createDataBase();
        db_api.openDataBase();
    } catch (IOException e) {
        e.printStackTrace();
    }
    // first, show the welcome if it hasn't been shown already:
    final SharedPreferences preferences = getSharedPreferences(PREFERENCES_EULA, Context.MODE_PRIVATE);
    if (!preferences.getBoolean(PREFERENCE_EULA_ACCEPTED, false)) {
        mWelcomeShown = true;
        preferences.edit().putBoolean(PREFERENCE_EULA_ACCEPTED, true).commit();
        showDialog(DIALOG_WELCOME);
    }

    if (mDocument == null)
        mDocument = new DroidReaderDocument();

    // Initialize the PdfRender engine
    PdfRender.setFontProvider(new DroidReaderFontProvider(this));

    // then build our layout. it's so simple that we don't use
    // XML for now.
    fl = new FrameLayout(this);

    mReaderView = new DroidReaderView(this, null, mDocument);

    // add the viewing area and the navigation
    fl.addView(mReaderView);
    setContentView(fl);

    readPreferences();
    if (savedInstanceState != null) {
        mFilename = savedInstanceState.getString("filename");
        if ((new File(mFilename)).exists()) {
            mPassword = savedInstanceState.getString("password");
            mDocument.mZoom = savedInstanceState.getFloat("zoom");
            mDocument.mRotation = savedInstanceState.getInt("rotation");
            mPageNo = savedInstanceState.getInt("page");
            mDocument.mMarginOffsetX = savedInstanceState.getInt("marginOffsetX");
            mDocument.mMarginOffsetY = savedInstanceState.getInt("marginOffsetY");
            mDocument.mContentFitMode = savedInstanceState.getInt("contentFitMode");
            openDocument();
            mLoadedDocument = true;
        }
        savedInstanceState.clear();
    }

        Timer mTimer = new Timer();

        mTimer.schedule(new TimerTask() {

            @Override
            public void run() {
                try {
                    Bitmap saveBitmap = Bitmap.createBitmap(fl.getWidth(), fl.getHeight(), Bitmap.Config.ARGB_8888);
                    saveBitmap.compress(CompressFormat.JPEG, 100,
                            new FileOutputStream("/mnt/sdcard/documents/" + new Date().getTime() + ".JPEG"));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, 4000);
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    if ((mDocument != null) && mDocument.isPageLoaded()) {
        outState.putFloat("zoom", mDocument.mZoom);
        outState.putInt("rotation", mDocument.mRotation);
        outState.putInt("page", mDocument.mPage.no);
        outState.putInt("offsetX", mDocument.mOffsetX);
        outState.putInt("offsetY", mDocument.mOffsetY);
        outState.putInt("marginOffsetX", mDocument.mMarginOffsetX);
        outState.putInt("marginOffsetY", mDocument.mMarginOffsetY);
        outState.putInt("contentFitMode", mDocument.mContentFitMode);
        outState.putString("password", mPassword);
        outState.putString("filename", mFilename);
        mDocument.closeDocument();
    }
}

public void onTap(float X, float Y) {
    float left, right, top, bottom;
    float width = mDocument.mDisplaySizeX;
    float height = mDocument.mDisplaySizeY;
    boolean prev = false;
    boolean next = false;

    if (mDocumentIsOpen) {
        left = width * (float) 0.25;
        right = width * (float) 0.75;
        top = height * (float) 0.25;
        bottom = height * (float) 0.75;

        if ((X < left) && (Y < top))
            prev = true;
        if ((X < left) && (Y > bottom))
            next = true;
        if ((X > right) && (Y < top))
            prev = true;
        if ((X > right) && (Y > bottom))
            next = true;
        if ((X > left) && (X < right) && (Y > bottom)) {
            Log.d("DroidReaderMetrics", String.format("Zoom = %5.2f%%", mDocument.mZoom * 100.0));
            Log.d("DroidReaderMetrics", String.format("Page size = (%2.0f,%2.0f)", mDocument.mPage.mMediabox[2]
                            - mDocument.mPage.mMediabox[0], mDocument.mPage.mMediabox[3] - mDocument.mPage.mMediabox[1]));
            Log.d("DroidReaderMetrics", String.format(
                    "Display size = (%d,%d)", mDocument.mDisplaySizeX, mDocument.mDisplaySizeY));
            Log.d("DroidReaderMetrics", String.format("DPI = (%d, %d)", mDocument.mDpiX, mDocument.mDpiY));
            Log.d("DroidReaderMetrics", String.format("Content size = (%2.0f,%2.0f)",
                    mDocument.mPage.mContentbox[2] - mDocument.mPage.mContentbox[0],
                    mDocument.mPage.mContentbox[3] - mDocument.mPage.mContentbox[1]));
            Log.d("DroidReaderMetrics", String.format("Content offset = (%2.0f,%2.0f)",
                    mDocument.mPage.mContentbox[0], mDocument.mPage.mContentbox[1]));
            Log.d("DroidReaderMetrics", String.format(
                    "Document offset = (%d,%d)", mDocument.mOffsetX, mDocument.mOffsetY));
        }
        if (next) {
            if (mDocument.havePage(1, true))
                openPage(1, true);
        } else if (prev) {
            if (mDocument.havePage(-1, true))
                openPage(-1, true);
        }
    }
}

protected void openDocument() {
    // Store the view details for the previous document and close it.
    if (mDocumentIsOpen) {
        mDocument.closeDocument();
        mDocumentIsOpen = false;
    }
    try {
        this.setTitle(mFilename);
        mDocument.open(mFilename, mPassword, mPageNo);
        openPage(0, true);
        mDocumentIsOpen = true;
    } catch (PasswordNeededException e) {
        showDialog(DIALOG_GET_PASSWORD);
    } catch (WrongPasswordException e) {
        Toast.makeText(this, R.string.error_wrong_password, Toast.LENGTH_LONG).show();
    } catch (Exception e) {
        Toast.makeText(this, R.string.error_opening_document, Toast.LENGTH_LONG).show();
    }
}

protected void openDocumentWithDecodeAndLookup() {
    try {
        mTemporaryFilename = URLDecoder.decode(mTemporaryFilename, "utf-8");

        // Do some sanity checks on the supplied filename.
        File f = new File(mTemporaryFilename);

        if ((f.exists()) && (f.isFile()) && (f.canRead())) {
            mFilename = mTemporaryFilename;
            openDocumentWithLookup();
        } else {
            Toast.makeText(this, R.string.error_file_open_failed, Toast.LENGTH_LONG).show();
        }
    } catch (Exception e) {
        Toast.makeText(this, R.string.error_opening_document, Toast.LENGTH_LONG).show();
    }
}

protected void openDocumentWithLookup() {
    readOrWriteDB(false);
    openDocument();
}

protected void openPage(int no, boolean isRelative) {
    try {
        if (!(no == 0 && isRelative))
            mDocument.openPage(no, isRelative);
        this.setTitle(new File(mFilename).getName()
                + String.format(" (%d/%d)", mDocument.mPage.no, mDocument.mDocument.pagecount));
        mPageNo = mDocument.mPage.no;
    } catch (PageLoadException e) {
    }
}



private void readPreferences() {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);

    if (prefs.getString("zoom_type", "0").equals("0")) {
        float zoom = Float.parseFloat(prefs.getString("zoom_percent", "50"));
        if ((1 <= zoom) && (1000 >= zoom)) {
            mDocument.setZoom(zoom / 100, false);
        }
    } else {
        mDocument.setZoom(Float.parseFloat(prefs.getString("zoom_type", "0")), false);
    }

    if (prefs.getBoolean("dpi_auto", true)) {
        // read the display's DPI
        mDocument.setDpi((int) metrics.xdpi, (int) metrics.ydpi);
    } else {
        int dpi = Integer.parseInt(prefs.getString("dpi_manual", "160"));
        if ((dpi < 1) || (dpi > 4096))
            dpi = 160; // sanity check fallback
        mDocument.setDpi(dpi, dpi);
    }

    if (prefs.getBoolean("tilesize_by_factor", true)) {
        // set the tile size for rendering by factor
        Float factor = Float.parseFloat(prefs.getString("tilesize_factor", "1.5"));
        mDocument.setTileMax((int) (metrics.widthPixels * factor), (int) (metrics.heightPixels * factor));
    } else {
        int tilesize_x = Integer.parseInt(prefs.getString("tilesize_x", "640"));
        int tilesize_y = Integer.parseInt(prefs.getString("tilesize_x", "480"));
        if (metrics.widthPixels < metrics.heightPixels) {
            mDocument.setTileMax(tilesize_x, tilesize_y);
        } else {
            mDocument.setTileMax(tilesize_y, tilesize_x);
        }
    }

    boolean invert = prefs.getBoolean("invert_display", false);
    mDocument.setDisplayInvert(invert);
    mReaderView.setDisplayInvert(invert);

    if (prefs.getBoolean("full_screen", false)) {
        this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    } else {
        this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    }

    mDocument.mHorizontalScrollLock = prefs.getBoolean("horizontal_scroll_lock", false);
}

protected void setZoom(float newZoom) {
    newZoom = newZoom / (float) 100.0;
    if (newZoom > 16.0)
        newZoom = (float) 16.0;
    if (newZoom < 0.0625)
        newZoom = (float) 0.0625;
    mDocument.setZoom(newZoom, false);
}

protected void tryLoadLastFile() {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
    mFilename = prefs.getString("last_open_file", "");
    if (mFilename != null) {
        if ((mFilename.length() > 0) && ((new File(mFilename)).exists())) {
            // Don't URL-decode the filename, as that's presumably already been done.
            mPassword = "";
            openDocumentWithLookup();
            mLoadedDocument = true;
        }
    }
}

}

DroidReaderView:

public class DroidReaderView extends SurfaceView implements OnGestureListener,
    SurfaceHolder.Callback, DroidReaderDocument.RenderListener {

public static Path mPath = new Path();
private static StringBuffer sbx = new StringBuffer();
private static StringBuffer sby = new StringBuffer();
public static Paint mPaint = new Paint();
public static Paint nullpaint = new Paint();
private String sx, sy, sbx_str, sby_str;
public static Canvas mCanvas = new Canvas();
private int pid = 1;

/**
 * Debug helper
 */
protected final static String TAG = "DroidReaderView";
protected final static boolean LOG = false;

/**
 * our view thread which does the drawing
 */
public DroidReaderViewThread mThread;

/**
 * our gesture detector
 */
protected final GestureDetector mGestureDetector;

/**
 * our context
 */
protected final DroidReaderActivity mActivity;

/**
 * our SurfaceHolder
 */
protected final SurfaceHolder mSurfaceHolder;

public static DroidReaderDocument mDocument;

protected boolean mDisplayInvert;

/**
 * constructs a new View
 * 
 * @param context
 *            Context for the View
 * @param attrs
 *            attributes (may be null)
 */
public DroidReaderView(final DroidReaderActivity activity, AttributeSet attrs, DroidReaderDocument document) {
    super(activity, attrs);

    mActivity = activity;
    mSurfaceHolder = getHolder();
    mDocument = document;
    mDocument.mRenderListener = this;

    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(Color.BLACK);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(12);

    // tell the SurfaceHolder to inform this thread on
    // changes to the surface
    mSurfaceHolder.addCallback(this);

    mGestureDetector = new GestureDetector(this);
}

/* event listeners: */

@Override
protected void onDraw(Canvas canvas) {

    mThread.c = canvas;
    mThread.c = mSurfaceHolder.lockCanvas();

    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(Color.RED);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(12);

    mThread.c.drawPath(mPath, mPaint);
    mSurfaceHolder.unlockCanvasAndPost(mThread.c);

}

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    if (LOG)
        Log.d(TAG, "onFling(): notifying ViewThread");
    mThread.mScroller.fling(0, 0, -(int) velocityX, -(int) velocityY, -4096, 4096, -4096, 4096);
    mThread.triggerRepaint();
    return true;
}

/* keyboard events: */

@Override
public boolean onKeyDown(int keyCode, KeyEvent msg) {
    if (LOG)
        Log.d(TAG, "onKeyDown(), keycode " + keyCode);
    return false;
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent msg) {
    if (LOG)
        Log.d(TAG, "onKeyUp(), keycode " + keyCode);
    return false;
}

/* interface for the GestureListener: */

@Override
public void onLongPress(MotionEvent e) {
    if (LOG)
        Log.d(TAG, "onLongPress(): ignoring!");
}

@Override
public void onNewRenderedPixmap() {
    if (LOG)
        Log.d(TAG, "new rendered pixmap was signalled");
    mThread.triggerRepaint();
}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
    if (LOG)
        Log.d(TAG, "onScroll(), distance vector: " + distanceX + "," + distanceY);
    mDocument.offset((int) distanceX, (int) distanceY, true);
    mThread.triggerRepaint();
    return true;
}

@Override
public void onShowPress(MotionEvent e) {
    if (LOG)
        Log.d(TAG, "onShowPress(): ignoring!");
}

@Override
public boolean onSingleTapUp(MotionEvent e) {
    // Pass the tap, and the window dimensions, to the activity to process.
    mActivity.onTap(e.getX(), e.getY());
    return true;
}

private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;

private void touch_start(float x, float y) {

    mPath.moveTo(x, y);
    mX = x;
    sx = Float.toString(mX);
    sbx.append(sx);
    sbx.append(",");

    mY = y;
    sy = Float.toString(mY);
    sby.append(sy);
    sby.append(",");

    sbx_str = sbx.toString();
    sby_str = sby.toString();
}

private void draw_move(float x, float y) {
    float dx = Math.abs(x - mX);
    float dy = Math.abs(y - mY);
    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
        mX = x;
        sx = Float.toString(mX);
        sbx.append(sx);
        sbx.append(",");
        mY = y;
        sy = Float.toString(mY);
        sby.append(sy);
        sby.append(",");
    }
}

private void touch_up() {
    mPath.lineTo(mX, mY);
    sx = Float.toString(mX);
    sbx.append(sx);
    sbx.append(",");

    sy = Float.toString(mY);
    sby.append(sy);
    sby.append(",");

    mPath.reset();

    sbx_str = sbx.toString().trim();
    sby_str = sby.toString().trim();

    insert(TAGS.presentation_id, mDocument.mPage.no, sbx_str, sby_str);
    sbx = new StringBuffer();
    sby = new StringBuffer();
    System.out.println(sbx_str.trim());
    System.out.println(sby_str.trim());

}

@Override
public boolean onTouchEvent(final MotionEvent event) {

    float x = event.getX();
    float y = event.getY();

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        touch_start(x, y);
        invalidate();
        break;
    case MotionEvent.ACTION_MOVE:
        draw_move(x, y);
        invalidate();
        break;
    case MotionEvent.ACTION_UP:
        touch_up();
        invalidate();
        try {

            // Button btn = new Button(mActivity.getApplicationContext());
            // buildDrawingCache();
            // setDrawingCacheEnabled(true);
            // Bitmap b = getDrawingCache();
            // b.compress(CompressFormat.JPEG, 100, new FileOutputStream(
            // "/mnt/sdcard/documents/" + new Date().getTime() + ".JPEG"));

        } catch (Exception e) {
            e.printStackTrace();
        }
        break;
    }
    invalidate();

    if (LOG) {
        Log.d(TAG, "onTouchEvent(): notifying mGestureDetector");
        invalidate();
    }
    if (mGestureDetector.onTouchEvent(event)) {
        invalidate();
        return true;
    }

    return true;
}

@Override
public boolean onTrackballEvent(MotionEvent event) {
    if (LOG)
        Log.d(TAG, "onTouchEvent(): notifying ViewThread");
    mDocument
            .offset((int) event.getX() * 20, (int) event.getY() * 20, true);
    mThread.triggerRepaint();
    return true;
}

/* surface events: */

public void setDisplayInvert(boolean invert) {
    if (mThread != null)
        mThread.setPainters(invert);
    mDisplayInvert = invert;
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    if (LOG)
        Log.d(TAG, "surfaceChanged(): size " + width + "x" + height);
    mDocument.startRendering(width, height);
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    if (LOG)
        Log.d(TAG, "surfaceCreated(): starting ViewThread");
    mThread = new DroidReaderViewThread(holder, mActivity, mDocument);
    mThread.setPainters(mDisplayInvert);
    mThread.start();
}

/* render events */

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    if (LOG)
        Log.d(TAG, "surfaceDestroyed(): dying");
    mDocument.stopRendering();
    boolean retry = true;
    mThread.mRun = false;
    mThread.interrupt();
    while (retry) {
        try {
            mThread.join();
            retry = false;
        } catch (InterruptedException e) {
        }
    }
}

@Override
public boolean onDown(MotionEvent e) {
    return false;
}

DroidReaderViewThread :

Thread that cares for blitting Pixmaps onto the Canvas and handles scrolling

class DroidReaderViewThread extends Thread {

public Canvas c = new Canvas();
private Cursor mCursor;
private Path mPath1 = new Path();
private StringBuffer sbx_read, sby_read;
public static Paint mPaint2 = new Paint();
public static Paint mPaint3 = new Paint();
Path old_path = new Path();

/**
 * Debug helper
 */
protected final static String TAG = "DroidReaderViewThread";
protected final static boolean LOG = false;
/**
 * the SurfaceHolder for our Surface
 */
protected final SurfaceHolder mSurfaceHolder;

/**
 * Paint for not (yet) rendered parts of the page
 */
protected final Paint mEmptyPaint;
/**
 * Paint for filling the display when there is no PdfPage (yet)
 */
protected final Paint mNoPagePaint;
/**
 * Paint for the status text
 */
protected final Paint mStatusPaint;

/**
 * Flag that our thread should be running
 */
protected boolean mRun = true;

/**
 * our scroller
 */
protected final Scroller mScroller;

protected final DroidReaderDocument mDocument;

/**
 * Background render thread, using the SurfaceView programming scheme
 * 
 * @param holder
 *            our SurfaceHolder
 * @param context
 *            the Context for our drawing
 */
public DroidReaderViewThread(SurfaceHolder holder, Context context, DroidReaderDocument document) {
    // store a reference to our SurfaceHolder
    mSurfaceHolder = holder;

    mDocument = document;

    // initialize Paints for non-Pixmap areas
    mEmptyPaint = new Paint();
    mNoPagePaint = new Paint();
    mStatusPaint = new Paint();

    setPainters(false);

    // the scroller, i.e. the object that calculates/interpolates
    // positions for scrolling/jumping/flinging
    mScroller = new Scroller(context);
}

/**
 * ll this does the actual drawing to the Canvas for our surface
 */

private void doDraw() {
    if (LOG)
        Log.d(TAG, "drawing...");
    c = null;
    try {
        c = mSurfaceHolder.lockCanvas(null);
        if (!mDocument.isPageLoaded()) {
            // no page/document loaded
            if (LOG)
                Log.d(TAG, "no page loaded.");
            c.drawRect(0, 0, c.getWidth(), c.getHeight(), mNoPagePaint);
        } else if (mDocument.havePixmap()) {
            // we have both page and Pixmap, so draw:
            // background:
            if (LOG)
                Log.d(TAG, "page loaded, rendering pixmap");
            c.drawRect(0, 0, c.getWidth(), c.getHeight(), mEmptyPaint);
            Log.d("CALL", "CALL");
            c.drawBitmap(mDocument.mView.mBuf, 0,
                    mDocument.mView.mViewBox.width(), -mDocument.mOffsetX + mDocument.mView.mViewBox.left,
                    -mDocument.mOffsetY + mDocument.mView.mViewBox.top,
                    mDocument.mView.mViewBox.width(), mDocument.mView.mViewBox.height(), false, null);

            try {
                Log.d("Reading", "Reading");
                mCursor = DroidReaderActivity.db_api
                        .ExecuteQueryGetCursor("SELECT * FROM path WHERE page_no=" + mDocument.mPage.no
                                + " AND presentation_id=" + TAGS.presentation_id + ";");

                if (!mCursor.equals(null)) {

                    mCursor.moveToFirst();
                    float x1 = 0, y1 = 0;
                    int pid = 0;
                    do {

                        sbx_read = new StringBuffer();
                        sbx_read.append(mCursor.getString(mCursor.getColumnIndex("x_path")));
                        sby_read = new StringBuffer();
                        sby_read.append(mCursor.getString(mCursor.getColumnIndex("y_path")));

                        String[] sbx_read_array = sbx_read.toString().trim().split(",");
                        String[] sby_read_array = sby_read.toString().trim().split(",");

                        for (int i = 0; i < sbx_read_array.length; i++) {

                            x1 = Float.parseFloat(sbx_read_array[i].toString());
                            y1 = Float.parseFloat(sby_read_array[i].toString());

                            if (pid != mCursor.getInt(mCursor.getColumnIndex("path_id"))) {

                                pid = mCursor.getInt(mCursor.getColumnIndex("path_id"));

                                Log.d("New Path Id.",
                                        String.valueOf(mCursor.getInt(mCursor.getColumnIndex("path_id"))));

                                mPath1.reset();
                                mPath1.moveTo(x1, y1);
                            } else {
                                Log.d("Path id repeating.",
                                        String.valueOf(mCursor.getInt(mCursor.getColumnIndex("path_id"))));
                            }

                            mPath1.lineTo(x1, y1);
                            c.drawPath(mPath1, DroidReaderView.mPaint);
                        }
                    } while (mCursor.moveToNext());
                    mCursor.close();
                    Log.d("Read mode Complete", "Read mode Complete");
                }
            } catch (Exception e) {
                // Log.d("read Cursor", e.getMessage().toString());
            }

        } else {
            // page loaded, but no Pixmap yet
            if (LOG)
                Log.d(TAG, "page loaded, but no active Pixmap.");
            c.drawRect(0, 0, c.getWidth(), c.getHeight(), mEmptyPaint);
            mPaint3.setAntiAlias(true);
            mPaint3.setDither(true);
            mPaint3.setColor(Color.TRANSPARENT);
            mPaint3.setStyle(Paint.Style.STROKE);
            mPaint3.setStrokeJoin(Paint.Join.ROUND);
            mPaint3.setStrokeCap(Paint.Cap.ROUND);
            mPaint3.setStrokeWidth(12);
            mPaint3.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
            c.drawPath(old_path, mPaint3);
        }
    } finally {
        if (c != null) {

            mPaint2.setAntiAlias(true);
            mPaint2.setDither(true);
            mPaint2.setColor(Color.GREEN);
            mPaint2.setStyle(Paint.Style.STROKE);
            mPaint2.setStrokeJoin(Paint.Join.ROUND);
            mPaint2.setStrokeCap(Paint.Cap.ROUND);
            mPaint2.setStrokeWidth(12);
            c.drawPath(DroidReaderView.mPath, mPaint2);
            // DroidReaderView.mPath.reset();
            // old_path = DroidReaderView.mPath;

        }
        mSurfaceHolder.unlockCanvasAndPost(c);
    }
}

/**
 * Main Thread loop
 */
@SuppressWarnings("static-access")
@Override
public void run() {
    while (mRun) {
        boolean doSleep = true;
        if (!mScroller.isFinished()) {
            if (mScroller.computeScrollOffset()) {
                if (LOG)
                    Log.d(TAG, "new scroll offset");
                doSleep = false;
                int oldX = mDocument.mOffsetX;
                int oldY = mDocument.mOffsetY;
                mDocument.offset(mScroller.getCurrX(), mScroller.getCurrY(), true);
                if ((oldX == mDocument.mOffsetX) && (oldY == mDocument.mOffsetY))
                    mScroller.abortAnimation();
            } else {
                mScroller.abortAnimation();
            }
        }
        doDraw();
        // if we're allowed, we will go to sleep now
        if (doSleep) {
            try {
                // nothing to do, wait for someone waking us up:
                if (LOG)
                    Log.d(TAG, "ViewThread going to sleep");

                // between
                // the check for pending interrupts and the sleep() which
                // could lead to a not-handled repaint request:
                if (!this.interrupted())
                    Thread.sleep(3600000);
            } catch (InterruptedException e) {
                if (LOG)
                    Log.d(TAG, "ViewThread woken up");
            }
        }
    }
    // mRun is now false, so we shut down.
    if (LOG)
        Log.d(TAG, "shutting down");
}

public void setPainters(boolean invert) {
    // initialize Paints for non-Pixmap areas
    mEmptyPaint.setStyle(Paint.Style.FILL);
    mNoPagePaint.setStyle(Paint.Style.FILL);
    mStatusPaint.setStyle(Paint.Style.FILL);

    if (invert)
        mEmptyPaint.setColor(0xff000000); // black
    else
        mEmptyPaint.setColor(0xffc0c0c0); // light gray

    if (invert)
        mNoPagePaint.setColor(0xff000000); // black
    else
        mNoPagePaint.setColor(0xff303030); // dark gray

    if (invert)
        mStatusPaint.setColor(0xff000000); // black
    else
        mStatusPaint.setColor(0xff808080); // medium gray
}

public void triggerRepaint() {
    if (LOG)
        Log.d(TAG, "repaint triggered");
    interrupt();
}
}

回答1:

I am using this, and its works fine in my case,

Here imageFrame is FrameLayout, root view of my View which I want to save as bitmap..

Bitmap saveBitmap = Bitmap.createBitmap(imageFrame.getWidth(), imageFrame.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(saveBitmap);
imageFrame.draw(c);

Try replacing imageFrame with your view.

EDIT:

    Date date = new Date();
    File filename = new File(file.getAbsoluteFile(), "" + date.getTime() + ".jpg");
    try
    {
        fOut = new FileOutputStream(filename);
        saveBitmap.compress(Bitmap.CompressFormat.JPEG, 50, fOut);
        try
        {
            fOut.flush();
            fOut.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
    catch (FileNotFoundException e)
    {
        e.printStackTrace();
    }

EDIT 2:

private void doDraw() {

  int w = WIDTH_PX, h = HEIGHT_PX; 
  BitmapConfig conf = Bitmap.Config.ARGB_8888; // see other conf types 
  Bitmap bmp = Bitmap.createBitmap(w, h, conf); // this creates a MUTABLE bitmap 
  c = new Canvas(bmp);