Как рисовать поверх других приложений в React-native? - PullRequest
0 голосов
/ 27 сентября 2018

Мне нужно, чтобы в моем приложении было что-то похожее на головы чата Facebook Messenger, в основном пузырь, который можно просматривать поверх других приложений.В этой теме я не могу найти ничего, кроме этого вопроса.Так есть ли способ сделать что-то подобное с RN?

1 Ответ

0 голосов
/ 07 февраля 2019

эта функция не поддерживается напрямую от реагировать на нативную, а также не поддерживается в ios, поэтому только вы можете реализовать ее с нативным кодом Java в Android.Чтобы сделать это, вы должны написать сервис в Android, который обрабатывает этот жизненный цикл элемента.Вы можете найти здесь простую реализацию этого в проекте Android.Это такой простой пример, и вы можете использовать его сервис для своего собственного собственного проекта и просто изменить его XML-файл, чтобы настроить свой вид.И просто, чтобы запустить свой сервис, вы должны написать очень простой собственный модуль реагирования, похожий на этот

@ReactMethod
public void startService(Promise promise) {

    String result = "Success";
    Activity activity = getCurrentActivity();
    if (activity != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(getReactApplicationContext())) {
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + getCurrentActivity().getPackageName()));
            getCurrentActivity().startActivityForResult(intent, MainActivity.DRAW_OVER_OTHER_APP_PERMISSION_REQUEST_CODE);
        }
    }
    try {
        Intent intent = new Intent(FloatingWidgetService.FLOATING_WIDGET_ID);
        intent.setClass(this.getReactApplicationContext(), FloatingWidgetService.class);
        getReactApplicationContext().startService(intent);
        FloatingWidgetService.setUri(uri);
    } catch (Exception e) {
        promise.reject(e);
        return;
    }
    promise.resolve(result);
}

в Android-8Oreo, вы должны запросить canDrawOverlays, и вы можете ждать результата в своей MainActivity, например:

private static final int DRAW_OVER_OTHER_APP_PERMISSION_REQUEST_CODE = 1222;
....
private void startFloatingWidgetService() {
    if (!mStarted) {
        Intent intent = new Intent(this, FloatingWidgetService.class);
        ContextCompat.startForegroundService(this, intent);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            this.startForegroundService(intent);
        }else{
            startService(intent);
        }
        mStarted = true;
        finish();
    }
}
....
 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == DRAW_OVER_OTHER_APP_PERMISSION_REQUEST_CODE) {
            //Check if the permission is granted or not.
            if (resultCode == RESULT_OK)
                //If permission granted start floating widget service
                startFloatingWidgetService();
            else
                //Permission is not available then display toast
                Toast.makeText(this,
                        getResources().getString(R.string.draw_other_app_permission_denied),
                        Toast.LENGTH_SHORT).show();

        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

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

<activity
        ...
        android:launchMode="singleInstance"
        ...
        >

И используйте такие намерения (!) В вашем служении:

ReactApplicationContext reactContext = VideoViewModule.getReactContext();
Intent activityIntent = createSingleInstanceIntent();
reactContext.startActivity(activityIntent);



 private Intent createSingleInstanceIntent() {
        ReactApplicationContext reactContext = VideoViewModule.getReactContext();
        String packageName = reactContext.getPackageName();
        Intent launchIntent = reactContext.getPackageManager().getLaunchIntentForPackage(packageName);
        String className = launchIntent.getComponent().getClassName();
        Intent activityIntent = null;
        try {

            Class<?> activityClass = Class.forName(className);

            activityIntent = new Intent(reactContext, activityClass);

            activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        } catch (Exception e) {
            stopCurrentService();
            Log.e("POIFOIWEGBF", "Class not found", e);

        }
        return activityIntent;
    }

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...