I have an app which has a .db (sql database) inside the "assets" folder.
When I need to update this database, I simply copy the new version in the "assets" folder, change the user version of the .db file and rebuild the apk. At runtime the application deletes the file in memory and copy exactly the one in the "assets" folder, then it checks if the version of this file is greater than the last one it had in memory (in another database) and, in that case, it does some stuff (which I'm skipping, since is not the point of the question).
The problem is: my application seems to ignore this new file, maintaining the old file in the "assets" folder, so naturally no change is detected.
It seems like my new file is not present in the apk, but only in devices with Android 9.
Is something changed with the usage of the assets folder that I am missing?
How can I arbitrarily update a file inside my apk when packing and upgrade?
This exact process works fine for older devices, then I had to upgrade the target sdk version to 28 and I got this problem while testing on an Android 9 (Pie) device.
Here I delete older file:
File l_DatabaseDir = p_Context.getDir("Database", Context.MODE_PRIVATE);
File l_DatabaseFile = new File(l_DatabaseDir, "MainDatabase.db");
File l_PlayersFile = new File(l_DatabaseDir, "players.db");
l_PlayersFile.delete();
Here I copy the file from the assets folder:
try
{
InputStream inputStream = p_Context.getAssets().open("players.db");
//Create the file before
OutputStream outputStream = new FileOutputStream(l_PlayersFile);
byte[] buffer = new byte[4096];
int length;
while ((length = inputStream.read(buffer)) > 0)
{
outputStream.write(buffer, 0, length);
}
outputStream.flush();
outputStream.close();
inputStream.close();
} catch (IOException e)
{
e.printStackTrace();
}
Finally I try to get the current version of the db:
m_PlayersDatabase = SQLiteDatabase.openDatabase(l_PlayersFile.toString(), null, SQLiteDatabase.OPEN_READWRITE);
int playersVersion = m_PlayersDatabase.getVersion();
Result on android 9: db version is the same as the first apk installed
Result on android 8: db version is the one of the file included in the new apk
EDIT: after further investigating it seems that the problem is more related to android memory, because simply changing the database file name (basically the destination of the copy)
l_PlayersFile = new File(l_DatabaseDir, "newplayers.db");
makes the application read the correct file also in android 9, so it looks like maintaining the same file name as the old one is causing the problem (Even if both the deletion and the copy of the new file are completed successfully).
So the assets folder update is fine.
The issue is only postponed to the next update though, since using again the name "newplayers.db" causes the exact same problem.
Generating a random name at every opening is quite brutal as workaround, any ideas?
Solved as I stated in the edit: copy the file from the assets folder with a different name (in my case with a timestamp).
You can change the assets folder's name eg:dist->dist1,then assets will be upgraded.
Related
An empty database file with the same name exists BEFORE we copy it from the assets folder.
android.database.sqlite.SQLiteException: no such table:
This error message is legitimate because an empty database exists in our data directory with the same name. Although we have not copied it yet.
How is our database file being created?
Why does it exist even if we have not called or instantiated our Database Helpers?
Using the same SQLiteHelper classes for all previous versions with no issues.
Running on Android 9 Pie causes this error message after a clean install of our Android app that uses an existing database in the assets directory. Normally when this file does NOT exist in the data directory it is copied then opened.
Checked and rechecked, the file exists BEFORE our call to move it from our assets directory.
When checking the Android 9 Pie data directory, our SQLite database file already exists. This is after a new install AND clearing cache & data
To repeat what we are seeing.
Settingsā¦ Apps & Notifications
Select our app
Storage
Clear Cache + Clear Storage
Uninstall the app.
Launcher Activity "SplashActivity" onCreate()
String mName = "myawesomedatabase.db";
String mDatabasePath = this.getApplicationInfo().dataDir + "/databases";
File file = new File (mDatabasePath + "/" + mName);
Log.i("DATABASE", "##### SplashActivity.getData() " + mDatabasePath + "/" + mName);
if (file.exists()) {
Log.i("DATABASE", "##### SplashActivity.getData() FILE EXISTS!!!");
}
Repeating the above and NOT uninstalling the app, copies the file properly. It is ONLY on new installations.
We have confirmed we are not hardcoding the data directory. Researching this we learned that the database directory has changed.
From: /data/data/com.___._____/databases/
To: /data/user/0/com.____.____/databases/
Referencing this article that helped this discovery.
Android P - 'SQLite: No Such Table Error' after copying database from assets
Work around:
Clean install of the app.
Wait for crash
Settings... Apps... Specific App... Clear Cache + Clear Storage
Run app again
Success, database does NOT exist in data directory, then the app copies file from Assets Directory with no issue.
No stupid questions?
But man I feel dumb when it was an easy answer.
Perhaps taking the time to ask here made us look harder.
Android P has auto restore from backup. Even if you do not have a copy of the app installed. So a corrupted file was being restored from backup.
Android P steps to correct (at least in development environment)
Settings...
System
/ Advanced
Backup
App data
Turn OFF Automatic Restore
Discovery came after finding out it worked on AVD with Factory reset. However development devices with different app versions experienced the same issue.
I am new to Unity. I have an Android library jar that I want to offer also as a plugin with Unity.
Within the library jar I have a folder html which contains a file temp.json. In the jar file (if I unzip it) the structure is like this: html/temp.json (Note here that jar works fine when running with any Android app outside Unity)
These are the steps that I followed to call my library through Unity:
1) Created folder Assets/Plugins/ Android in my Unity project hierarchy
2) Placed my library jar file there along with AndroidManifest.xml
3) Created a bridge.cs file that I use to call the functions in the jar file
Functions from the jar are called, but within the code of the jar somewhere on the Android side during the library lifecycle I call:
InputStream inputStream = MyClass.class.getClassLoader()
.getResourceAsStream("html/temp.json");
and I get a ResourceNotFound exception
From what I have read Unity ignores these files(like .json) when packaging. Therefore from what I understood in order to keep them in the Jar when packaging I created the following Unity structure:
Assets/Plugins/Android/assets/StreamingAssets/html/temp.json
I realise that any file that is placed within the StreamingAssets folder get copied in the assets folder of the library.
and in Java I call now:
inputStream = activity.getResources().getAssets().open("html/temp.json");
However I still get an exception that the file is not found.
Can anyone please help me/explain to me the procedure I have to follow to be able to read these files on the Java side while executing on Unity for Android?
Try this code:
private void readJson() {
String json = null;
try {
InputStream is = getAssets().open("html/temp.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException ex) {
ex.printStackTrace();
}
}
And save your json file to:
Assets/Plugins/Android/assets/html/temp.json
If you still can not do it, plz contact me
Br,
Frank
I'm having trouble reading from a csv file for my Android project. I'm using a Mac, with Eclipse ADT, and have imported OpenCSV.
The problem that I keep running into is that the file is not found. I have tried putting it everywhere, including: in the root folder (where the src folder is located), inside the src folder, and inside res/raw. I have refreshed the view, I have cleaned and rebuilt the project, I have restarted Eclipse, I have tried importing the file by drag and drop as well as by using the import option. For some reason, it still refuses to be found.
When I look at its path and absolute path (using file.getPath() and file.getAbsolutePath() they are: "abc.csv" and "/abc.csv" respectively. I have also double checked the file name, it is not named abc.csv.csv or anything similar.
I've used the following lines of code and these are the ones that have returned the error:
(This is from the OpenCSV site.)
CSVReader reader = new CSVReader(new FileReader("abc.csv"));
(#2 and #3 are not from OpenCSV and are just me experimenting around.)
AssetFileDescriptor descriptor = getAssets().openFd("abc.csv");
CSVReader reader = new CSVReader(new FileReader(descriptor.getFileDescriptor()));
3.
File file = new File("abc.csv");
try
{
Scanner inputStream = new Scanner(file);
while(inputStream.hasNext())
{
String data = inputStream.next();
}
inputStream.close();
}
catch(FileNotFoundException e)
{
Log.i(TAG, "File not found.");
}
Place the file in the assets folder and use AssetManager.
The application that I work on has a external SQLite database (sitting in the assets folder). My friend is using the same DB file in the iPhone version of the app. Content of the DB file is updated continuously. As both projects are in the same repository we created a Shared folder where we keep the DB file so both of use can link to that shared resource. It works in the iPhone project but fails in Android.
When in Eclipse, I click on the assets/new/file and click on Advanced and then Link to file in the file system. The file appears in the assets folder (in Eclipse) but I cannot access it from JAVA code.
Why that doesn't work? Is there any other was of linking external files to the project in Eclipse?
Thanks
EDITED:
I use this code for opening the assets file:
OutputStream os = new FileOutputStream(db_path + DB_NAME);
byte []b = new byte[1024];
int i, r;
//load list of files from 'data' folder
String[] fileCollection = am.list("data");
Arrays.sort(fileCollection);
for(i=0;i<fileCollection.length;i++)
{
//String fn = String.format(DB_NAME"%dd.db", (i + 1));
String fn = DB_NAME + "." + (i + 1);
if(fileCollection[i].equals(fn) == false){
break;
}
InputStream is = am.open("data/"+fn);
while((r = is.read(b)) != -1) {
os.write(b, 0, r);
}
is.close();
}
os.close();
From, the detail you given in question, I conclude that you can not use database file directly from the asset directory, you have to copy that database file into application's internal storage data/data/database/ and then use it.
EDIT:
I think Android environment can't recognize the physical path of you system files, so when we try to link any file for asset or any folder which are in android project hierarchy then it can not find the file which one linked from a system path.
So to make it working in android you have to put that file in your asset directory physically, not virtually (by putting file link in asset).
Hope I am not wrong in this. If yes then let me know on this topic.
Thanks.
My program opens a .txt file from the assets folder and reads from it. Here is the code:
AssetManager myAssetManager = myContext.getAssets();
try{
InputStream is = myAssetManager.open("databaseeleven.txt");
byte[] bytes = new byte[is.available()];
is.read(bytes);
commands = new String(bytes);
} catch(IOException e){
Toast.makeText(myContext, e.getMessage(), Toast.LENGTH_SHORT).show();
e.printStackTrace();
}//try-catch
I have noticed that when I make changes to the file called databaseeleven.txt and save the file, my changes aren't reflected on the emulator when I run my program again. The project is saved to a thumb drive. I checked it to make sure there's only one file with that name, and it is up to date. I know the application is re-downloaded because of changes to the code. I'm using egit, Eclipse version 3.6.2, and ADT version 10.0.1. Does anybody know why my program isn't working off this saved file?
Update: Refreshing and then cleaning the project again doesn't help.
If i have understood your problem correctly, you are trying to alter the file in /assets folder. changing .apk contents after signing the package is not possible.
If the file is small, copy it into your app's private data directory.
If the file is bigger, copy it into the /sdcard.
It was happening to me with a .sqlite file in the assets folder and I solved it by
uninstalling the app from the phone
and rebuilding.
What's the file size of databaseeleven.txt?
There is a limit of 1MB per file for the assets file, if the file size exceeds this limit it won't be available in your apk.
If this is your case, there are two alternatives I know of:
Split your file into 1MB chunks, you have an example this in this SO question
Use a file extension that doesn't get compressed by Android, as suggested here. Note that your file won't be compressed and you will probably end up with a big apk.
NOTE: It seems that the 1MB limit was removed in Android 2.3, so this only applies to 2.2 and lower.
Clean the project after you edit the file....hope this helps
hi try after refreshing the project in eclipse and clean & build it again. Hope you will be able to find the changes reflected in the emulator
If its a txt file of your format, you should be doing something like this
InputStream ins = getResources().openRawResource(R.raw.options);
where "options" is options.txt file in the ~/res/raw folder.
Any changes to this file will still require a publish/deploy back to the device/emulator so it has the latest apk.
Hope this helps...