且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在 React-native 中绘制其他应用程序?

更新时间:2022-12-21 18:47:16

react native 不直接支持此功能,而且 ios 也不支持此功能,因此只有您可以在 android 中使用 java 本机代码来实现它.为此,您应该在 android 中编写一个处理此元素生命周期的服务.你可以在这里找到它的简单实现在一个安卓项目中.这是一个如此简单的示例,您可以将它的服务用于您的本机项目,只需更改它的 xml 文件即可自定义您的视图.并且要启动您的服务,您必须编写一个非常简单的 React Native 模块,如下所示

this feature is not support directly from react native and also this is not supported in ios therefore only you could implement it with java native code in android. to do that you should write a service in android which handle this element life cycle. You could find here simple implementation of that in an android project. it's such a straightforward example and you can use it's service for your react native project and just change it's xml file to customize your view. And just to start your service you must write a very simple react native module look like this

@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 中等待结果:

in Android-8Oreo you must ask for canDrawOverlays and you can wait for result in your MainActivity like this:

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);
        }
    }

然后从具有相同应用程序状态的服务再次返回到您的应用程序(不是创建新活动)首先将您的活动启动模式定义为清单中的单个实例:

And after that to come back again to your app from that service with the same appstate(not to create new activity) first define your activity launchmode as a singleInstance in manifest:

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

并在您的服务中使用这种意图(!):

And use this kind of intent(!) in your service:

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;
    }

希望能帮到你.