• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
Locked
0

SharedObject broken on Android 8?

Contributor ,
Dec 08, 2018 Dec 08, 2018

Copy link to clipboard

Copied

Hi All,

My app uses SharedObject to store data locally without problems on iOS, and on my Android 5 device, but it doesn't work on my Android 8 device.

When I say that it doesn't work what I mean is that it appears to write and read successfully, but when I restart my app the saved SharedObject doesn't contain any data.

Have any of you seen this?

Thanks in advance,

Douglas

TOPICS
Development

Views

1.9K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 10, 2018 Dec 10, 2018

Copy link to clipboard

Copied

Hi Douglas,

which version of the Air SDK are you using? I remember there was a bug related to this: When the device was close to being out of disk space, say 100 MB, SharedObject would not save any data. We encountered this bug only on iOS though, but this one was definitely fixed in a later Air SDK, so you might want to update to Air 31 and try it out. I can definitely say that we have no issues saving data in the SharedObject in Android 8 with Air.

Good luck,

Ruben

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 10, 2018 Dec 10, 2018

Copy link to clipboard

Copied

Hi Ruben -

Thanks for your response. I'm using AIR 31. Also, my app checks regularly to see how much disk space is available, so I'm confident that I have more than 400 MB. But thanks for the thoughts in any case.

All -

I'm wondering if this could be a permissions issue. I have the vague impression that Android is requiring more permissions to do things, just as iOS is.

But I tend to assume that local SharedObjects are saved to the applicationStorageDirectory, and this shouldn't require a special permission ... ?

Douglas

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe Employee ,
Dec 10, 2018 Dec 10, 2018

Copy link to clipboard

Copied

Hi,

Thank you for reporting the issue!

Please log a bug on Tracker and attach a sample project for the same.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Dec 10, 2018 Dec 10, 2018

Copy link to clipboard

Copied

I remember someone claiming you need these two for shared object:

android.permission.WRITE_EXTERNAL_STORAGE

android.permission.READ_PHONE_STATE

Don't know if it's true, though.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 11, 2018 Dec 11, 2018

Copy link to clipboard

Copied

Hi Lars,

Thanks for these suggestions. I already have these permissions in my app descriptor file, so I don't think that that's the issue.

Best,

Douglas

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Dec 11, 2018 Dec 11, 2018

Copy link to clipboard

Copied

Ah, good to know.

I also recall an earlier bug where the shared object's "getLocal name" had to be the exact same as the name of the APK file. As in:

var mySharedObj = SharedObject.getLocal("sameNameAsMyAPK"). But I don't think that will fix your problem.

You could try the latest AIR 32 that was released today.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 11, 2018 Dec 11, 2018

Copy link to clipboard

Copied

Hi Lars,

Thanks for the further thoughts.

One question - how does one sign up for notifications of beta releases of AIR? I would have thought that they'd be announced on this forum, but that doesn't seem to be the case.

All,

At this point I'm inclining towards switching from using SharedObject to using ByteArray.writeObject() and saving the ByteArray instance as a file. It just seems like this will be easier than trying to figure out whether this is a bug, how to work around it, etc.

I'll create another thread on that subject, to see if that approach is fraught with similar perils... 

Douglas

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Dec 11, 2018 Dec 11, 2018

Copy link to clipboard

Copied

I'm not sure whether there is a way to sign up for notification of beta releases. I just visit these sites frequently:

Beta: https://labs.adobe.com/downloads/air.html

Non-beta: https://www.adobe.com/devnet/air/air-sdk-download.html

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 15, 2018 Dec 15, 2018

Copy link to clipboard

Copied

I may be facing the same issue. What you say about the permissions being in your app descriptor need not be enough. Those settings are for Android 5 and earlier, for Android 6 you have to check to see if the user has previously given permission, and if they haven't they will be shown a dialog asking for permission, much like is done with iOS.

But, the things you can ask permissions for don't include reading phone state or external storage. Here's a topic that lists what things you can ask permissions for:

