LibGDX Android create internal files on installation - java

I need several files to be in the internal directory of my Android app on installation.
I could theoretically just copy them from the assets folder but that is not really convenient.
The files would be to store settings and progression.
How could I create these files?

As mentioned in the comments, during installation, the device does nothing but simply copy the app itself. If you want to do anything else, that's the job of your application.
Use local storage for this purpose (will be deleted on uninstall, on the desktop target, this is the same as internal.)
You could either:
check whether the files exist, and copy them if they do not
This is the more reliable choice, as in the (rare?) case that the files are deleted, they will be replaced.
#Override
public void create() {
...
for (String file : filesToCopy) {
final FileHandle handle = Gdx.files.local(file);
if (!handle.exists()) {
// copy to handle
}
}
}
store whether or not the app has already been launched at least once, and if the key does not exist, copy the files
You can use Preferences for this:
#Override
public void create() {
...
final Preferences prefs = Gdx.app.getPreferences("prefs");
if (prefs.getBoolean("newInstall", false)) {
for (String file : filesToCopy) {
final FileHandle handle = Gdx.files.local(file);
// copy to handle
}
}
prefs.putBoolean("newInstall", true);
prefs.flush();
}

Related

How to delete a folder on Android 11?

I have a doubt, how I can delete a folder on Android 11 (or 10)?
Have much answers here on Stack how to do it, but nothing of worked.
This code worked for me on Android 5:
public static boolean deleteDir(File dir) {
if (dir.isDirectory()) {
String[] children = dir.list();
for (int i=0; i<children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
}
// The directory is now empty so delete it
return dir.delete();
}
On newest versions of Android it not work. I noticed that there are applications that can to do this, so I imagine it is possible. Any answer about it?
Android has done much to change its permission models around file access since Android 10 and 11. The preferred approach is to use Scoped Storage APIs.
Many of the old file read/write permissions are on life support and will no longer work. If they do continue to work, then must justify to Google why you need them, and then go through a security approval by Google. You will only be granted approval if you app is classified as a file browser application, or the like.
Basically, the new model is to use Android's file browsers to gain access to read/write/update a particular file that the user selects, and defer the rest of the file management to Google's first-party applications. The access you get is based on what the user selected in the first-party file browser. You are then handed a URI back to your application with the proper permissions to perform the intended action, such as read/write/etc...
You may find this video useful:
https://www.youtube.com/watch?v=RjyYCUW-9tY
Have you tried Context.deleteFile() ?
getApplicationContext().deleteFile(filename);

How to show only videos folder?

I am working on an android app, please tell me, How to show only videos folder?
this code shows all folder in my device, But I want to show only videos folder. How to do that?
here is my code
public class MainActivity extends ListActivity {
private List<String> listfile = new ArrayList<String>();
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
File fileroot = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
File[] files = fileroot.listFiles();
FileFilter fileFilter = new FileFilter() {
public boolean accept(File file) {
return file.isDirectory();
}
};
files = fileroot.listFiles(fileFilter);
System.out.println(files.length);
if (files.length == 0) {
//
} else {
for (int i = 0; i < files.length; i++) {
listfile.add(files[i].getName());
}
ArrayAdapter <String> dis = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listfile);
setListAdapter(dis);
}
}
}
There's no simple way to do this in Android. It's a mistake to assume that there will be only one directory videos/ on a particular device. Even if there is, you can't assume that video files will be stored there, and nowhere else.
If you really only want to scan one directory, then a simple approach is to prompt the user for the location when your app first starts, and store the selected location for future use. Many android apps that handle media do, in fact, take this approach -- although they might allow the user to select multiple locations.
If you want to list video files, rather than the contents of a specific directory, then the way to do this is to query the Android media store. This store is (or should be) updated whenever files are transferred to the device. Each file is tagged with various attributes according to various inspection methods built into Android. Modern Android versions are pretty good at recognizing video files, although that wasn't always the case.
To use the media store, you'd do a query on the ContentResolver for a specific Context, testing for a flag that indicates that the content is video. Then you'd iterate the results, extracting the various pieces of information you need.
To be honest, I've not used the Android media store for video, although I have for audio. I think the basic principles will be the same. I have some sample code for audio queries here, if that's any help:
https://github.com/kevinboone/androidmusicserver/blob/master/src/net/kevinboone/androidmusicplayer/AudioDatabase.java

I don't understand what happens on file.exists() for android on eclipse

i am creating an application for android in eclipse.
i have a chat application in which user's contact's images are downloaded in sdcard and are put in a HashMap (url, localAddress), when i want to load contact list, for any contacts I use a function to find address of contacts' pictures on sdcard, three different state may occur
1- image found on sdcard then return path.
2- image don't download before and HashMap return null, then download it.
3- HashMap return a path but user deleted image from sdcard then remove key from Hashmap and download again.
my code:
public static String findFile(Context ctx, String url, String type)
{
try
{
String value = globalVars.addresses.get(url);
if(value != null)
{
File ff = new File(value);
if(ff.exists())
return value;
globalVars.addresses.remove(url);
}
globalVars.enqueueJob(ctx, new globalVars.downloadJob(url, url, type));
return null;
}
catch(Exception ex)
{
Log.e("Find File", "Start");
Log.e("Find File", ex.toString());
ex.printStackTrace();
return null;
}
}
but when i delete an image it download more and more .
function enqueueJob :
public static void enqueueJob(Context context, downloadJob dj)
{
if(inQueue.get(dj.getAddress())!= null && inQueue.get(dj.getAddress())== true)
return;
downloads.add(dj);
inQueue.put(dj.address, true);
FileUtils.doDownload(context);
}
It work's fine for pictures don't download yet and pictures that download and don't delete yet.
Your title is confusing as it indicates you suspect the File.exists as the problem. Looking at your code, the fact that deleted images are added to download queue means File.exists works fine at least the first time. Otherwise, you would not even add it to the queue. Now the question is what happens when it is added to queue and downloaded. Check your code to make sure that it added back to the map properly. In your code, something should be added to the download queue only under two conditions: one if nothing in the map and the other is whatever in the map is deleted. So either it is not added back properly or may be a race condition where your File.exists is happening before the download is completed fully and you are adding it back to the queue again.
Good luck.

