Skip to content
CARP Docs
Ask AISystemLightDark
On this page

Installation

Add research_package to a Flutter app, register its localization delegates and add its translation files.

Copy MarkdownOpen inOpen in GitHubView as MarkdownOpen in Scira AIOpen in ChatGPTOpen in ClaudeOpen in Cursor

Setting up research_package in a Flutter app takes four steps:

  1. Add the packages

    flutter pub add research_package
    flutter pub add "flutter_localizations@{sdk: flutter}"

    flutter_localizations holds Flutter's own Material and Cupertino texts for languages other than English. Research Package shows Material dialogs and a Cupertino date picker, which fail in other languages without these texts.

    Note

    In an app that also uses carp_survey_package or cognition_package, the first command resolves research_package 3.2.0, because both packages require version 3. Version 3.2.0 brings the health and permission_handler plugins and their platform setup, as described in Survey Sampling Installation.

  2. Initialize Research Package

    In lib/main.dart, call ResearchPackage.ensureInitialized() at the start of main():

    import 'package:flutter/material.dart';
    import 'package:research_package/research_package.dart';
    
    void main() {
      ResearchPackage.ensureInitialized();
      runApp(const MyApp());
    }

    ensureInitialized() registers the model classes that fromJson() needs to load tasks and results from JSON. If a consent flow asks for permissions, also pass a permission requester as permissionRequester. See Permissions.

  3. Register the localization delegates

    Add the delegates and the languages your app supports to your MaterialApp:

    import 'package:flutter/material.dart';
    import 'package:flutter_localizations/flutter_localizations.dart';
    import 'package:research_package/research_package.dart';
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) => MaterialApp(
        supportedLocales: const [Locale('en'), Locale('da')],
        localizationsDelegates: [ 
          RPLocalizations.delegate,
          GlobalMaterialLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
        ],
        home: const HomePage(),
      );
    }

    RPLocalizations.delegate loads the package's own texts, which exist in Chinese (Simplified), Danish, English, French, Hungarian, Portuguese and Spanish. It then loads your app's translation file for the language and lets it override the package's texts. For any other language, your file must also translate the package's texts, or the screens show their keys.

    Write the list without const: RPLocalizations.delegate is not a constant.

  4. Add the translation files

    In assets/lang/, create one file for each language in supportedLocales, named after the language code: en.json and da.json for the app above. A file holds your translations as a JSON object, which may be empty until you add any:

    assets/lang/en.json
    {}

    Then declare the folder as an asset:

    pubspec.yaml
    flutter:
      uses-material-design: true
      assets:
        - assets/lang/

    Warning

    RPLocalizations.delegate requires these files. When the file for the current language is missing, the delegate fails to load, and the app does not show its first screen. An app without translation files uses RPLocalizationsDelegate(loaders: const []) instead, which loads only the package's own texts.

    For the file format, keys and plurals, see Localization.

Add media and sound assets

Instruction steps, image choices and timer steps load files from your app's assets. Add only the ones your tasks use:

AssetNeeded whenPath in the task
ImageAn instruction step has an imagePath, or an image choice has an imageUrl.The full asset key, such as assets/images/sleep.png
AudioAn instruction step has an audioPath.Relative to assets/, such as audio/breathing.mp3 for assets/audio/breathing.mp3
VideoAn instruction step has a videoPath.The full asset key, such as assets/video/intro.mp4
Timer soundA timer step has playSound: true.Fixed to assets/audio/RPTimerStepSound.mp3

The package does not bundle the timer sound into your app. Copy RPTimerStepSound.mp3 from the example app, or use your own sound under that name.

Declare each folder you use:

pubspec.yaml
flutter:
  uses-material-design: true
  assets:
    - assets/lang/
    - assets/images/
    - assets/audio/
    - assets/video/

imagePath, audioPath and videoPath also accept URLs. See Instruction step.

Configure Android and iOS

Research Package asks for no permissions and needs no manifest or Info.plist entries for surveys, consent screens and asset media. Each platform still has a minimum version:

AndroidiOS

Set minSdk to 24 or later. The default flutter.minSdkVersion of current Flutter releases is 24, so a new app needs no change.

Flutter declares the INTERNET permission only for debug and profile builds. To load media from a URL in a release build, add it to android/app/src/main/AndroidManifest.xml, directly above <application:

android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>

Set the deployment target to 15.0 or later, which is the default of new Flutter apps. For an older project, select Runner → General in Xcode and set Minimum Deployments to 15.0.

Load media from https URLs: by default, both platforms block video and audio over plain http.

A consent flow that sets askPermission asks through your app's permission requester, which brings its own platform setup. See Permissions.

Troubleshooting

The app shows a blank screen at startup

Add a translation file for every language in supportedLocales, and declare assets/lang/ in pubspec.yaml. Without the file for the current language, RPLocalizations.delegate fails to load, and Flutter does not show the first screen. An app without translations uses RPLocalizationsDelegate(loaders: const []) instead.

Error: No CupertinoLocalizations found

Add flutter_localizations and its three delegates, as in the third step. The app supports a language other than English, and the date picker and dialogs need Flutter's texts for it.

fromJson throws a SerializationException

Call ResearchPackage.ensureInitialized() before the first fromJson(). Until then, no model class is registered for JSON.

The timer step plays no sound

Add the file assets/audio/RPTimerStepSound.mp3 to your app, and declare assets/audio/ in pubspec.yaml. When the file is missing, the step prints an error and continues without sound.

Next step

Quickstart

Build a short survey and print the answers as JSON.

Quick links

Page · DocumentationCARP DocumentationPage · DocumentationIntroductionPage · DocumentationQuickstartPage · DocumentationTerminologyPage · DocumentationArchitecture