New Android permissions model for Android 6 in AIR SDK 24. Is there a table which lists all possible...

It could be that the file, or file reference permissions would take care of shared object too. I may give that a try.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 18, 2018 Dec 18, 2018

Copy link to clipboard

Copied

Hi Colin,

Yes, I was wondering if this was related to the new requirements re asking the user for permissions.

But, rather than figuring this out, I am instead switching to simply loading my data into a ByteArray and saving that as a file.

I haven't tested it thoroughly yet, but it seems to work so far. I assume that SharedObjects have some advantages - encryption? - but I don't need that...

Code below.

Douglas

Here's the code I'm using ... I don't see any option in this forum's editor that will allow me to prevent formatting - indents etc. - from getting munged - so, sorry about the lousy formatting ...

public class ByteArrayPersistenceManager {

   private var _initialized:Boolean;

   private var _persistenceDict:Dictionary;

   // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  //
  // Public Methods
  //
  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

   public function ByteArrayPersistenceManager() {

   initializeIfNeeded();

  }

   public function setProperty(key:String, value:Object):void {

   initializeIfNeeded();

   if (_persistenceDict != null)

   _persistenceDict[key] = value;

  }

   public function getProperty(key:String):Object {

   initializeIfNeeded();

   if (_persistenceDict != null) {

   if (_persistenceDict.hasOwnProperty(key)) {

   return _persistenceDict[key];

  }

   else {

   return null;

  }

  }

   else {

   return null;

  }

  }

   public function save():Boolean {

   if (_initialized) {

   try {

   var fs:FileStream = new FileStream();

   var file:File = File.applicationStorageDirectory.resolvePath(getFilePath());

   fs.open(file, FileMode.WRITE);

   var byteArray:ByteArray = new ByteArray();

   byteArray.writeObject(_persistenceDict);

   fs.writeBytes(byteArray);

   fs.close()

  }

   catch (e:Error) {

  Log.error("ByteArrayPersistenceManager.save() - save failed: " + e.message);

   return false;

  }

   return true;

  }

   else {

  Log.error("ByteArrayPersistenceManager.save() - instance not initialized");

   return false;

  }

  }

   // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  //
  // Private Methods
  //
  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

   private function initializeIfNeeded():void {

   if (!_initialized)

   load();

  }

   private function getFilePath():String {

   var result:String = Constants.FILEPATHINFO__PERSISTENCE_FOLDER_NAME + File.separator + Constants.FILEPATHINFO__PERSISTENCE_FILE_FILE_NAME;

   return result;

  }

   private function load():Boolean {

   try {

   var file:File = File.applicationStorageDirectory.resolvePath(getFilePath());

   if (file.exists) {

   var fs:FileStream = new FileStream();

   fs.open(file, FileMode.READ);

   var byteArray:ByteArray = new ByteArray();

   fs.readBytes(byteArray);

   fs.close();

   _persistenceDict = Dictionary(byteArray.readObject());

  }

   else {

   _persistenceDict = new PersistenceDict();

  }

   _initialized = true;

  }

   catch (e:Error) {

  Log.error("ByteArrayPersistenceManager.load() - load failed: " + e.message);

  }

   return _initialized;

  }

}

}

        

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 18, 2018 Dec 18, 2018

Copy link to clipboard

Copied

None of this has anything to do with SharedObject, you are just saving data to a file so you can read it back later. This should work without problem as long as you are saving primitive values but here's the question, is saving only primitive values then why would you need a dictionary? If you need a dictionary then you might save complex values, if you save complex values then you are required to register their classes to be able to save/retrieve them. Are you saving complex objects and are you correctly using RegisterClassAlias?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 18, 2018 Dec 18, 2018

Copy link to clipboard

Copied

Hi ASWC,

You're right - this has nothing to do with SharedObject.

I should have, instead, put this code into this thread. I think that I'll copy it over there, and copy your reply also, and respond there.

