2015-02-10 71 views
1

我想尝试实现Android的屏幕截图功能。为此,我想从android的活动视图。我不允许使用R.id.viewid,因为我正在将其作为库的一部分而不是应用程序来实现。所以我试图使用activity.getWindow().getDecorView 请让我知道,如果得到DecorView是正确的做法?或者应该有另一种方法。从android的活动获取视图的截图?

MyActivity.java

@Override 
    protected void onResume(){ 
     super.onResume();  
     String mPath = Environment.getExternalStorageDirectory().toString() + "/test"; 
     Screenshot.takeScreenshot (this.getWindow().getDecorView(), mPath); 
     imageView.setImageBitmap(Screenshot.getBitmapScreenshot(this.getWindow().getDecorView())); 
    } 

Screenshot.java

public static void takeScreenshot(View view, String filePath) { 
     Bitmap bitmap = getBitmapScreenshot(view); 
     File imageFile = new File(filePath); 
     imageFile.getParentFile().mkdirs(); 
     try { 
      OutputStream fout = new FileOutputStream(imageFile); 
      bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout); 
      fout.flush(); 
      fout.close(); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

public static Bitmap getBitmapScreenshot(View view) { 

     //Define a bitmap with the same size as the view 
     Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888); 
     //Bind a canvas to it 
     Canvas canvas = new Canvas(returnedBitmap); 
     //Get the view's background 
     Drawable bgDrawable =view.getBackground(); 
     if (bgDrawable!=null) 
      //has background drawable, then draw it on the canvas 
      bgDrawable.draw(canvas); 
     else 
      //does not have background drawable, then draw white background on the canvas 
      canvas.drawColor(Color.WHITE); 
     // draw the view on the canvas 
     view.draw(canvas); 
     //return the bitmap 
     return returnedBitmap; 


    } 

我收到以下错误。

3795-3795/com.screenshot.nileshagrawal.screenshotapp E/AndroidRuntime﹕ FATAL EXCEPTION: main 
     Process: com.screenshot.nileshagrawal.screenshotapp, PID: 3795 

     java.lang.RuntimeException: Unable to resume activity {com.screenshot.nileshagrawal.screenshotapp/com.screenshot.nileshagrawal.screenshotapp.MainActivity}: 

java.lang.NullPointerException: Attempt to invoke virtual method 'int android.view.View.getWidth()' on a null object reference 
       at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2951) 
       at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2982) 
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2365) 
       at android.app.ActivityThread.access$800(ActivityThread.java:144) 
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278) 
       at android.os.Handler.dispatchMessage(Handler.java:102) 
       at android.os.Looper.loop(Looper.java:135) 
       at android.app.ActivityThread.main(ActivityThread.java:5221) 
       at java.lang.reflect.Method.invoke(Native Method) 
       at java.lang.reflect.Method.invoke(Method.java:372) 
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.view.View.getWidth()' on a null object reference 
       at com.screenshot.nileshagrawal.screenshotapp.Screenshot.getBitmapScreenshot(Screenshot.java:49) 
       at com.screenshot.nileshagrawal.screenshotapp.Screenshot.takeScreenshot(Screenshot.java:24) 
       at com.screenshot.nileshagrawal.screenshotapp.MainActivity.onResume(MainActivity.java:32) 
       at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1241) 
       at android.app.Activity.performResume(Activity.java:6019) 
       at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2940) 
                at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2982) 
                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2365) 
                at android.app.ActivityThread.access$800(ActivityThread.java:144) 
                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278) 
                at android.os.Handler.dispatchMessage(Handler.java:102) 
                at android.os.Looper.loop(Looper.java:135) 
                at android.app.ActivityThread.main(ActivityThread.java:5221) 
                at java.lang.reflect.Method.invoke(Native Method) 
                at java.lang.reflect.Method.invoke(Method.java:372) 
                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 
                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 
+1

确定。所以装饰视图为空。 – njzk2 2015-02-10 21:50:08

+0

我不知道,但是是应用程序崩溃在'位图returnedBitmap = Bitmap.createBitmap(view.getWidth(),view.getHeight(),Bitmap.Config.ARGB_8888);'调用getWidth空行,所以可能是装饰视图为空。 – 2015-02-10 21:53:22

+0

@downvote:我可以知道投票的理由吗? – 2015-02-10 22:30:56

回答

1

尝试把这个方法的onPause()作为视图做好准备过程中的任何修改onResume()。因此要么在onResume中加入一些延迟(使用处理程序以异步方式截图)或者如果屏幕截图不是那么重要,请在onPause()中使用相同的方法,然后在调用super.onPause()之前调用该函数。在其中一个stackoverflow后,下面的代码示例正在工作。 我已经在onPause()中测试过了。

使用这种方法

public static String takeScreenshot(Activity activity) { 
     Bitmap bitmap = null; 
     Bitmap resultBitmap = null; 
     ByteArrayOutputStream bos = null; 
     String encodedImg = null; 
     Toast.makeText(activity.getBaseContext(), "Taking screenshot", 
       Toast.LENGTH_SHORT).show(); 
     try { 
      View v1 = activity.getWindow().getDecorView().getRootView(); 

      v1.setDrawingCacheEnabled(true); 
      bitmap = Bitmap.createBitmap(v1.getDrawingCache()); 
      resultBitmap = Bitmap.createScaledBitmap(bitmap, 
        v1.getMeasuredWidth(), v1.getMeasuredHeight(), false); 
      v1.setDrawingCacheEnabled(false); 

      //MediaStore.Images.Media.insertImage(activity.getContentResolver(), 
      //resultBitmap, "myScreenshot2", "Test2"); 

      bos = new ByteArrayOutputStream(); 
      resultBitmap.compress(Bitmap.CompressFormat.JPEG, 10, bos); 
      byte[] bitmapdata = bos.toByteArray(); 
      encodedImg = new String(Base64.encode(bitmapdata, Base64.DEFAULT)); 

     } catch (Exception e) { 
      Log.e(Constants.LOG_TAG, "Could not capture the screen image"); 
      Log.e(Constants.LOG_TAG, e.toString()); 
      Log.e(Constants.LOG_TAG, Arrays.toString(e.getStackTrace())); 
     } finally { 
      if (bitmap != null) { 
       bitmap.recycle(); 
      } 
      if (resultBitmap != null) { 
       resultBitmap.recycle(); 
      } 
      if (bos != null) { 
       bos.reset(); 
      } 
      return encodedImg; 
     } 
    } 
-2

尝试更换getWindow()。getDecorView此

getWindow().getDecorView().findViewById(android.R.id.content) 

我觉得其余的将工作

+0

'getDecorView'返回null,调用'findViewById'不会更好... – njzk2 2015-02-10 22:03:20

+0

不,这不会帮助我,因为我将它创建为库的一部分。所以我不能要求用户的观点。 – 2015-02-10 22:03:47

+0

哦,右大声笑,我不知道然后 – CyborgFish 2015-02-10 22:04:57