Why does it require a reboot after copy/cutting/pasting a file/folder?

I am working on a small File manager to get the hang of things on Android and I have cut/copy/paste operation. It seems to work fine, but I run into issues with pasting things. On my app it is displayed fine, but for it to be recognized by other apps, it requires that I reboot the phone. For example, if I cut/paste an image from the download folder to the DCIM folder, the gallery app does not display that image unless I reboot the whole phone. I am using an algorithm that takes data byte by byte. Its extremely inefficient, but I am not totally sure how to implement a faster algorithm.
Thanks.
No actually you wont need to reboot our phone. When you copy an image and paste it to other location your newly copied media file is not added to the android's ContentResolver. So you should scan your data using the class MediaScannerConnection
Eg:
When you paste a file you have the file right ?
Modify as your wish, this works fine
private void scanImage(File targetLocation) {
// Scans the media to load images
String mimetype = Utility.getMimeType(targetLocation.getAbsolutePath());
if(mimetype.contains("image"))
{
MediaScannerConnection.scanFile(context, new String[] { targetLocation.getPath() }, new String[] { "image/jpeg" }, this);
}
}
UPDATE
Callback should be like
either you can implement OnScanCompletedListener in your class and add unimplemented method, So you can pass this as callback OR you can use
OnScanCompletedListener listener = new OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
// you will get the callback here
}
};
and pass listener as callback

How to make Android app automatically configure w/ debug vs. release values?

I'm working on an Android app, specifically one that uses the Facebook Android SDK. In development mode, I'm working with a test Facebook app that goes by one ID. However, in release mode, the app will be working with second Facebook app with a different ID.
I'm wondering how most Android (or Java might be a suitable enough realm of knowledge) developers here go about having their app automatically build with debug vs. release values. An ideal solution does not involve a manual switch (e.g.: switching public static final DEBUG = false; to true) before building.
It's been a while since you asked but I thought I'd share how I'm doing it.
Like Sebastian hinted, an Ant script can handle that change for you and generate the static final constants that you're looking for. You can configure IntelliJ or Eclipse to make it almost seamless.
I tried to detail the different steps I took over here, let me know if it helps. I know I never have to make any manual changes before releasing, and it's a nice relief!
In eclipse ADT 17.0 and above there is a new feature for this. Check the BuildConfig.DEBUG that is automatically built with your code.
For more information see http://developer.android.com/sdk/eclipse-adt.html
I can't recommend the IMEI method... the main problem with it is that not all Android devices will have IMEIs. A better way is to examine the signature used to sign the .apk.
// See if we're a debug or a release build
try {
PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);
if (packageInfo.signatures.length>0) {
String signature = new String(packageInfo.signatures[0].toByteArray());
isReleaseBuild = !signature.contains("Android Debug");
}
} catch (NameNotFoundException e1) {
e1.printStackTrace();
}
I use a slightly more mundane method (in case you're still interested in solutions).
At application launch my application checks for the existence of a text file stored in /sdcard/. Each application I have looks for a specific file like "applicationdebug.txt". If the file exists, then the application goes into debug mode and starts being verbose with log statements and using my debug Facebook key, etc.
Then I simply remove (or rename) the file to on the device to see how the application performs in release mode.
Usually you will use 1 or 2 devices for debugging only. So you can set the DEBUG switch based on the Devices? So you can simply use the IMEI.
add a new Application class to your project and have it initialize the field (suspect to put it in a Const class).
In your Applications onCreate method, call Const.setupDebug(getApplicationContext());
Implement the setupDebug like this
public class Const {
private static boolean debug = false;
public static boolean isDebug() {
return debug;
}
private static void setDebug(boolean debug) {
Const.debug = debug;
}
private static String [] DEBUG_DEVICES = new String[] {
"000000000000000", "gfjdhsgfhjsdg" // add ur devices
};
public static void setupDebug(Context context) {
Arrays.sort(DEBUG_DEVICES);
TelephonyManager mTelephonyMgr = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
String imei = mTelephonyMgr.getDeviceId();
if (imei == null) imei = "000000000000000";
if(Arrays.binarySearch(DEBUG_DEVICES, imei) > -1) {
setDebug(true);
}
}
}
Switch from constant field to constant Method.
Const.isDebug()
With Eclipse I create 3 projects in the workspace :
ApplicationProject
It is a library project
Contain all source code
In values/refs.xml I add
<bool name="debug_mode">true</bool>
ApplicationProjectDEBUG
Use ApplicationProject
Overide AndroidManifest and other xml file with
developement specific config
In values/refs.xml I add
<bool name="debug_mode">true</bool>
ApplicationProjectPROD
Use ApplicationProject
Overide AndroidManifest and other xml file with
production specific config
In values/refs.xml I add
<bool name="debug_mode">false</bool>
I signe APK from this project to put on the store

Categories

Resources