Data in Documents directory not accessible in Kindle Freetime Unlimited (Kindle Fire)

We have had a number of Kindle Fire customers who are trying to run our app using Kindle Freetime and running into problems. After working with the customer, we realized what was basically happening is that our app stores certain states in system.DocumentsDirectory. But the data stored there isn’t been shared with the profiles within Kindle Freetime. It’s as though each profile within Kindle Freetime has it’s own system.DocumentsDirectory.

The really weird part is, we haven’t been duplicate the same behavior using Kindle Freetime on our Kindle Fire. On ours, it appears the system.DocumentsDirectory within and without the Kindle Freetime.

Has anyone else seen this?

I’m guessing that Kindle FreeTime uses Android 4.3’s “restricted profiles” feature…

   http://developer.android.com/about/versions/android-4.3.html#RestrictedProfiles

I haven’t played with it in a while, but I remember restricted profiles get their own separate data directories.  Much like how it works on a desktop PC/Mac where each user on the same machine gets their own “My Documents” directory so-to-speak.  So, the files you write to the DocumentsDirectory for the main account should not be available to the restricted account.  The one big issue that I see with this is with in-app purchase.  If the main user does an in-app purchase and you flag that purchase to file in the DocumentsDirectory, the restricted user does not have access to the purchase information and your app has no choice but to think that the purchase was never made.  I’m guessing that’s the issue that you’re running into, correct?

We’ll contact someone at Amazon for their advise on how this should be handled.

They wrote the in-app purchase plugin for us, so they would know best.

Thanks for bringing this up.

@Joshua Thank you for such a quick response as always!

We are running into 2 issues with this. One is precisely what you have pointed out. Second is that after the IAP purchase, we actually download a fair bit of content onto the device. That would mean downloading all this content >2x (depending on how many restricted profiles you have).

2 other things to note:

  • I had the customers try doing an IAP restore from within the profiles, but the restore fails (not a surprise).

  • On our office Kindle, the data appears to be shared between the device’s profile and the restricted Kindle Freetime profile. I am not sure if this has something to do with the way Amazon’s “cloud-based” restore is working on our device… That’s probably a different topic we’ll do a separate post on.

When we tested restricted profiles on a regular Android 4.3 tablet (like a Nexus 7) several months ago, I remember Android’s handling of the app data directory being different when creating the restricted profile before/after your app gets installed.  That is, if you create the restricted profile before you installed your app… versus installing your app and then creating a restricted profile afterwards.  If I remember right, the paths to the data directory would be different in each case.

That said, I’m merely guessing that Kindles are using Android’s restricted profiles feature.  They might not.  We’re waiting for a definitive answer from Amazon on exactly how this works.

@Josh I got the following response from Amazon. I think your hunch is right, they do use restricted profiles.

But this still doesn’t help me with the problem, since the user can’t restore IAP purchases from within the profile, I can’t unlock the content for them once they are in the profile. Any thoughts/suggestions would be much appreciated.

Thank you for writing in. This will happen on latest 3rd Gen devices as Kindle FreeTime is built on top of multiple android users, which was a feature introduced in Android 4.2. This means that when the customer starts Kindle FreeTime, they actually switch to a separate android user. Data is not shared because Android allocates separate data directories for each user; ex “/data/user/0” for the parent, “/data/user/10” for the first child, “/data/user/11” for the second child, etc. I believe that the “sdcard” is also emulated per user in /storage/emulated/<android user_id>.

We’re still waiting for a response from Amazon.

I know that Google Play’s solution to this is to query for all purchases on app startup via their version 3 API.  I’m wondering if Amazon has an equivalent… or perhaps some other recommended practice.  Amazon wrote the in-app purchase plugin, so they would know best.

I’m guessing that Kindle FreeTime uses Android 4.3’s “restricted profiles” feature…

   http://developer.android.com/about/versions/android-4.3.html#RestrictedProfiles

I haven’t played with it in a while, but I remember restricted profiles get their own separate data directories.  Much like how it works on a desktop PC/Mac where each user on the same machine gets their own “My Documents” directory so-to-speak.  So, the files you write to the DocumentsDirectory for the main account should not be available to the restricted account.  The one big issue that I see with this is with in-app purchase.  If the main user does an in-app purchase and you flag that purchase to file in the DocumentsDirectory, the restricted user does not have access to the purchase information and your app has no choice but to think that the purchase was never made.  I’m guessing that’s the issue that you’re running into, correct?

We’ll contact someone at Amazon for their advise on how this should be handled.

