Proposal to set or create a project programmatically

1. What is the general goal of the feature?
To fix a crash when our wrapper app(Kaznet) tries to interact with the form API before a surveyor has created a project in ODK collect v2022.1.1.
The exact stacktrace for the crash is

org.odk.collect.android E/AndroidRuntime: FATAL EXCEPTION: main
    Process: org.odk.collect.android, PID: 23731
    java.lang.RuntimeException: Unable to start activity ComponentInfo{org.odk.collect.android/org.odk.collect.android.activities.FormDownloadListActivity}: java.lang.IllegalStateException: No current project!
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6077)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
     Caused by: java.lang.IllegalStateException: No current project!
        at org.odk.collect.android.projects.CurrentProjectProvider.getCurrentProject(CurrentProjectProvider.kt:25)
        at org.odk.collect.android.storage.StoragePathProvider.getProjectRootDirPath(StoragePathProvider.kt:20)
        at org.odk.collect.android.storage.StoragePathProvider.getOdkDirPath(StoragePathProvider.kt:51)
        at org.odk.collect.android.utilities.FormsRepositoryProvider.get(FormsRepositoryProvider.kt:18)
        at org.odk.collect.android.utilities.FormsRepositoryProvider.get$default(FormsRepositoryProvider.kt:17)
        at org.odk.collect.android.utilities.FormsRepositoryProvider.get(FormsRepositoryProvider.kt)
        at org.odk.collect.android.injection.config.AppDependencyModule.providesServerFormDetailsFetcher(AppDependencyModule.java:360)
        at org.odk.collect.android.injection.config.AppDependencyModule_ProvidesServerFormDetailsFetcherFactory.providesServerFormDetailsFetcher(AppDependencyModule_ProvidesServerFormDetailsFetcherFactory.java:52)
        at org.odk.collect.android.injection.config.DaggerAppDependencyComponent.serverFormsDetailsFetcher(DaggerAppDependencyComponent.java:386)
        at org.odk.collect.android.injection.config.DaggerAppDependencyComponent.injectFormDownloadListActivity(DaggerAppDependencyComponent.java:1101)
        at org.odk.collect.android.injection.config.DaggerAppDependencyComponent.inject(DaggerAppDependencyComponent.java:570)
        at org.odk.collect.android.activities.FormDownloadListActivity.onCreate(FormDownloadListActivity.java:146)
        at android.app.Activity.performCreate(Activity.java:6662)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6077) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) 

2. What are some example use cases for this feature?

  • A surveyor should be able to use ODK Collect along with other projects that are not related to our wrapper app.
  • A surveyor should be able to use the wrapper app with different configurations and switch between projects without having to make the change in ODK Collect every time. Currently the wrapper apps can change URL, username and password for the specific form upload.

3. What can you contribute to making this feature a reality?

  • Ona can assign an engineer to make the necessary changes to the code base.

@Hilary_Egesa it looks like we missed this. Is it still something you'd like to see addressed? We're open to a PR with tests and docs that would use the URL, username and password to look up the appropriate project or create it if needed.

@Grzesiek2010 and @seadowg does that sound right? I believe we do our best to maintain the URL, username, password intent functionality but tend to forget about it because it was contributed without tests and documentation.

2 Likes

Yeah, that sounds right. We'd likely need a content provider for Projects that support the insert action. One thing to keep in mind, is that the user would be able to add and switch Projects in Collect. This might mean that a wrapper app would need a way to set the current project. I can imagine this could also happen via a content provider - maybe with update and the ability to set a current value for a Project.