Снимок экрана - PullRequest
       67

Снимок экрана

9 голосов
/ 28 ноября 2011

Я разрабатываю приложение для снятия скриншотов в устройстве. В этом приложении мы можем нарисовать что угодно на экране. Для этого я использую Canvas, Paint и Path, чтобы сделать это.

Я использую этот код для снимков экрана:

        public void saveScreenshot() 
    {
        if (ensureSDCardAccess()) 
        {
            Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            onDraw(canvas);
            File file = new File(mScreenshotPath + "/" + System.currentTimeMillis() + ".jpg");
            FileOutputStream fos;
            try {
                fos = new FileOutputStream(file);
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                fos.close();
            } catch (FileNotFoundException e) {
                Log.e("Panel", "FileNotFoundException", e);
            } catch (IOException e) {
                Log.e("Panel", "IOEception", e);
            }
        }
    }

    /**
     * Helper method to ensure that the given path exists.
     * TODO: check external storage state
     */
    private boolean ensureSDCardAccess() {
        File file = new File(mScreenshotPath);
        if (file.exists()) {
            return true;
        } else if (file.mkdirs()) {
            return true;
        }
        return false;
    }

Однако, когда запускается следующая строка:

Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);

мое приложение закрывается со следующим исключением:

11-28 15:05:46.291: E/AndroidRuntime(8209): java.lang.IllegalArgumentException: width and height must be > 0

Если я изменю высоту и ширину, снимок экрана будет сделан, но он пуст:

Empty

Почему это происходит? Что я делаю не так?

Ответы [ 6 ]

18 голосов
/ 03 декабря 2011

Вы можете сделать это так,

Дайте идентификатор для вашего основного макета и после того, как вы отобразите контент на экране, напишите приведенный ниже код на каком-нибудь Слушателе, скажем, нажатие кнопки или элемент меню или любой такой Слушатель (убедитесь, что вы вызываете эти строки после того, как ваш макет отображается, иначе выдаст пустой экран).

        View content = findViewById(R.id.myLayout);
        content.setDrawingCacheEnabled(true);
        getScreen(content);

метод getScreen (содержимое)

private void getScreen(View content)
    {
        Bitmap bitmap = content.getDrawingCache();
        File file = new File("/sdcard/test.png");
        try 
        {
            file.createNewFile();
            FileOutputStream ostream = new FileOutputStream(file);
            bitmap.compress(CompressFormat.PNG, 100, ostream);
            ostream.close();
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
        }
    }

Также нельзя добавлять разрешение на запись файла на SDCard.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
                                                               </uses-permission>
3 голосов
/ 28 ноября 2011

Исключением является то, что высота и ширина Bitmap, который вы создаете, равна нулю

попробуйте код ниже, чтобы получить высоту и ширину

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();
int height = display.getHeight();

В случае отсутствия доступа к getWindowManager

Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
0 голосов
/ 26 августа 2016

Я обернул код скриншота в очень простую библиотеку. Это позволяет вам делать скриншоты и сохранять их на диск, если хотите.

https://github.com/abdallahalaraby/Blink

0 голосов
/ 05 ноября 2013

Я столкнулся с подобной проблемой, и решение было:

Вы получаете ширину и высоту до того, как ваш вид тонет, поэтому сначала проверьте, равна ли ширина или высота нулю:

if (getWidth() == 0 || getHeight() == 0) {
            initRemote(remote);
            isViewInitialized=false;
        }

isViewInitialized является значением элемента.

Затем поместите этот код в OnSizeChanged

@Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {

        super.onSizeChanged(w, h, oldw, oldh);
        if(!isViewInitialized&&){
            // this is the right place to take snapshot :)
        }

    }
0 голосов
/ 06 декабря 2011

Не могли бы вы показать больше вашего кода PLS?Кажется, что вы вызываете width и height не имеют положительных целочисленных значений.Вы можете отладить это, напечатав значения ширины и высоты.

0 голосов
/ 28 ноября 2011

getWidth (), getHeight () требуется вызывать с контекстом, если вы пробуете его вне Activity, он потерпит неудачу. Попробуйте getApplicationContext.getWidth ().

...