Home > OS >  AndoridManifest.xml structured incorrectly
AndoridManifest.xml structured incorrectly

Time:10-24

UPDATED OCT 22 2021

  • My debug AndoridManifest.xml file is giving me errors at build time.
  • Happens only with Android Simulator, IOS runs perfectly.
  • android.useAndroidX=true
  • android.enableJetifier=true

SUMMARY: The error is being caused by the tag: com.yalantis.ucrop.UCropActivity which is out of place. Even if I move it to the right place, it automatically moves back when building.

Error I am getting:

error: unexpected element <activity> found in <manifest>.

Here is my debug/AndroidManifest.xml:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.tomasward.fredi"
    android:versionCode="1"
    android:versionName="1.0.0" >

    <uses-sdk
        android:minSdkVersion="21"
        android:targetSdkVersion="31" />
    
    <uses-permission android:name="android.permission.INTERNET" />

    <activity
        android:name="com.yalantis.ucrop.UCropActivity"
        android:screenOrientation="portrait"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar" />

    <uses-feature
        android:name="android.hardware.location.network"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.location.gps"
        android:required="false" />

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 适配Android R包可见性 开始 -->
    <queries package="com.tomasward.fredi" >
        <intent>
            <action android:name="android.media.action.IMAGE_CAPTURE" />
        </intent>
        <intent>
            <action android:name="android.media.action.ACTION_VIDEO_CAPTURE" />
        </intent>
        <!-- For browser content -->
        <intent>
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.BROWSABLE" />

            <data android:scheme="https" />
        </intent> <!-- End of browser content -->
        <!-- For CustomTabsService -->
        <intent>
            <action android:name="android.support.customtabs.action.CustomTabsService" />
        </intent>
    </queries>

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE" />

    <application
        android:appComponentFactory="androidx.core.app.CoreComponentFactory"
        android:debuggable="true"
        android:icon="@mipmap/ic_launcher"
        android:label="Fredi"
        android:supportsRtl="true" >
        <activity
            android:name="com.tomasward.fredi.MainActivity"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:exported="true"
            android:hardwareAccelerated="true"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:windowSoftInputMode="adjustResize" >

           
            <meta-data
                android:name="io.flutter.embedding.android.NormalTheme"
                android:resource="@style/NormalTheme" />
            <meta-data
                android:name="com.google.android.geo.API_KEY"
                android:value="AIzaSyD9pKRFa-bPpig6wnQC5kj7nNMFF72rN3U" />
            <meta-data
                android:name="com.google.android.gms.ads.ca-app-pub-2176711646772763~2658546918"
                android:value="ca-app-pub-2176711646772763~2658546918" />
            <!--
                 Displays an Android View that continues showing the launch screen
                 Drawable until Flutter paints its first frame, then this splash
                 screen fades out. A splash screen is useful to avoid any visual
                 gap between the end of Android's launch screen and the painting of
                 Flutter's first frame.
            -->
            <meta-data
                android:name="io.flutter.embedding.android.SplashScreenDrawable"
                android:resource="@drawable/launch_background" />

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!--
             Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java
        -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
        <meta-data
            android:name="com.facebook.sdk.ApplicationId"
            android:value="@string/facebook_app_id" />

        <activity
            android:name="com.facebook.FacebookActivity"
            android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
            android:label="@string/app_name"
            android:theme="@style/com_facebook_activity_theme" />

        <activity
            android:name="com.facebook.CustomTabActivity"
            android:exported="true" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="@string/fb_login_protocol_scheme" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data
                    android:host="cct.com.tomasward.fredi"
                    android:scheme="fbconnect" />
            </intent-filter>
        </activity>

        <!-- Set up the Sign in with Apple activity, such that it's callable from the browser-redirect -->
        <activity
            android:name="com.aboutyou.dart_packages.sign_in_with_apple.SignInWithAppleCallback"
            android:exported="true" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="signinwithapple" />
                <data android:path="callback" />
            </intent-filter>
        </activity>

        <service
            android:name="com.google.firebase.components.ComponentDiscoveryService"
            android:directBootAware="true"
            android:exported="false" >
            <meta-data
                android:name="com.google.firebase.components:io.flutter.plugins.firebase.database.FlutterFirebaseAppRegistrar"
                android:value="com.google.firebase.components.ComponentRegistrar" />
            <meta-data
                android:name="com.google.firebase.components:io.flutter.plugins.firebase.auth.FlutterFirebaseAuthRegistrar"
                android:value="com.google.firebase.components.ComponentRegistrar" />
            <meta-data
                android:name="com.google.firebase.components:io.flutter.plugins.firebase.storage.FlutterFirebaseAppRegistrar"
                android:value="com.google.firebase.components.ComponentRegistrar" />
            <meta-data
                android:name="com.google.firebase.components:io.flutter.plugins.firebase.core.FlutterFirebaseCoreRegistrar"
                android:value="com.google.firebase.components.ComponentRegistrar" />
            <meta-data
                android:name="com.google.firebase.components:com.google.firebase.auth.FirebaseAuthRegistrar"
                android:value="com.google.firebase.components.ComponentRegistrar" />
            <meta-data
                android:name="com.google.firebase.components:com.google.firebase.storage.StorageRegistrar"
                android:value="com.google.firebase.components.ComponentRegistrar" />
            <meta-data
                android:name="com.google.firebase.components:com.google.firebase.database.DatabaseRegistrar"
                android:value="com.google.firebase.components.ComponentRegistrar" />
        </service>

        <provider
            android:name="io.flutter.plugins.imagepicker.ImagePickerFileProvider"
            android:authorities="com.tomasward.fredi.flutter.image_provider"
            android:exported="false"
            android:grantUriPermissions="true" >
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/flutter_image_picker_file_paths" />
        </provider>

        <meta-data
            android:name="io.flutter.embedded_views_preview"
            android:value="true" />

        <activity android:name="com.facebook.CustomTabMainActivity" />
        
        <provider
            android:name="com.facebook.internal.FacebookInitProvider"
            android:authorities="com.tomasward.fredi.FacebookInitProvider"
            android:exported="false" />

        <receiver
            android:name="com.facebook.CurrentAccessTokenExpirationBroadcastReceiver"
            android:exported="false" >
            <intent-filter>
                <action android:name="com.facebook.sdk.ACTION_CURRENT_ACCESS_TOKEN_CHANGED" />
            </intent-filter>
        </receiver>

        <activity
            android:name="com.google.firebase.auth.internal.GenericIdpActivity"
            android:excludeFromRecents="true"
            android:exported="true"
            android:launchMode="singleTask"
            android:theme="@android:style/Theme.Translucent.NoTitleBar" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data
                    android:host="firebase.auth"
                    android:path="/"
                    android:scheme="genericidp" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.google.firebase.auth.internal.RecaptchaActivity"
            android:excludeFromRecents="true"
            android:exported="true"
            android:launchMode="singleTask"
            android:theme="@android:style/Theme.Translucent.NoTitleBar" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data
                    android:host="firebase.auth"
                    android:path="/"
                    android:scheme="recaptcha" />
            </intent-filter>
        </activity>

        <service
            android:name="com.google.firebase.auth.api.fallback.service.FirebaseAuthFallbackService"
            android:enabled="true"
            android:exported="false" >
            <intent-filter>
                <action android:name="com.google.firebase.auth.api.gms.service.START" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </service>

        <provider
            android:name="com.google.firebase.provider.FirebaseInitProvider"
            android:authorities="com.tomasward.fredi.firebaseinitprovider"
            android:directBootAware="true"
            android:exported="false"
            android:initOrder="100" />
        <provider
            android:name="com.luck.picture.lib.PictureFileProvider"
            android:authorities="com.tomasward.fredi.luckProvider"
            android:exported="false"
            android:grantUriPermissions="true" >
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

        <activity
            android:name="com.luck.picture.lib.PictureSelectorActivity"
            android:configChanges="orientation|keyboardHidden|screenSize" />
        <activity
            android:name="com.luck.picture.lib.PictureSelectorWeChatStyleActivity"
            android:configChanges="orientation|keyboardHidden|screenSize" />
        <activity
            android:name="com.luck.picture.lib.PictureSelectorCameraEmptyActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:theme="@style/Picture.Theme.Translucent" />
        <activity
            android:name="com.luck.picture.lib.PictureCustomCameraActivity"
            android:configChanges="orientation|keyboardHidden|screenSize" />
        <activity
            android:name="com.luck.picture.lib.PicturePreviewActivity"
            android:configChanges="orientation|keyboardHidden|screenSize" />
        <activity
            android:name="com.luck.picture.lib.PictureSelectorPreviewWeChatStyleActivity"
            android:configChanges="orientation|keyboardHidden|screenSize" />
        <activity
            android:name="com.luck.picture.lib.PictureVideoPlayActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:screenOrientation="sensor" />
        <activity
            android:name="com.luck.picture.lib.PictureExternalPreviewActivity"
            android:configChanges="orientation|keyboardHidden|screenSize" />
        <activity
            android:name="com.luck.picture.lib.PicturePlayAudioActivity"
            android:configChanges="orientation|keyboardHidden|screenSize" />
        <activity
            android:name="com.yalantis.ucrop.UCropActivity"
            android:theme="@style/Base.Theme.NoActionBar" />
        <activity
            android:name="com.yalantis.ucrop.PictureMultiCuttingActivity"
            android:theme="@style/Base.Theme.NoActionBar" />
        <activity
            android:name="com.google.android.gms.auth.api.signin.internal.SignInHubActivity"
            android:excludeFromRecents="true"
            android:exported="false"
            android:theme="@android:style/Theme.Translucent.NoTitleBar" />
       
        <service
            android:name="com.google.android.gms.auth.api.signin.RevocationBoundService"
            android:exported="true"
            android:permission="com.google.android.gms.auth.api.signin.permission.REVOCATION_NOTIFICATION" /> <!-- Include the AdActivity and InAppPurchaseActivity configChanges and themes. -->
        <activity
            android:name="com.google.android.gms.ads.AdActivity"
            android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
            android:exported="false"
            android:theme="@android:style/Theme.Translucent" />

        <provider
            android:name="com.google.android.gms.ads.MobileAdsInitProvider"
            android:authorities="com.tomasward.fredi.mobileadsinitprovider"
            android:exported="false"
            android:initOrder="100" />

        <service
            android:name="com.google.android.gms.ads.AdService"
            android:enabled="true"
            android:exported="false" />

        <activity
            android:name="com.google.android.gms.common.api.GoogleApiActivity"
            android:exported="false"
            android:theme="@android:style/Theme.Translucent.NoTitleBar" />

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <provider
            android:name="androidx.work.impl.WorkManagerInitializer"
            android:authorities="com.tomasward.fredi.workmanager-init"
            android:directBootAware="false"
            android:exported="false"
            android:multiprocess="true" />

        <service
            android:name="androidx.work.impl.background.systemalarm.SystemAlarmService"
            android:directBootAware="false"
            android:enabled="@bool/enable_system_alarm_service_default"
            android:exported="false" />
        <service
            android:name="androidx.work.impl.background.systemjob.SystemJobService"
            android:directBootAware="false"
            android:enabled="@bool/enable_system_job_service_default"
            android:exported="true"
            android:permission="android.permission.BIND_JOB_SERVICE" />

        <receiver
            android:name="androidx.work.impl.utils.ForceStopRunnable$BroadcastReceiver"
            android:directBootAware="false"
            android:enabled="true"
            android:exported="false" />
        <receiver
            android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$BatteryChargingProxy"
            android:directBootAware="false"
            android:enabled="false"
            android:exported="false" >
            <intent-filter>
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
            </intent-filter>
        </receiver>
        <receiver
            android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$BatteryNotLowProxy"
            android:directBootAware="false"
            android:enabled="false"
            android:exported="false" >
            <intent-filter>
                <action android:name="android.intent.action.BATTERY_OKAY" />
                <action android:name="android.intent.action.BATTERY_LOW" />
            </intent-filter>
        </receiver>
        <receiver
            android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$StorageNotLowProxy"
            android:directBootAware="false"
            android:enabled="false"
            android:exported="false" >
            <intent-filter>
                <action android:name="android.intent.action.DEVICE_STORAGE_LOW" />
                <action android:name="android.intent.action.DEVICE_STORAGE_OK" />
            </intent-filter>
        </receiver>
        <receiver
            android:name="androidx.work.impl.background.systemalarm.ConstraintProxy$NetworkStateProxy"
            android:directBootAware="false"
            android:enabled="false"
            android:exported="false" >
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
        </receiver>
        <receiver
            android:name="androidx.work.impl.background.systemalarm.RescheduleReceiver"
            android:directBootAware="false"
            android:enabled="false"
            android:exported="false" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.TIME_SET" />
                <action android:name="android.intent.action.TIMEZONE_CHANGED" />
            </intent-filter>
        </receiver>
        <receiver
            android:name="androidx.work.impl.background.systemalarm.ConstraintProxyUpdateReceiver"
            android:directBootAware="false"
            android:enabled="@bool/enable_system_alarm_service_default"
            android:exported="false" >
            <intent-filter>
                <action android:name="androidx.work.impl.background.systemalarm.UpdateProxies" />
            </intent-filter>
        </receiver>

        <service
            android:name="androidx.room.MultiInstanceInvalidationService"
            android:exported="false" />

        <activity
            android:name="com.twitter.sdk.android.core.identity.OAuthActivity"
            android:configChanges="orientation|screenSize"
            android:excludeFromRecents="true"
            android:exported="false" />
    </application>

