My app is setup to allow backups to be saved to a Google Drive appdata folder. It all works perfectly well on the same device. When I make a backup, delete the app's data, then restore it all works.
However, when I try to backup on one device, then install on another and attempt to restore there are no files found. Same goes for when I uninstall the app on the original device, reinstall it on the same device and attempt to restore. Both cases result in no files being found despite the fact that I see there are files in the appdata folder when I log into Google Drive.
I read somewhere that you must use the RESOURCE_ID instead of the DRIVE_ID of a file for it to work between devices since a DRIVE_ID will be different from device to device. However the only way I've seen how to get the RESOURCE_ID is by using the driveId.getResourceId(), and I can't get the proper DRIVE_ID from another device.
tl;dr: how should I go about retrieving the proper file from the appdata folder that was created by another device/installation?
I have a database backup option in my app as well. I implemented it using the new Google Drive Android Api and what's more important, it works perfectly fine from one device to another.
Here's how I did it and what I recommend:
Before reading or writing anything to Google Drive, call requestSync to make sure everything is synchronized and up to date (see how to use it here).
Retrieve your files by name using a query instead of identifiers. As Google Drive allows multiple files with the same name, order your query by date and use the newest one.
To avoid creating multiple backup files with the same name, use a query to find if the backup file already exists on Google Drive and if it does, open it and overwrite it.
This is the point I guess you won't like: I recommend not using the Appfolder... for the moment. Google has acknowleged there might be some synchronization issues with it when uninstalling and reinstalling the app. I tried to use the Appfolder as well in my app without success and I finally ended up creating an ordinary folder in Google Drive. With that said, you can try the first three recommendations before adopting this one.
I hope these points can help with your implementation. If you need anything else, just tell.
Related
in google drive, there's a tab named "backups" that contains data from old android phones I have.
These backups are not downloadable.
Is there a way to download these backup files? is there a way to get the information inside the backup files? ( API requests )
I know that for the Whatsapp backup-file there is a different API (because it's not downloadable like the others).
There's no mention of accessing the backup folder in Drive API. But, if you're referring to a special folder called App Folder which is only accessible by your application, then you can. Check the Get authorization to use the App Folder.
I tried following both the documentation:
https://developers.google.com/drive/android/pinning
And the demo:
https://github.com/googledrive/android-demos/blob/master/app/src/main/java/com/google/android/gms/drive/sample/demo/PinFileActivity.java
but I am still very confused on how to sync a pinned file between my local device and Google Drive.
According to the documentation:
Pinning a file causes the latest version of that file's contents and metadata to be downloaded to the local device whenever a new version is available.
I implemented the code provided, but they only show to set a file as "pinned" without more explanation.
When and where do we specify where those pinned files must be downloaded on the local device?
I created test files that are well listed in the remote Google Drive, but I have no idea how those pinned files can be retrieved automatically on the local device as explained in the guide.
The demos provided are just too simple and limited...
I actually succeeded to accomplish what I wanted, I had to understand how it worked through several tests.
In my app I actually use the specific app folder to interact with Google Drive:
Drive.DriveApi.getAppFolder(mGoogleApiClient)
This folder on Google Drive is accessed by the app only.
At first I thought I had to specify a folder on my device to indicate where the files from the Google Drive app folder should be downloaded but it does not work that way.
You just have to access this app folder directly and check if there were any changes inside it since the last time it was accessed.
So basically when the files were changed I copy them where I need in my app file structure.
I want to protect my application from being copied by users from device to another device. I know that wont be possible because once the apk is installed any third party application may be able to copy or extract the apk. I mostly care about the private data of the application rather than the apk itself. So, my questions are :
1- Can I protect the apk from being copied to another device by the user ?
2- If user copied an application from device to another (e.g. via third party app or by bluetooth) will he/she be able to copy the private data as well ? If yes, can I protect that ?
Thanks in advance.
To answer briefly, AFAIK, No.
Regarding the single questions:
if device is rooted it's really easy to access the /data/app/ dir and copy your apk, even on the device itself.
For un-rooted devices you need to issue some adb commands. For reference, look here:
https://stackoverflow.com/a/11013175/1865860
https://stackoverflow.com/a/17135554/1865860
How to get a list of installed android applications and pick one to run
the same applies to /data/data/com.example.app/ for the private app's data. Just different folder and possibly many files to copy.
Basically the difference it's not in having root or not, but in the ease of realization.
you can use google licence in your app even if its copied from rooted device it wont work until its downloaded from playstore
second /data/data/<packagename>/ can be copied from rooted device
Android introduced the Multiple Users feature in 4.2 (Jelly Bean MR1) and its documentation states:
From your app’s point of view, each user is running on a completely separate device.
And here is a quote from the Environment.getExternalsStorageDirectory() and getExternalStoragePublicDirectory() methods doc:
On devices with multiple users (as described by UserManager), each user has their own isolated external storage. Applications only have access to the external storage for the user they're running as.
Could it be true that there really is no reliable way to communicate data between users on a single device without using the network as mediator? I'm looking for solutions that don't rely on quirks of how the device's file system is laid out by a manufacturer. Also, for security, the sharing should be internal to my app.
Even if file sharing is indeed impossible, is communication via intents somehow possible?
There are use cases for this. Use Case 1: let's say I'm writing an input method app that requires a 100MB dictionary file. I'd like to code things so that if User A downloads this file, then User B can access it also without needing to re-download. Use Case 2: let's say I'm writing a fun Leave My Wife a Note app that allows User A to type messages that will appear next time User B logs in (without using the network).
This thread on a separate site proposes a solution, but their method seems undocumented and possibly unreliable. And there are a few other SO questions that have a title similar to this one but are actually discussing different topics.
OBB Folder (/sdcard/Android/obb) is used to share files and folder between the multi users. But OBB folder not shown in my second user (One plus 5 mobile). So I have tried to create an OBB folder in Android folder (/sdcard/Android/) in second user and "BOOM" it worked. Now i am able to access the shared files in second user. Try this trick if OBB folder not shown in your second user.
OBB files (stored in /sdcard/Android/obb) and used as expansion files in Google Play are shared between all users by design, as they are fairly large. If you Input method uses expansion files, the downloaded data will be shared automatically. You can send broadcasts to other users but that requires the INTERACT_ACROSS_USERS permission, which is reserved for system applications.
I also had the same question, and have tried various approaches such as using /sdcard/Android/obb but it does not work in Android 10. So I followed below approach, and I am able to copy files seamlessly between users.
Login to the User from where you would like to copy files from (lets call U1)
Run FTP Server using any application of choice like MiXplorer / ES Explorer etc... Note down the details of the port#, username, password etc... and point it to /sdcard
Switch user, to where you want to copy files to (lets call U2)
Install the FTP browser. If you use MiXplorer / ES Explorer, they will allow you to add a FTP share
Use ftp://localhost:2121 assuming the port is 2121, if not change it accordingly and add the FTP share
Open the FTP share and you can see all the files & folders of U1 here
Copy across to your heart's content !
I know that similar questions have been posted before, but I believe there has not been an answer for my exact use case.
I have a trial and a full version of my Android app. When the user buys the full version, both versions should share their settings. Changes in one app should show up in the other app as well. When one app is un-installed, the settings shall be preserved for the other app. It's not a one-time import because the user might not uninstall the trial app and could even continue using it.
Both apps use the same shared user id and run in the same process. However, when I call getFilesDir(), the directory returned contains the package name of the app, so the directories for storing files used by the two apps differ. How can I have both apps use the exact same file without using external storage?
How can I have both apps use the exact same file without using external storage?
That will not meet your objective:
When one app is un-installed, the settings shall be preserved for the other app
Given that objective, by definition, you cannot be using a single file that will be removed on uninstall, as if the user uninstalls that app, the other app is broken.
Your choices are:
Use external storage, specifically not getExternalFilesDir() or getExternalCacheDir(), or
Have each app maintain its own copy of the file, using some mechanism to keep the changes in sync, or
Switch to in-app purchases, so you do not have separate free/paid apps, or
Abandon your "both apps should share their settings" objective
You need to save those preferences either to a file or database if you want them to remain after the process containing all the components close.
A quick way, if you have this in your control, is to change all the uid's for your applications to the same and use the file api's for reading and writing from a file or the database. Using a database is just a step away from using a content provider though... which is probably the correct most solution.