我使用了覆盖服务按钮。当我单击覆盖按钮时,会拍摄快照,但会抛出异常
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>
答案 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 强>