geometer / FBReaderJ

Official FBReaderJ project repository
http://www.fbreader.org/FBReaderJ/
1.83k stars 801 forks source link

Ad write support to external SD card #414

Open baztian opened 8 years ago

baztian commented 8 years ago

Android 5.0 and above supports writing to an external SD card, but requires that the user select the allowed directory. FBReader for Android 2.6.13 (2061322) doesn't seem to support this. Are there any plans to add support for this in the near future? Folders on sd card are marked with a lock when I try to configure them as the download folder.

alaricljs commented 6 years ago

This is still an issue, any chance of getting it worked on?

DMcCunney commented 6 years ago

This is still an issue. On a new tablet running Android 6.01 Marshmallow, FBReaderJ cannot load books from an external card, let alone write to it. Attempting to select /storage/extsd as a place to look for books returns a Permission Denied error. This makes FBReader unusable on that platform.

Fmstrat commented 6 years ago

This also contains another issue. If you switch to SD card for book location (no write) it allows it, but you can't switch back!

DMcCunney commented 6 years ago

I've found two open source eBook viewers based on FBReader code - Book Reader and ReadEra. Both successfully access volumes on an external card on the tablet running Marshmallow. ReadEra popped up a dialog box indicating it needed permissions, and took me the the Settings are to give it access to the card. Unfortunately, neither are at a state of development where they would be a viable substitute.

It's probably a fairly simple change to FB to add support for the permissions required in Marshmallow and later, but Nikolay doesn't seem to be paying attention at the moment. I suspect Real Life is eating the time he would use updating FBReader for Android.

hwasiti commented 6 years ago

@DMcCunney Nikolay seems changed its further development into closed source after v2.6. You can install his FBReader app from Playstore and you will see that his newest version app does support runtime permission for mashmallow. Update: I meant runtime permission and not writing permission to external SD card, which seems still the newest FBReader v2.8.11 does not support

By the way, I checked ReaderEra and it's seemed it is indeed based on FBReader. However I could not find its open source code? Are you sure it is open source?

DMcCunney commented 6 years ago

@hwasiti: It's permission to access the external card that is the issue. The card is seen as /storage/extsd on the problem device. It works fine on older devices with external cards running Kit Kat and Lollipop. Current FBReader runs fine on a couple of phones running Mareshmallow and Nougat that don't have external cards, where FBReader documents are in device primary storage. I run FBReader Premium, but the current free version behaves the same way.

On the 10" tablet running Marshmallow, I get a "Permission denied" error trying to select /storage/extsd as a place to look for eBooks. ReadEra, mentioned above, just popped up a dialog box telling me I need to give the appropriate permissions and took me to the Settings menu where I can. That should be a simple addition for FB...

