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

u5rb5r59  于 2023-06-20  发布在  Android
关注(0)|答案(2)|浏览(121)

我需要在我的应用程序中有类似于Facebook Messenger的聊天头的东西,基本上是一个可以在其他应用程序上查看的气泡。我在网上找不到关于这个主题的任何东西,除了this问题。那么有没有办法用RN做这样的东西呢?

whlutmcx

whlutmcx1#

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

@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-8 Oreo中,您必须请求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),请首先将您的Activity launchmode定义为manifest中的singleInstance:

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

希望能帮上忙。

7ajki6be

7ajki6be2#

如果你只想渲染图像,那么使用react-native-floating-bubbles包。https://github.com/hybriteq/react-native-floating-bubble遵循此文档。

相关问题