I have been looking at a few different tutorials, however am really struggling to see exactly how the Expansion Files can be firstly copied to a location that the user cannot access adn the how to use them in my actual app.
I will have a lot of key images within the Expansion file and therefore would also need to prevent users from playing the game until everything is downloaded.
Finally, I would have to also access a density based section for a lot of the images, along with a handful of raw files such as videos, this is what I currently have to work out which folder to open within the extension files.
String ExpansionFolder = "";
switch (getResources().getDisplayMetrics().densityDpi)
{
case DisplayMetrics.DENSITY_MEDIUM:
ExpansionFolder = "mdpi";
break;
case DisplayMetrics.DENSITY_HIGH:
ExpansionFolder = "hdpi";
break;
default: // This cover XHDPI, XXHDPI, TVDPI
ExpansionFolder = "xhdpi";
break;
}
Some sample code that i can use would be much appreciated.
I don't have sample code, because i haven't used expansion files myself, but specific answers to your questions do seem to be available at Android Developer APK Expansion Files page.
how the Expansion Files can be firstly copied to a location that the user cannot access adn the how to use them in my actual app.
from the "Storag Location" section of the Android developer page on expansion files (APK Expansion Files):
When Google Play downloads your expansion files to a device, it saves them to the system's shared storage location. To ensure proper behavior, you must not delete, move, or rename the expansion files. In the event that your application must perform the download from Google Play itself, you must save the files to the exact same location.
The specific location for your expansion files is:
[shared-storage]/Android/obb//
[shared-storage] is the path to the shared storage space, available from getExternalStorageDirectory().
[package-name] is your application's Java-style package name, available from getPackageName().
For each application, there are never more than two expansion files in this directory. One is the main expansion file and the other is the patch expansion file (if necessary). Previous versions are overwritten when you update your application with new expansion files.
If you must unpack the contents of your expansion files, do not delete the .obb expansion files afterwards and do not save the unpacked data in the same directory. You should save your unpacked files in the directory specified by getExternalFilesDir(). However, if possible, it's best if you use an expansion file format that allows you to read directly from the file instead of requiring you to unpack the data. For example, we've provided a library project called the APK Expansion Zip Library that reads your data directly from the ZIP file.
Note: Unlike APK files, any files saved on the shared storage can be read by the user and other applications.
From http://developer.android.com/reference/android/content/Context.html#getExternalFilesDir(java.lang.String):
getExternalFilesDir
Returns the absolute path to the directory on the primary external filesystem (that is somewhere on Environment.getExternalStorageDirectory()) where the application can place persistent files it owns. These files are internal to the applications, and not typically visible to the user as media.
I will have a lot of key images within the Expansion file and therefore would also need to prevent users from playing the game until everything is downloaded.
From the "Downloading the Expansion Files" section of APK Expansion Files:
In most cases, Google Play downloads and saves your expansion files to the device at the same time it installs or updates the APK. This way, the expansion files are available when your application launches for the first time. However, in some cases your app must download the expansion files itself by requesting them from a URL provided to you in a response from Google Play's Application Licensing service.
The basic logic you need to download your expansion files is the following:
When your application starts, look for the expansion files on the shared storage location (in the Android/obb/[package-name]/ directory).
If the expansion files are there, you're all set and your application can continue.
If the expansion files are not there:
a. Perform a request using Google Play's Application Licensing to get your app's expansion file names, sizes, and URLs.
b. Use the URLs provided by Google Play to download the expansion files and save the expansion files. You must save the files to the shared storage location (Android/obb/[package-name]/) and use the exact file name provided by Google Play's response.
Note: The URL that Google Play provides for your expansion files is unique for every download and each one expires shortly after it is given to your application.
In addition to the LVL, you need a set of code that downloads the expansion files over an HTTP connection and saves them to the proper location on the device's shared storage. As you build this procedure into your application, there are several issues you should take into consideration:
The device might not have enough space for the expansion files, so you should check before beginning the download and warn the user if there's not enough space.
File downloads should occur in a background service in order to avoid blocking the user interaction and allow the user to leave your app while the download completes.
A variety of errors might occur during the request and download that you must gracefully handle.
Network connectivity can change during the download, so you should handle such changes and if interrupted, resume the download when possible.
While the download occurs in the background, you should provide a notification that indicates the download progress, notifies the user when it's done, and takes the user back to your application when selected.
To simplify this work for you, we've built the Downloader Library, which requests the expansion file URLs through the licensing service, downloads the expansion files, performs all of the tasks listed above, and even allows your activity to pause and resume the download. By adding the Downloader Library and a few code hooks to your application, almost all the work to download the expansion files is already coded for you. As such, in order to provide the best user experience with minimal effort on your behalf, we recommend you use the Downloader Library to download your expansion files. The information in the following sections explain how to integrate the library into your application.
You may also find Steps to create APK expansion file useful, if you haven't already seen it, though I don't know if Google has changed anything regarding expansion files since that question and its answers were posted.
Related
Android Api 29 has big changes regarding files and folders.
I have not found a way so far to create a folder in the internal storage that is public visible.
Every folder I create can be seen by my app only.
I write an app that creates data files that shall be picked up by other apps, for instance the Total Commander to copy them to a destination.
Everything worked fine until I activated Api 29. Some of my clients DO use pixel phones and they use Android 10.
How can I create a folder and files in Android 10 that are public?
This has been deprecated:
Environment.getExternalStorageDirectory();
Environment.getExternalStoragePublicDirectory(type);
and when I use
File root = context.getExternalFilesDir(null);
The created files can only be seen by my app.
How can I achieve the behavior that was valid before Android 10?
Thanks in advance.
when I use File root = context.getExternalFilesDir(null); The created files can only be seen by my app
They can be seen by any app that uses the Storage Access Framework (e.g., ACTION_OPEN_DOCUMENT), if the user chooses the document that you place in that directory.
I write an app that creates data files that shall be picked up by other apps
Other apps have no access to external or removable storage on Android 10, except in the limited directories like getExternalFilesDir() or via non-filesystem means (ACTION_OPEN_DOCUMENT, MediaStore).
How can I create a folder and files in Android 10 that are public?
Use getExternalFilesDir() and related methods on Context. Or, use ACTION_CREATE_DOCUMENT or ACTION_OPEN_DOCUMENT_TREE and use the Storage Access Framework. In either case, the resulting documents can be used by other apps that also use the Storage Access Framework.
Starting from Android 10, you should use SAF, and let user choose the directory using ACTION_OPEN_DOCUMENT_TREE.
If you need a simple example. You can find it here
Alternatively, you could use requestLegacyExternalStorage = true in manifest when your app is not newly released. But, this is something that should not be used for future release, as this is a short-term solution provided by Google.
Note: In future releases of Android, user will not be able to pick the whole external file directory and Downloads directory, so unfortunately, keep in mind that we are not going to have access to these as well! For more information you can click here
in my app I handle obb extension files download and hosting manually.
I did not upload it in app store, because I use more than one obb files depending on the specific user needs, so I cannot just use a single obb file that is uploaded on play store for the user to download.
I also manage manually obb files rename, so they can be usable for the app, as user can have more than one obb files downloaded and switch between them while app is renaming the obb accordingly.
My issue is, that after a normal update through Play Store, the obb file gets deleted, thus requiring user to re-download it.
I would be happy to know why this is happening or a way to avoid it.
Please note, that I don't have any obb file uploaded on Play Store, because it wouldn't serve my needs. Once user opens the app, chooses appropriate extension to use and then download it through my app.
Thank you!
If your OBB is not downloaded from the Play Store, then I wouldn't stick it in the Play OBB directory. The directory is <shared-storage>/Android/obb/<package-name>/ and the Play store assumes it has a duty to keep this directory clean as part of the update process, so the user isn't left with a bunch of unnecessary OBB files.
If you want to download the files yourself, and take care of the updates yourself, just put the files in another directory. I'd recommend reading the docs on developer.android.com to help you choose the best location.
I'm opening many types of files using external applications which are available on phone. For security reasons I need to delete this file when the external app does not need it. How can I check if I can safely remove file which are used by third app ?
First of all you need to know which files are used by the third app. You can simply do it by analyzing, (decompiling, if needed) the source code of the application. After knowing all the files used by the third party app you need to check if the third party app actually running or not, because the third party app might use some temporary files, which could be removed when it's no longer open.
If you just want to make a simple cleaner, which cleans the trash of all the apps, then you should simply just remove certain file types (like .tmp files) and remove the cache of the apps.
First of all, I think there is no 100% way to determine if file is not used by another application.
I you are asking about files in sandbox of other apps, by the way you be able to remove such files because they have granted permissions only for app that they are belong to. So you need root access in this case.
You can remove file like cache,tmp ... files like system app manager does. If third-party is built correctly this should not affect application.
Also another method is to determine how often file is being used is based on unix file timestamps, they are
Access - the last time the file was read
Modify - the last time the file was modified (content has been modified)
Change - the last time meta data of the file was changed (e.g. permissions)
You can check for example the date when app was installed, than check access time of the file and determine does the application require this file.
But again there is no 100% guarantee that you won't brake an app.
For my app I download some resources like images and small mp3 and save them in the external storage (at /mnt/sdcard/Android/data/com.example.packagename/cache for example.
But I don't want that if a user explores that folder finds all the resources in a "common format".
One of my options is to remove the extensions (I know it's easy to guess the file type even if it have not extension but is a basic protection against most users)
I have noticed most of the programs that have their caches at the external storage don't have their cache as raw files.
I wonder if is there any easy way (with some class or something) for "hiding" those files and access them transparently or I must implement my own system
(It is not vital that these files remain hidden but I'd like keep those resources "unknown" unless a user takes a special trouble to see them)
Thanks
You can use ObjectOutputStream, it will save data as binary data, when the user tries to open it, even using Text Editor, it will show corrupted data, and here some sample how to use it Writing objects to file with ObjectOutputStream
I am working on rewriting a Java web application to Rails which relies heavily on collections (100's or 1000's) of large (50-100MB) TIFF files. In the Java version, the user specifies a local root path (such as a mounted SAN drive) for these files in the application configuration, and they are read by the application using these paths. The application also writes new files to those paths.
Essentially, users must be able to add files to the application in two ways:
1) Specify a storage location as the 'root' for a collection of TIFFs, which could already contain many TIFFs. These are then processed.
2) Upload new files to an existing collection, which would then be written to the above path and processed.
I guess the gist of my question is: What is the standard way to store, retrieve, and write to such large files in the context of web applications? Should the availability of a local file system with enough storage space be assumed, or is there a better way to do it?
I would look into storing the files with paperclip or carrierwave. They are two great file upload and management gems that allow you to store your files in many different ways.
I have included links to two great sceencasts above and here are the github pages for paperclip and carrierwave.