I'm developing an app which reads content loaded on my company's server. How can I detect if new files are loaded into the designated folder online or whether any of the existing files has been overwritten in that folder?
From what I've researched so far,
(1) FileObserver seems to be a likely solution, but can it check on a specific URL?
(2) I've used Json's Request.Method.HEAD on a single file to detect updates, but I currently have close to 500 over files (and growing) in that folder and it seems like a potential resource hog to process the header information every time the app loads.
Anyone has suggestion on what functions to use, or library which can help in this scenario?
Many many thanks!
How can I detect if new files are loaded into the designated folder online or whether any of the existing files has been overwritten in that folder?
Have the server notify your app of changes, such as via GCM.
Or, have the server publish some sort of a changelog that you monitor.
FileObserver seems to be a likely solution, but can it check on a specific URL?
FileObserver is for local files.
I've used Json's Request.Method.HEAD on a single file to detect updates, but I currently have close to 500 over files (and growing) in that folder and it seems like a potential resource hog to process the header information every time the app loads.
Agreed. Your problem is on the server. Your server needs to provide the change details in a more efficient fashion.
Create a small API that will have method smth like
List<String url> getAllChangedFiles(long timestamp) that return all files that had been changed from your date. In this case all time consuming logic (like searching for such files) will be on the server, you even could cache it for some reasons.
GCM is not a perfect solution 'cause there is no guarantee that your push notification will be delivered.
Related
I have an app that wants to have the ability to download files locally. A user can download a file (no restrictions to file type) and should be able to save it on the device so it can be used for other purposes. I would also like the user to be able to delete the file from the app (they would know which file is downloaded and which isn't, a ticker would indicate if it's backed up locally). Say it is a pdf file -- the user would want to open it with different apps or edit it if they have the ability to, or just share it via email. Considering we cannot opt out of scoped storage anymore (requirement to target 30), I got a couple of questions.
I've tried to use Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath()) and also getExternalFilesDirPath(ctx, Environment.DIRECTORY_DOWNLOADS)). While the former is deprecated, it works for me in that the Files app can be used to navigate to the file in question (and possibly open/delete the file). On the other hand, I am not being able to delete this file from my app due to lack of permissions. Obviously, the latter path is unable to be navigated to by another app (or is it? I haven't found a way, hence the question).
The other thing I've considered using is the MediaStore API but I'm struggling to see how this is an improvement over the old ways in terms of function. Disregarding moving back to manual content resolver and cursor usage, how should arbitrary files be sorted? Should I manually sort by mime types and have different methods for saving for specific media types? It sounds exceptionally tedious and counter intuitive. If this is the way, so be it, I will implement it, but it does not sound like the way to go. On the positive side, it at least sounds like a solution due to the content resolver's CRUD abilities.
I'm working on a RN app that uses a 3rd party library for the download paths, which old/new versions, respectively, use different paths (rn fetch blob and rn fetch blob util). Additionally, MediaStore API doesn't have a RN implementation as of right now, so everything would have to be done from scratch, too.
What are my options? In the short term I'm considering disabling the erase feature from the app (at least for now). Anything I am missing and should consider? Thanks in advance.
I'm creating an Android app that needs to download a set of images and audio files in order to work properly. Those files will be updated on the server from time to time. On startup, the app will check for updated files and download them.
My concern: The updates/downloads of those files must be completed in an atomic fashion, meaning that the update is successful only if all files have been downloaded. If one file failed to download (reason being poor internet connection, insufficient storage space on the phone, etc), the update should be rolled back.
I feel that implementing something like that from scratch could be a pretty big task, so I first wanted to ask if there's already a library/module, or at least a best practice for implementing something like this.
I feel that implementing something like that from scratch could be a pretty big task.
I disagree:
Your app can creat a temporary private folder (i.e. -tmp-update-20190321_122800) and download all files into this folder.
After all downlads finished without error the app can replace the original files.
So instead of searching for a transaction-multi-filie-download-lib you can use any android-download-lib and you must know how to copy/move/delete files.
I'm not sure if this is the right place to ask this question but I've looked around and couldn't find the answer.
An app that I'm building allows the user to download files, but I want to protect the URL of the files.
Is there a way to find the URL of a file being downloaded via an app?
If there is, can I prevent it somehow?
I am using download manager to download the files. Is it any different in this aspect if I write my own async methods?
Similarly, can users see the GET requests sent by the app?
Any info or direction to pages that talk more about this is appreciated.
Thanks.
I am using download manager to download the files. Is it any different in this aspect if I write my own async methods?
If you are using DownloadManager to download files, depending on how you're using it, yes, users could get the URL quite easily, since the downloads app may show it. (this depends on how you're actually doing the download with DownloadManager, I'd need to see your code in order to tell you for sure.
If you write your own code to do the download, then yes, it will be harder for users to figure out where the file is being downloaded from.
Is there a way to find the URL of a file being downloaded via an app?
Even if you don't use DownloadManager, it is still possible, just more difficult. If users are using a firewall which logs network accesses, or something similar, your URLs will be logged and visible. Similarly, users can use a tool like Wireshark to see all networ traffic going between the device (and your app) and the server your data is coming from. On rooted devices, users can also install monitoring tools.
Similarly, can users see the GET requests sent by the app?
Yes, using the same tools (eg. wireshark), one can see exactly what URLs your app is requesting.
If there is, can I prevent it somehow?
No. If someone wants this information, they will get it, all you can do is make it harder. For starters though, I'd recommend not using DownloadManager and writing your own code instead, and using HTTPS. Additionally, you could try to ensure that your URL only works for users which have been authenticated in some way - check this question for possibilities.
Let me know if you have any other questions, and I'll try to help.
I'm developing an app which stores items for the user, and the user has an option to sync with Google Drive. Each item consists of text and image.
My current method is to save a .json and .jpg file for each item internally to the device, and then once onConnected is called from Drive APIs, upload these files to the user's APP folder in Google Drive. Similar with deletion, I would create a flag that an item with name 'foo' has been deleted, then try to see if the files 'foo.jpg' and 'foo.json' exists in Drive, and delete accordingly.
This works for me now, but often I get the app to crash because of googleApiClient errors and I realize that this is not an efficient method. So what I'm wondering is whether any of you guys know a more efficient method to do this?
In the ideal world I would love to have something like this: I save the files for each item to the device internally, and a library tracks these and sync Drive accordingly.
Thanks for advice!
Based on the fact that you are referring to 'onConnected' and 'googleApiClient', I assume that you're using GDAA not the REST Api.
You should re-think the idea of using file names when dealing with GooDrive. They are not unique in GooDrive and the GDAA's latency will sooner or later cause a problem with presence of multiple files with the same name, created by ubiquitous construct:
if file.name not exist
create file.name
The fact that you use APP folder makes debugging even harder since you don't have feedback by looking at the http://drive.google.com.
You should refer to your files by the DriveId (if using only a single Android device) or by the ResourceId (if you intent to send/broadcast the IDs to a different device/app). And if you decide to use the ResourceId, make sure you handle the latency issues caused by delayed GDAA's promotion of objects to the Drive.
This certainly does not fully cover your question, but it is too broad to answer correctly anyway.
Good Luck
I'm using the Google Drive Android API (yes I know its still in developer preview), to create a file on Drive that can persist data across all of a user's devices.
https://developers.google.com/drive/android/create-file
So, use the app on your phone:
-Check that the file exists (filter by filename and not in trash)
--If exists then read and update local sqlite with data
--If not exists then create new file, and write data from sqlite. Then request sync.
-When user changes data, open file again, write contents and commit/sync.
I'm finding situations when testing where I run on my phone, and then on my tablet, and there happens to be multiple files created of the same name and my app gets confused when opening. I'm guessing there were duplicates because there was a delay in the sync and the 2nd device didn't find the existing file so created a new one.
So, now I'm thinking, I pull in all files with that name (not marked trash) and merge them, then mark trash on all but one of them and call that the current. This will leave many files in the trash as time passes.
Couple of questions:
Is there anyway to create a file with a unique name, or pull by some unique handle. The duplicates are making things a hassle to use this Drive product.
Is there anyway to delete a file, not mark for trash, but actually delete. After a merge, I don't want to leave hundreds of files marked for trash on someones drive after months of use.
Am I missing something obvious here? All I want to do is continually overwrite a file by the last device to save data and call that the master copy. Then let other devices know that they should refresh when they run. Right now, I have a network tool app, but I'm also creating a game and was hoping to leverage this same mechanism to save/persist game state across devices....at this point I'm not so confident that Drive is the proper means.
As you've discovered title's are not unique in Drive. However, each item in Drive does have a unique identifier. In the Android API, the DriveId is the representation of this. (In the web API its the resource id).
Once you create the file, you can save the DriveId in local preferences so that next time you can just look it up by the ID. This will guarantee that you will always have the same file on the same device.
On other devices, you can first do a query by title to determine if it exists already, and then save off the DriveId if it does.
Google Play Cloud Save is designed for lightweight persisting of save state across multiple devices including conflict resolution and was built originally for games (although any app can use it). This seems like a more likely fit for what you want to do than trying to work with the full file system approach that is Google Drive.