Douglas

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 18, 2018 Dec 18, 2018

Copy link to clipboard

Copied

'File' is definitely one of the things that now needs permissions. The guess was that indirectly SharedObject is using File, and so permission to use File would solve the problem for ShareObject.

As for the old problem on iOS, where under low memory situations SharedObject wouldn't work, that would also fail when using File.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 18, 2018 Dec 18, 2018

Copy link to clipboard

Copied

Hi Colin,

> 'File' is definitely one of the things that now needs permissions.

If you mean "needs interactive permission from the user", I'm not sure that this is actually the case. Take a look at the code that I shared above - the code that I'm using for the alternative "ByteArray" approach to saving data. It uses File and FileStream to save the data, and seems to be working without asking the user for permission. I mean, it's working in Android 8 which is the environment where SharedObject is failing for me.

To be clear, this is only of intellectual interest to me, not practical interest, as I'm switching over to the ByteArray approach. I'm happily fleeing from SharedObject for now.      At least, I'll be happily fleeing until some problem appears with the ByteArray approach.

Douglas

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 19, 2018 Dec 19, 2018

Copy link to clipboard

Copied

I hope that you're right, but in the release notes it says:

"The developers can request permissions for classes like Camera, Microphone, Geolocation, CameraRoll, CameraUI, File, and FileReference."

Also, an app update I thought I had finished is crashing at the point that some 3rd party code is invoking File, on Android 8. It works fine on Android 5.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 19, 2018 Dec 19, 2018

Copy link to clipboard

Copied

Perhaps it depends on where one is saving the file. I'm saving to applicationStorageDirectory. Perhaps Android sees this as a 'safe place' that doesn't require permissions...  ?

But I would think that SharedObject would save to the same folder. So I can't explain why I'm running into problems with SharedObject.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 19, 2018 Dec 19, 2018

Copy link to clipboard

Copied

I'm using the same directory (writing/reading files) for many of my Android apps without problem. I only set in app-xml the permission for read/write external storage and user is never requested to grant permission for that directory (unless Google has changed something VERY recently which I'm not aware of). So without testing myself your class/code, the idea of it should work in principle.

If you are forbidden to access that folder then shouldn't you get runtime errors? If you do not get those then what exactly is happening instead?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 19, 2018 Dec 19, 2018

Copy link to clipboard

Copied

Since November 1st Google require that you support Android 6 as the minimum SDK. That then kicks in all of the permissions things. If you submitted an app update before November 1st, you could opt to support Android 5 or earlier, and not have these difficulties.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 20, 2018 Dec 20, 2018

Copy link to clipboard

Copied

LATEST

I did update all our apps for that deadline using AIR 31 and didn't have to change a thing, everything was still working as usual. Many of our apps ship with no sounds and go grab them on our cdn as needed then save a local copy in ApplicationStorageDirectory for later use, that system is not broken with the update.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Dec 19, 2018 Dec 19, 2018

Copy link to clipboard

Copied

If you use SharedObject in a desktop app then that file will end up in that folder but I cannot tell if it's the same thing for Android or Ios. Maybe they do have a different place for those.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Dec 19, 2018 Dec 19, 2018

Copy link to clipboard

Copied

Very strange to hear you're having trouble with SharedObject, all of our apps use it and we haven't run into any issues with Android 8 or Android 9, haven't heard from any of our users having trouble with saves either.  We do use the permission for WRITE_EXTERNAL_STORAGE in our apps for saving images, but even if I manually disable that permission in Android 9 the SharedObjects are still working for me.

I'm trying to figure out if we're doing anything special that's letting it work.... are you using anything for your localPath in SharedObject.getLocal ?  We've always used "/" for our localPath instead of the null default, it puts the SharedObject in a different location when you do this.  I haven't really tested if it makes a difference what you use for apps, but might be worth a shot to try "/" for your localPath if you're not using one right now to see if that helps.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines