osayouba / opendatakit

Automatically exported from code.google.com/p/opendatakit
0 stars 0 forks source link

Install ODK Collect and MY_OWN_APP which uses ODK collect as a library #617

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1.Install both the apps (ODK Collect, MY_OWN_APP which uses ODK Collect as 
library) on the android phone
2.Installation will fail because of duplicate provider authority

What is the expected output? What do you see instead?
It is a known issue in android that authorities of 2 apps cannot be the same. 
One thing which we can do is change the content provider to our own content 
provider in AndroidManifest.xml so that ODK collect and MY_OWN_APP will not 
have conflicting providers.

But the following is hardcoded in many classses of ODK_COLLECT,
public static final String AUTHORITY = 
"org.odk.collect.android.provider.odk.forms";
public static final String AUTHORITY = 
"org.odk.collect.android.provider.odk.instance";

These are the classes,
FormsProvider
FormsProviderAPI
InstanceProvider
InstanceProviderAPI

One solution I thought was generalizing,

public static final String AUTHORITY = getString(R.string.forms_provider)
where forms_provider is declared in strings.xml, where you can have your custom 
resource authority according to your app.

But FormsProviderAPI and InstanceProviderAPI being plain Java classes do not 
have context.So cannot resolve any string from strings.xml (getString is not 
available).

What can be the solution to this problem ?

Would really appreciate your response to this.

Thanks,
Geet.

p.s: Glad that the date picker format (MM-YYYY) patch that we sent was included 
in your code.

Original issue reported on code.google.com by geetchan...@gmail.com on 25 Jun 2012 at 6:46

GoogleCodeExporter commented 9 years ago
You should be able to simply access ODK Collect's content provider, and should 
not have any need to define or expose the same content provider from within 
your app.  

This should all be at the manifest level, so even if you included all the 
source code directly, I would expect that it would ignore the content provider 
classes and instead access ODK Collect's content provider via the ODK Collect 
app, and not from within any classes defined in your app.

I haven't played around with libraries much. What do you need out of ODK 
Collect?  Seems like making that into an external intent that can be invoked 
would be a better option.

Original comment by mitchellsundt@gmail.com on 25 Jun 2012 at 10:35

GoogleCodeExporter commented 9 years ago
Some background to the problem --
So we had this issue due to the following scenario,
A client who had MY_APP(uses ODK Collect as android library) installed on his 
phone.
He tried to install ODK Collect app separately from the market. The 
installation failed. As both the apps viz. ODK COLLECT and MY_APP have the same 
provider authorities.

Suggested Change in ODK Collect--
We can change the FormsProviderAPI, InstanceProviderAPI classes in ODK Collect 
and instead of hardcoding this ---- > public static final String AUTHORITY = 
"org.odk.collect.android.provider.odk.forms";

We can either to something like,
public static final String AUTHORITY = getString(R.string.forms_provider)

OR

pick AUTHORITY from the AndroidManifest

This will make ODK Collect more generic and will enable people to install both 
apps viz. ODK Collect and THEIR_OWN_APP (which uses ODK as a library).

Original comment by geetchan...@gmail.com on 27 Jun 2012 at 9:42

GoogleCodeExporter commented 9 years ago
Yes, the authoritative string should be whatever is in the registry; I agree 
that it should ideally reference only one authoritative value.  Right now, that 
value is in 2 places -- the manifest and the string constant.

However, this won't avoid or solve the problems with MY_APP including ODK 
Collect as a library -- isn't that problem due to MY_APP claiming to be a 
content provider for this same URI?

Original comment by mitchellsundt@gmail.com on 27 Jun 2012 at 5:23

GoogleCodeExporter commented 9 years ago
Exactly. So because of the same content providers it wont allow to install both 
the apps.
Any ideas on how it will have to be done? 
Tried multiple approaches but with no luck.
Do you see any approach by which this can be done?

Original comment by geetchan...@gmail.com on 29 Jun 2012 at 10:08

GoogleCodeExporter commented 9 years ago
If you have two or more  ODK Collect-based apps installed, this did work before 
by popping up a dialog to choose which app to use for the content provider, 
much like file browsers or apps implementing image libraries on the phone.

What app is not behaving? This may not be the root cause of the problem you see.

Original comment by mitchellsundt@gmail.com on 29 Jun 2012 at 8:19

GoogleCodeExporter commented 9 years ago
Exactly, so it asks to choose which app to use. But when you try to fill a form 
using your custom app, it says "unrecognized 
URI:content://org.odk.collect.android.provider.odk.forms/forms/1"

My app in this case uses ODK as a library. We are not modifying the source code 
of ODK  directly.

Original comment by geetchan...@gmail.com on 3 Jul 2012 at 4:59

GoogleCodeExporter commented 9 years ago
I'm still not understanding why the custom app needs to include ODK Collect as 
a library, and why it cannot simply depend upon ODK Collect being installed and 
launch it using Intents.  The standard interaction of apps like ODK Clinic and 
ODK Tables is to set up the forms and instances for their app by inserting them 
using the content providers. Then to launch ODK Collect on that form or 
instance using an Intent.  ODK Collect completes the form, returns back to the 
calling app (ODK Clinic or ODK Tables), and they then check the 
marked-as-complete status of the instance and retrieve the data from the 
filled-in instance via queries against the content provider.

Is the library using the same file paths as the ODK Collect (e.g., all data 
going into /odk tree)?  It sounds like the database state is not being flushed 
to disk and ODK Collect is handling the inserts into the database but the 
custom app is not seeing those inserts.

Original comment by mitchellsundt@gmail.com on 3 Jul 2012 at 4:25