使用OverlayService Button截取屏幕截图

时间:2017-01-27 05:56:39

标签: android

我使用了覆盖服务按钮。当我单击覆盖按钮时,会拍摄快照,但会抛出异常

  

android.view.Window.getDecorView()'在空对象引用上

代码如下

主要活动

public class MainActivity extends Activity 

    public View v2;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        isStoragePermissionGranted();


        DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        int widthContentView = displaymetrics.widthPixels;
        int heightContentView = displaymetrics.heightPixels;
        Log.e("dis", widthContentView + "  " + heightContentView);


        v2 = getWindow().getDecorView().getRootView();
        Log.e("main", v2.toString());
        Intent svc = new Intent(this, OverlayShowingService.class);
        startService(svc);
        finish();
    }

    public boolean isStoragePermissionGranted() {
        if (Build.VERSION.SDK_INT >= 23) {
            if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    == PackageManager.PERMISSION_GRANTED) {
                Log.v(TAG, "Permission is granted");
                return true;
            } else {

                Log.v(TAG, "Permission is revoked");
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                return false;
            }
        } else { //permission is automatically granted on sdk<23 upon installation
            Log.v(TAG, "Permission is granted");
            return true;
        }
    }

    public void takeScreenshot(View v) {

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

        try {

            Log.e("line", "155");
            String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg";
            Log.e("line", mPath);
            MainActivity mainActivity = new MainActivity();
            Bitmap bitmap;
            DisplayMetrics displaymetrics = new DisplayMetrics();
            int widthContentView = displaymetrics.widthPixels;
            int heightContentView = displaymetrics.heightPixels;
            Log.e("dis", widthContentView + "  " + heightContentView);
            View  v1 = getWindow().getDecorView().getRootView();
            Log.e("ser", v1.toString());
            v1.setDrawingCacheEnabled(true);
            bitmap = Bitmap.createBitmap(v1.getDrawingCache());
            v1.setDrawingCacheEnabled(false);
            Log.e("line", "163");
            Log.e("line", "166");  
            File imageFile = new File(mPath);
            Log.e("line", "174");
            FileOutputStream outputStream = new FileOutputStream(imageFile);
            Log.e("line", "176");
            int quality = 100;
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
            Log.e("line", "179");
            outputStream.flush();
            outputStream.close();


        } catch (Exception e) {

            e.printStackTrace();
        }

    }

OverlayShowingService

public class OverlayShowingService extends Service implements OnTouchListener, OnClickListener 

    private View topLeftView;

    private Button overlayedButton;
    private float offsetX;
    private float offsetY;
    private int originalXPos;
    private int originalYPos;
    private boolean moving;
    private WindowManager wm;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);

        overlayedButton = new Button(this);
        overlayedButton.setText("Overlay");

        overlayedButton.setOnTouchListener(this);
        // overlayedButton.setAlpha(0.0f);
        overlayedButton.setBackgroundColor(Color.BLACK);
        // overlayedButton.setBackgroundColor(0x55fe4444);
        overlayedButton.setOnClickListener(this);

        WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, PixelFormat.TRANSLUCENT);
        params.gravity = Gravity.LEFT | Gravity.TOP;
        params.x = 0;
        params.y = 0;
        wm.addView(overlayedButton, params);
        topLeftView = new View(this);
        WindowManager.LayoutParams topLeftParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, PixelFormat.TRANSLUCENT);
        topLeftParams.gravity = Gravity.LEFT | Gravity.TOP;
        topLeftParams.x = 0;
        topLeftParams.y = 0;
        topLeftParams.width = 0;
        topLeftParams.height = 0;
        wm.addView(topLeftView, topLeftParams);

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (overlayedButton != null) {
            wm.removeView(overlayedButton);
            wm.removeView(topLeftView);
            overlayedButton = null;
            topLeftView = null;
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            float x = event.getRawX();
            float y = event.getRawY();

            moving = false;

            int[] location = new int[2];
            overlayedButton.getLocationOnScreen(location);

            originalXPos = location[0];
            originalYPos = location[1];

            offsetX = originalXPos - x;
            offsetY = originalYPos - y;

        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            int[] topLeftLocationOnScreen = new int[2];
            topLeftView.getLocationOnScreen(topLeftLocationOnScreen);

            System.out.println("topLeftY=" + topLeftLocationOnScreen[1]);
            System.out.println("originalY=" + originalYPos);

            float x = event.getRawX();
            float y = event.getRawY();

            WindowManager.LayoutParams params = (LayoutParams) overlayedButton.getLayoutParams();

            int newX = (int) (offsetX + x);
            int newY = (int) (offsetY + y);

            if (Math.abs(newX - originalXPos) < 1 && Math.abs(newY - originalYPos) < 1 && !moving) {
                return false;
            }

            params.x = newX - (topLeftLocationOnScreen[0]);
            params.y = newY - (topLeftLocationOnScreen[1]);

            wm.updateViewLayout(overlayedButton, params);
            moving = true;
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            if (moving) {
                return true;
            }
        }

        return false;
    }

    @Override
    public void onClick(View v) {
        Toast.makeText(this, "hai....", Toast.LENGTH_SHORT).show();
        MainActivity mainActivity=new MainActivity();
        mainActivity.takeScreenshot(v);

    }

我在活动中使用过相同的课程,我没有及时收到任何错误。我正在打印View   com.android.internal.policy.PhoneWindow $ DecorView {f1da4b9 V.E ...... R ....... 0,0-720,1280}  但在我的服务类中,我打印View com.android.internal.policy.PhoneWindow $ DecorView {40bf076 VE ..... R ..... ID 0,0-0,0} < / p>

for ref exception

1 个答案:

答案 0 :(得分:0)

我认为您忘了添加权限。

<manifest .....>

         <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
         <application

             ..............
             .............>
          <service
                    android:name=".services.OverlayShowingService"
                    android:enabled="true"
                    android:exported="false">

                </service>


            </application>
</manifest>

<强> Source