Как решить деятельность, не начиная с услуги? - PullRequest
0 голосов
/ 20 марта 2020

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

Intent dialogIntent = new Intent(this, ScreenshotActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(dialogIntent);

Однако, похоже, это не работает. Мой logcat выдает этот вывод, но действие не запускается:

020-03-20 20:54:02.824 22977-22977/com.xx.xx I/Timeline: Timeline: Activity_launch_request time:19482980

Мой сервис и действие работают независимо друг от друга. Но не в этой ситуации. Точка, откуда я делаю этот звонок, также достигнута. Устройство, которое я использую для тестирования, работает Android 9.

Редактировать : Основной сервисный код:

public class MyAccessibility extends AccessibilityService {
public static MyAccessibility instance;
@Override
public void onCreate() {
    super.onCreate();
    Log.i("myLog", "create accessibility");
}

@Override
public void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {
    Log.i("myLog", "Event");
    if (instance == null) {
        Log.i("myLog", "Instance set to not null");
        instance = this;
    }

}

@Override
public void onInterrupt() {

}

@Override
protected void onServiceConnected() {
    super.onServiceConnected();

    AccessibilityServiceInfo info = new AccessibilityServiceInfo();
    info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
    info.notificationTimeout = 100;
    info.feedbackType = AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
    this.setServiceInfo(info);
    Toast t = Toast.makeText(getApplicationContext(), "Accessibility Service is connected now", Toast.LENGTH_SHORT);
    t.show();

    System.out.println("Accessibility was connected!");

    instance = this;

}

public void takeSS(){
    Intent dialogIntent = new Intent(this, ScreenshotActivity.class);
    dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    this.startActivity(dialogIntent);
}

Существуют некоторые другие методы, которые используют dispatchGesture. Вот почему у меня есть ссылка на это и я могу получить доступ к этим методам из других источников. В скриншоте используется медиапроекция, чтобы сделать скриншот и использовать изображение:

public class ScreenshotActivity extends Activity {
private static final int REQUEST_MEDIA_PROJECTION = 1;
private static final String TAG = "ScreenshotActivity";

private MediaProjectionManager mProjectionManager;

private MediaProjection mMediaProjection = null;

private VirtualDisplay mVirtualDisplay;

private ImageReader mImageReader;

private static final int MAX_IMAGE_BUFFER = 10;
private  int counter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_screenshot_dummy);

    counter = 0;

    OrientationChangedListener mOrientationChangedListener = new OrientationChangedListener(this);
    mOrientationChangedListener.enable();

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        mProjectionManager = (MediaProjectionManager)getSystemService(MEDIA_PROJECTION_SERVICE);
        startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION);
    }
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
    super.onActivityResult(requestCode, resultCode, resultData);
    if (requestCode == REQUEST_MEDIA_PROJECTION) {
        String message;

        if (resultCode != Activity.RESULT_OK) {
            message = "Media Projection Declined";
            mMediaProjection = null;
        } else {

            message = "Media Projection Accepted";
            mMediaProjection = mProjectionManager.getMediaProjection(resultCode, resultData);
            attachImageCaptureOverlay();

        }

        Toast toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
        toast.show();

    }
}

private class OrientationChangedListener extends OrientationEventListener {

    int mLastOrientation = -1;

    OrientationChangedListener(Context context) {
        super(context);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public void onOrientationChanged(int orientation) {

        final int screenOrientation = getWindowManager().getDefaultDisplay().getRotation();

        if (mVirtualDisplay == null) return;

        if (mLastOrientation == screenOrientation) return;

        mLastOrientation = screenOrientation;

        detachImageCaptureOverlay();

        attachImageCaptureOverlay();
    }
}

private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public void onImageAvailable(ImageReader reader) {

        Image image = reader.acquireLatestImage();

        if (image == null || image.getPlanes().length <= 0) return;

        final Image.Plane plane = image.getPlanes()[0];

        final int rowPadding = plane.getRowStride() - plane.getPixelStride() * image.getWidth();
        final int bitmapWidth = image.getWidth() + rowPadding / plane.getPixelStride();

        final Bitmap tempBitmap = Bitmap.createBitmap(bitmapWidth, image.getHeight(), Bitmap.Config.ARGB_8888);
        tempBitmap.copyPixelsFromBuffer(plane.getBuffer());

        Rect cropRect = image.getCropRect();
        final Bitmap bitmap = Bitmap.createBitmap(tempBitmap, cropRect.left, cropRect.top, cropRect.width(), cropRect.height());

        //Do something with the bitmap


        image.close();
    }
};

@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private void attachImageCaptureOverlay() {

    if (mMediaProjection == null) return;

    final DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getRealMetrics(metrics);

    mImageReader = ImageReader.newInstance(metrics.widthPixels, metrics.heightPixels, PixelFormat.RGBA_8888, MAX_IMAGE_BUFFER);

    mVirtualDisplay = mMediaProjection.createVirtualDisplay("ScreenCaptureTest",
            metrics.widthPixels, metrics.heightPixels, metrics.densityDpi,
            DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
            mImageReader.getSurface(), null, null);

    mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);
}

@RequiresApi(api = Build.VERSION_CODES.KITKAT)
private void detachImageCaptureOverlay() {
    mVirtualDisplay.release();
    mImageReader.close();
}


}

1 Ответ

2 голосов
/ 20 марта 2020

Вы не можете начать деятельность с фона , начиная с Android Oreo .

Одним из обходных путей является вызов startForeground(true) при запуске службы, затем добавьте в свою службу sticky Notification с соответствующим действием ( запустите желаемое действие через PendingIntent ).

...