They wrote the in-app purchase plugin for us, so they would know best.

Thanks for bringing this up.

@Joshua Thank you for such a quick response as always!

We are running into 2 issues with this. One is precisely what you have pointed out. Second is that after the IAP purchase, we actually download a fair bit of content onto the device. That would mean downloading all this content >2x (depending on how many restricted profiles you have).

2 other things to note:

  • I had the customers try doing an IAP restore from within the profiles, but the restore fails (not a surprise).

  • On our office Kindle, the data appears to be shared between the device’s profile and the restricted Kindle Freetime profile. I am not sure if this has something to do with the way Amazon’s “cloud-based” restore is working on our device… That’s probably a different topic we’ll do a separate post on.

When we tested restricted profiles on a regular Android 4.3 tablet (like a Nexus 7) several months ago, I remember Android’s handling of the app data directory being different when creating the restricted profile before/after your app gets installed.  That is, if you create the restricted profile before you installed your app… versus installing your app and then creating a restricted profile afterwards.  If I remember right, the paths to the data directory would be different in each case.

That said, I’m merely guessing that Kindles are using Android’s restricted profiles feature.  They might not.  We’re waiting for a definitive answer from Amazon on exactly how this works.

@Josh I got the following response from Amazon. I think your hunch is right, they do use restricted profiles.

But this still doesn’t help me with the problem, since the user can’t restore IAP purchases from within the profile, I can’t unlock the content for them once they are in the profile. Any thoughts/suggestions would be much appreciated.

Thank you for writing in. This will happen on latest 3rd Gen devices as Kindle FreeTime is built on top of multiple android users, which was a feature introduced in Android 4.2. This means that when the customer starts Kindle FreeTime, they actually switch to a separate android user. Data is not shared because Android allocates separate data directories for each user; ex “/data/user/0” for the parent, “/data/user/10” for the first child, “/data/user/11” for the second child, etc. I believe that the “sdcard” is also emulated per user in /storage/emulated/<android user_id>.

We’re still waiting for a response from Amazon.

I know that Google Play’s solution to this is to query for all purchases on app startup via their version 3 API.  I’m wondering if Amazon has an equivalent… or perhaps some other recommended practice.  Amazon wrote the in-app purchase plugin, so they would know best.

Can you elaborate on the Google Play solution you mention? I don’t understand what you mean.

Google’s version 3 in-app purchase/billing system supports querying for all purchases made.  Google now recommends using this method instead of storing what purchases were made to file for yourself.  I believe Google made this API to avoid the issue that is happening to akao when multiple user accounts are using your device… plus, it means you wouldn’t need to restore anymore.

Corona now supports Google’s version 3 in-app purchase/billing system as a plugin, which you have to opt-in to using or else Corona will default to Google’s version 2 system.  Documentation can be found here…

   http://docs.coronalabs.com/daily/plugin/google-iap-v3/index.html

Thanks for the clarifications on iap-v3. That’s super helpful.

Just FYI, I did speak to some folks over at Amazon the other day, and this is an issue that they are aware of. I get the sense they haven’t figured out a solution for it yet. Maybe suggesting this as a solution to them would help them along?

Well, that’s a bummer.  I’m sure Amazon can come up with a solution, but the problem is that you’ll have to wait for it.  I suppose your only other solution is to store purchases to your own web server, but that’s not a small effort.

Can you elaborate on the Google Play solution you mention? I don’t understand what you mean.

Google’s version 3 in-app purchase/billing system supports querying for all purchases made.  Google now recommends using this method instead of storing what purchases were made to file for yourself.  I believe Google made this API to avoid the issue that is happening to akao when multiple user accounts are using your device… plus, it means you wouldn’t need to restore anymore.

Corona now supports Google’s version 3 in-app purchase/billing system as a plugin, which you have to opt-in to using or else Corona will default to Google’s version 2 system.  Documentation can be found here…

   http://docs.coronalabs.com/daily/plugin/google-iap-v3/index.html

Thanks for the clarifications on iap-v3. That’s super helpful.

Just FYI, I did speak to some folks over at Amazon the other day, and this is an issue that they are aware of. I get the sense they haven’t figured out a solution for it yet. Maybe suggesting this as a solution to them would help them along?

Well, that’s a bummer.  I’m sure Amazon can come up with a solution, but the problem is that you’ll have to wait for it.  I suppose your only other solution is to store purchases to your own web server, but that’s not a small effort.

What about when a device is not online? When the app is started, it will be unable to query Google version 3 in-app purchasing/billing system.