</manifest>

As requested, here is the GeneratedPluginRegistrant.java code:

@Keep
public final class GeneratedPluginRegistrant {
  private static final String TAG = "GeneratedPluginRegistrant";
  public static void registerWith(@NonNull FlutterEngine flutterEngine) {
    ShimPluginRegistry shimPluginRegistry = new ShimPluginRegistry(flutterEngine);
    try {
      dev.gilder.tom.apple_sign_in.AppleSignInPlugin.registerWith(shimPluginRegistry.registrarFor("dev.gilder.tom.apple_sign_in.AppleSignInPlugin"));
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin apple_sign_in, dev.gilder.tom.apple_sign_in.AppleSignInPlugin", e);
    }
    try {
      flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.auth.FlutterFirebaseAuthPlugin());
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin firebase_auth, io.flutter.plugins.firebase.auth.FlutterFirebaseAuthPlugin", e);
    }
    try {
      flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin());
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin firebase_core, io.flutter.plugins.firebase.core.FlutterFirebaseCorePlugin", e);
    }
    try {
      flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.database.FirebaseDatabasePlugin());
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin firebase_database, io.flutter.plugins.firebase.database.FirebaseDatabasePlugin", e);
    }
    try {
      flutterEngine.getPlugins().add(new io.flutter.plugins.firebase.storage.FlutterFirebaseStoragePlugin());
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin firebase_storage, io.flutter.plugins.firebase.storage.FlutterFirebaseStoragePlugin", e);
    }
    try {
      flutterEngine.getPlugins().add(new ru.innim.flutter_login_facebook.FlutterLoginFacebookPlugin());
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin flutter_login_facebook, ru.innim.flutter_login_facebook.FlutterLoginFacebookPlugin", e);
    }
    try {
      flutterEngine.getPlugins().add(new io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin());
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin flutter_plugin_android_lifecycle, io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin", e);
    }
    try {
      com.roughike.fluttertwitterlogin.fluttertwitterlogin.TwitterLoginPlugin.registerWith(shimPluginRegistry.registrarFor("com.roughike.fluttertwitterlogin.fluttertwitterlogin.TwitterLoginPlugin"));
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin flutter_twitter_login, com.roughike.fluttertwitterlogin.fluttertwitterlogin.TwitterLoginPlugin", e);
    }
    try {
      flutter.plugins.vibrate.VibratePlugin.registerWith(shimPluginRegistry.registrarFor("flutter.plugins.vibrate.VibratePlugin"));
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin flutter_vibrate, flutter.plugins.vibrate.VibratePlugin", e);
    }
    try {
      flutterEngine.getPlugins().add(new io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin());
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin google_mobile_ads, io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin", e);
    }
    try {
      flutterEngine.getPlugins().add(new io.flutter.plugins.googlesignin.GoogleSignInPlugin());
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin google_sign_in, io.flutter.plugins.googlesignin.GoogleSignInPlugin", e);
    }
    try {
      flutterEngine.getPlugins().add(new com.ggichure.github.hexcolor.HexcolorPlugin());
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin hexcolor, com.ggichure.github.hexcolor.HexcolorPlugin", e);
    }
    try {
      flutterEngine.getPlugins().add(new vn.hunghd.flutter.plugins.imagecropper.ImageCropperPlugin());
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin image_cropper, vn.hunghd.flutter.plugins.imagecropper.ImageCropperPlugin", e);
    }
    try {
      flutterEngine.getPlugins().add(new io.flutter.plugins.imagepicker.ImagePickerPlugin());
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin image_picker, io.flutter.plugins.imagepicker.ImagePickerPlugin", e);
    }
    try {
      flutterEngine.getPlugins().add(new com.chavesgu.images_picker.ImagesPickerPlugin());
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin images_picker, com.chavesgu.images_picker.ImagesPickerPlugin", e);
    }
    try {
      com.github.adee42.keyboardvisibility.KeyboardVisibilityPlugin.registerWith(shimPluginRegistry.registrarFor("com.github.adee42.keyboardvisibility.KeyboardVisibilityPlugin"));
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin keyboard_visibility, com.github.adee42.keyboardvisibility.KeyboardVisibilityPlugin", e);
    }
    try {
      flutterEngine.getPlugins().add(new io.flutter.plugins.pathprovider.PathProviderPlugin());
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin path_provider, io.flutter.plugins.pathprovider.PathProviderPlugin", e);
    }
    try {
      flutterEngine.getPlugins().add(new io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin());
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin shared_preferences, io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin", e);
    }
    try {
      flutterEngine.getPlugins().add(new com.tekartik.sqflite.SqflitePlugin());
    } catch(Exception e) {
      Log.e(TAG, "Error registering plugin sqflite, com.tekartik.sqflite.SqflitePlugin", e);
    }
  }
}

CodePudding user response:

Firstly, you need to migrate your android project to v2 embedding (quoted from https://github.com/hnvn/flutter_image_cropper). So could you please try this?

Secondly, could you please search in your code where you use com.yalantis.ucrop.UCropActivity? I guess it may be caused by some kind of build script, which automatically injects that section of code into your xml (but inject wrongly).

Thirdly, maybe also show all your dependencies.

CodePudding user response:

Seems you have 2 activity tags with the name com.yalantis.ucrop.UCropActivity.

Move

 <activity
        android:name="com.yalantis.ucrop.UCropActivity"
        android:screenOrientation="portrait"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar" />

into the application tag.

Remove,

<activity
            android:name="com.yalantis.ucrop.UCropActivity"
            android:theme="@style/Base.Theme.NoActionBar" />
  • Related