(Another potential issue is the card itself. Other devices with external cards have 32GB cards, because the devices use SDHC slots that have a 32GB vlume size limit. The 10" tablet has a 64GB card that tablet recognized and formatted exFAT. That should not cause the problem I'm seeing, but plugging in a 32GB card instead is a test I need to make.)

No, I don't know if ReadEra is in fact open source. Consider my earlier statement corrected. It is freeware. I don't read Russian, so going to the vendor's website isn't helpful in determining the licensing.

But if it is based on FBReader code, FBReader uses a GPL license, so the ReadEra folks either cut a deal with Nikolay to create a closed source fork, or are in violation of the GPL license. (Not the first time I've seen that happen, and good luck getting it corrected. The GPL is ultimately a gentlemen's agreement that parties follow because it's the right thing to do. It someone doesn't obey the rules, you must take them to court, and few people in open source have the time, legal expertise, and money to do that.)

hwasiti commented 6 years ago

A workaround would be (although not an ideal one) is to root your phone. I have a marshmallow Cyanogen OS on my GNote3 phone and works fine with FBReader access to the external SD card. At least the reading works fine. I have not tested writing or downloading to the external SD card. I've just tried to open a file in my external 200GB SD card.

From the root -> storage -> Sdcard1 I could access all my ext SDcard.

If your phone is rooted, you can even use: Folder Mount which enables you to create a folder in the internal memory which is a symbolic link to an external memory folder. For the OS that folder is seen as an internal memory folder.

hwasiti commented 6 years ago

A side question: why would you prefer to use FBReader rather than putting all your books in the cloud in Google Playbooks which let you selectively assign your choice of books to be available offline, or even using another app that can access ext SD card if cloud is not your thing? I believe there are dozens of great book readers available.

jmcollis commented 5 years ago

So the issue here is that with Android Versions from Nougat onwards, control access to files on an external storage device more strongly than usual. So if you had a "Books" directory in the top level of the device ( /storage/xxxx-xxxx/Books ) the app needs to be obtain extra permissions to write to that directory. Other apps that do this use a call to set the permission to the whole storage device and the user is presented with a dialog and request to do so in Storage Manger. This seems to be the proper way to support writing to external storage. There is however one place on the External storage device that the app can write without issue. If you go to /storage/xxxx-xxxx/Android/data/com.fbreader in the "Where to store downloaded books" section of the Directories settings. There you can create a new directoy (I called it Books) and then set that as the place to save downloaded items. This should work OK. It's a little bit of a workaround but it does work. BTW the path above is for FBReader Premium - I presume that it would need to be /storage/xxxx-xxxx/Android/data/com.geometerplus/zlibrary.ui.android for the free version.

DMcCunney commented 5 years ago

@hwasiti "A workaround would be (although not an ideal one) is to root your phone."

I prefer to root my Android devices. I have been unable to find a rooting solution that works on the device I complained about.

"A side question: why would you prefer to use FBReader rather than putting all your books in the cloud"

I have way too many books to make cloud storage feasible. You are probably thinking of hundreds of books. My "To Be Read" stack is in round thousands. My full library forced me to buy a larger USB3 flash drive to have a backup of it.

Cloud storage is dandy and I use it, but it's not the solution for this problem.

There are lots of eBook viewers for Android. I've looked at most of them. I began using FBReader in a version written in C that ran on Windows and Linux, and supported a variety of eBook formats. (A big win was support for the format used by the Plucker offline HTML viewer for Palm OS, so I could read Plucker docs on something other than my PDA.)

When I got Android devices, FBReader for Android was the logical choice. If I could find an alternative that could scan the existing eBooks directory and sub-directories on the microSD card and replicate the list I see when I select Library from FB's menu to drill down and select books, I might switch. As it is, changing readers would be far more work that problems with one device would justify

DMcCunney commented 5 years ago

@jmcollis "So the issue here is that with Android Versions from Nougat onwards, control access to files on an external storage device more strongly than usual."

The issue I posted about bites on Marshmallow, but I assume Nougat will be more of the same.

"Other apps that do this use a call to set the permission to the whole storage device and the user is presented with a dialog and request to do so in Storage Manager. This seems to be the proper way to support writing to external storage."

I concur. The problem is that FBReader on the problem device never presents that dialog and request. I have a couple of other programs on that device that do, so this is an FBReader lack. (A recent update to FBReader Premium listed correction of some notification issues as an included fix. Unfortunately, the lack of a proper notification on my device wasn't part of the fixes mentioned.)

"There is however one place on the External storage device that the app can write without issue. If you go to /storage/xxxx-xxxx/Android/data/com.fbreader in the "Where to store downloaded books" section of the Directories settings. There you can create a new directoy (I called it Books) and then set that as the place to save downloaded items. This should work OK."

The device in question won't let me do that. And I don't believe that location points to the external card, even if it did. Good thought, though.

SonicZentropy commented 5 years ago

Just ran into this on my new phone. Old phone was fine, no problems reading or writing to the SD card. New phone flat refuses to allow writes. I ended up refunding the pro purchase and now I'm trying to find a working alternative. Hopefully this gets addressed soon, so I can come back to my favorite ebook reader!

Edit - I went to tinker again, because I have no self control. For whatever reason, there is a single folder under /storage/xxxx-xxxx/Android/data/ that is writeable. Looks like one created by an ancient app on my old phone. I have no idea how that's even possible, but it happened, so FBReader apparently CAN write just fine already

oleksabor commented 5 years ago

@jmcollis thanks a lot for your hint. I've used free version on Android 7 (non rooted) without any problem, writing books to the sdcard/books folder. However after upgrade to Android 8 fb reader stopped to write files. I've ticked the Fbreader's sd permission checkbox in Android apps list but no luck.

Only using your advice I can download books from an opds catalog using the Fbreader's network library option.

unpack5 commented 5 years ago

A workaround would be (although not an ideal one) is to root your phone.

@hwasiti I've rooted and it still doesn't work. Can't even navigate to the SD card to add a folder to scan, it gives me "Permission denied".

Edit - I went to tinker again, because I have no self control. For whatever reason, there is a single folder under /storage/xxxx-xxxx/Android/data/ that is writeable.

@SonicZentropy Does this mean you can read from the external SD card? How did you achieve that?

I've ticked the Fbreader's sd permission checkbox in Android apps list but no luck.

@oleksabor Where exactly can one find that permission setting?

DMcCunney commented 5 years ago

I also had an email discussion with Nikolay, and he said they were aware of the problem but hadn't been able to fix it. It was either very difficult or they were missing something simple and stupid. (My bet was the latter.) I queried a chap at Google in the Android development group about the permissions changes in recent versions and what apps had to do to get read/write permissions on external cards. He sent me this:

the storage expert says:

--BEGIN QUOTE--

Apps can use this API to ask the user to gain access to an entire directory tree on the device, such as an attached USB drive: https://developer.android.com/reference/android/content/Intent.html#ACTION_OPEN_DOCUMENT_TREE

If they have a bunch of existing java.io.File-style code, they can do a pretty much drop-in replacement using this support library API: https://developer.android.com/reference/androidx/documentfile/provider/DocumentFile

Specifically, take the tree-style Uri granted from the first API above and pass it in here: https://developer.android.com/reference/androidx/documentfile/provider/DocumentFile.html#fromTreeUri(android.content.Context,%20android.net.Uri)

--END QUOTE--

I passed that to Nikolay. I await a new version using that sort of code. (But it's moot at the moment because the 10" tablet that was the problem child failed and requires replacement.) FBReader still works fine on my other devices.

oleksabor commented 5 years ago

@unpack5 There is app permissions in the Android 8 it can be found at Settings - Apps & notifications - FBReader - Permissions It looks like App info page from Android 4 with uninstall and force stop buttons but there are app notifications and permissions When I tap on Permissions new screen is shown with Storage option on|off Unfortunately FBReader has stopped to download files after update to Android 8 besides of Storage permission is set to allow.

unpack5 commented 5 years ago

@oleksabor I think that governs access to storage in general, not to the external SD card (as you wrote).