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.

Hi ODK Team,

We are looking into using the ODK Collect app via a wrapper app, we would love to have the feature to create projects from our wrapper app and update the current project.

I think having this as a content provider would solve this issue and makes a wrapper app with ODK Collect feel really integrated.

Do you guys agree/plan to add a project content provider?
If so would like to offer our help by either helping implement it or helping test it :slight_smile:.

There aren't currently any plans to add one.

It would be great to have this added as a contribution! If you've not contributed code to Collect before, the best way to get started is by reading the project's contribution guide. I think it'd also be good to propose here what projects content provider API would look like so that we can discuss that before you do any implementation. Some things to think about off the top of my head:

  • Do you need to be able to query all the projects in Collect?
  • Which project settings should the updatable via the content provider?
  • Will switching between projects need to be done via the content provider?
  • What security implications would exposing projects and allowing them to be modified have? What mitigations are there for them?