can we store our Sql lite database in the assets folder for the Phonegap project?
I have already implemented an android project.i want to use the same DB for the Phonegap project.
can i use it? or else what is the alternative and what is the procedure for it?
I have searched for the past 2 days .i did not get any proper answer?
You can include the sqlite db in the assets folder but on first run of the application you'll need to move it to the right directory so the webview can open the database. There is a plugin and description of how to do exactly this at:
http://gauravstomar.blogspot.ca/2011/08/prepopulate-sqlite-in-phonegap.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed:+GauravSTomarBootstrappingIntelligence+(Gaurav+S+Tomar+:+Bootstrapping+Intelligence)
Alternatively you could include your DB as a .sql file and execute the file the first time you start your app:
http://simonmacdonald.blogspot.ca/2011/12/on-fourth-day-of-phonegapping-creating.html
My current MyPhoneGapActivity looks like this
package com.rkadukar.database;
import org.apache.cordova.DroidGap;
import android.os.Bundle;
public class MyPhoneGapActivity extends DroidGap {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.loadUrl("file:///android_asset/www/index.html");
}
}
Where do I add the code to copy the db file from Assets folder to the data/data/... folder for my application.
As per my understanding once the database is copied I can then delete the file and use the native PhoneGap storage API to read my imported database but in that case why do we need this plugin https://github.com/brodyspark/PhoneGap-SQLitePlugin-Android
Can someone kindly detail the steps required to
Copy the database from the assets folder to the data/data/.. folder
Read the copied database and perform operations on it.
Related
I have a situation where I need to read an image file (jpg) in a submodule.
The class where I need access to that image is a normal class. So I have two options.
I put that image in the asset folder and try to use assetManager, which doesn't work because I don't have context. My project doesn't have any activity or fragment, because it's a submodule
I put that image in a package. How can I access that image?
The code was written in kotlin.
I will be appreciated any help or suggestions
I am trying to use SQLiteAssetHelper and it requires me to create database on PC and copy it to assets/databases/databasename.db. I do that, but when I check on the device, nor the database, nor the databases folder is there under my app's data folder.
I did this based on a video, and the guy there doesn't do anything else to make the copy work.
So, are the files supposed to be automatically copied over to device?
If not, how can I copy the files?
So, are the files supposed to be automatically copied over to device? If not, how can I copy the files?
Yes it will BUT only when an attempt is made to access the database. Just instantiating the class that extends SQLiteAssetHelper will not copy the database and thus if that is all you do then the database will not be visible.
The steps when using SQliteAssetHelper to take should be :-
Create your project.
Amend the build.gradle to include implementation 'com.readystatesoftware.sqliteasset:sqliteassethelper:+' in the dependencies section.
Create the assets folder and then the databases folder in the assets folder and
Copy the database file into the databases folder.
Create the Database Helper class that extends SQliteAssetHelper.
Instantiate the Database Helper
Access the database (this is when the database is copied).
If when doing step 5 you use, as an example (based upon the information in the question) :-
public class DatabaseHelper extends SQLiteAssetHelper {
public static final String DATABASENAME = "databasename.db"; //<<<<<<<<< MUST match file name in assets/databases
public static final int DATABASEVERSION = 1;
public DatabaseHelper(Context context) {
super(context, DATABASENAME, null, DATABASEVERSION);
this.getWritableDatabase(); //<<<<< will force database access and thus copy database from assets
}
}
Then when doing 6 (instantiating the database helper), then 7 is done because this.getWritableDatabase(); accesses (implicitly opens) the database.
e.g.
public class MainActivity extends AppCompatActivity {
DatabaseHelper mDBHelper; //<<<<< declares the database helper
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDBHelper = new DatabaseHelper(this); // instantiates the database helper
}
}
The procedure you're explaining requires root access to the app storage on the device which is impossible on a normal non-rooted device due to security considerations. For this, you need a rooted device OR you could use emulator in Android Studio, that's much easier and user friendly approach:
Open emulator from Android Studio -> Settings -> Memory -> Internal Storage -> Others
A pop-up window will open. Click explore. You will get access to your app's internal storage so you can manage the database folder as well.
P.S.: Also, you might just package your app with the database table you have, just as with any other file, simply place it under your src/main/assets folder and access from code in runtime. Code samples are available in this thread : Android - Copy assets to internal storage (suggested by #Ezaldeen sahb)
I have a simple button
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button"
android:onClick="trap" />
Initial code
package com.example.a21.ii;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void trap(View view){
//click function
}
}
After clicking it must change to this code
package com.example.a21.ii;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void trap(View view){
//click function
}
private void additionalFunction(){}
}
so how to change the own code? Any suggestion is appreciate and Please let me know if more details are need. Thanks
If you want to add an additional function, you cannot do it by changing the existing code.
The ANdroid APK is read-only. You cannot write to it, so you cannot change the .java files in the APK.
However:
You can create a class that loads the new methods (NOTE Database, shared prefs or files is required) and strips the function of them, and takes appropriate action without writing the methods to the APK.
Essentially, you want to execute the method without writing it to the APK, so you need to design a class that can execute these methods.
OR:
YOu can create an external class(File only) in internal or external storage. Then you write any methods to that class. Refer this SO question to see how you can load and execute code in external .java files.
Please note that this is a workaround. You cannot write to the APK, but you can write .java files to the system and load them and execute them at runtime.
Final note
The first option (Create a class to load methods and execute them internally in the app) is extremely hard. It may even be impossible. The second option (where you create a .java file externally and load it in) is probably the easiest option around. You save a file externally and add any methods you want, and create a new instance of the external class in the class you want these methods in. This is the only way (I know of) you can create files and make them editable.
And I cannot say it enough times:
The APK is read only!
You cannot write to the APK, but you can read from it. For an instance oyu can read assets, but you cannot write to the assets.
The only way to "change" the contents of an APK is to decode the old, add whatever changes you need and create a new apk. But the process of doing this requires root, and adding the entire system to an application that does something else will add a lot of bloat to your app. Further, it will then most likely be signed with a different keystore and may make it incompatible with the store version, which may remove the option for updates in the future.
And from your comments, I apparently have to say it one more time:
You cannot change the APK like changing a text file! The APK is like a zipped file. To change it, you have to unpack it and then edit it. Meaning no matter what programming language you are thinking of, you have to unpack the APK, change it and repack it. Which, as I mentioned above, has many side effects.
And as you mentioned in another comment, if you suddenly are wondering about windows and the function there, that is a whole other topic (and a whole different set of developers who have competence on the topic). Ask another question instead of having two very distinct questions in one
quick background - I have no real programming knowledge so think complete beginner!
I used the below guide to load a database from the assets folder and it worked fine
http://www.javahelps.com/2015/04/import-and-use-external-database-in.html.
I now want to adjust this slightly so it loads a different SQLite database which I have created using DB Browser for SQLite but it is throwing the following error:
Missing databases/Exercisesthree.db file (or .zip, .gz archive) in assets, or target folder not writable
I have placed the new database (Excercisesthree.db.zip) in the same assets folder as the database that works (I have also left the unzipped file there too (Excercisesthree.db).
I altered the DatabaseOpenHelper class to open the Excercisesthree.db instead of the other db (code below) but for some reason it doesnt work. I suspect its something to do with the format of the database as I've hardly changed the code
package com.example.mat.externaldatabasedemo;
/**
* Created by Mat on 24-Jan-17.
*/
// http://www.javahelps.com/2015/04/import-and-use-external-database-in.html
import android.content.Context;
import com.readystatesoftware.sqliteasset.SQLiteAssetHelper;
public class DatabaseOpenHelper extends SQLiteAssetHelper {
private static final String DATABASE_NAME = "Exercisesthree.db";
private static final int DATABASE_VERSION = 1;
public DatabaseOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
}
Here's a link to the database file:
https://1drv.ms/u/s!AupGvbDoJdp9i26l9oO5CcCGf2I0
This is the location of the database files:
C:\Users\Mat\AndroidStudioProjects\ExternalDatabaseDemo\app\src\main\assets\databases
Ok I've sorted it and confirm it was nothing to do with the Database format. In the end I created a new project and followed the original guide but changed it to the new database.
I think what must of happened is I'd changed some part of the code somewhere along the way and it stopped working. When testing it however it appeared to be working because the original databse had already been loaded onto the emulator and so it masked the fact that the database was no longer loading from the assets folder.
I would have like to have found out exactly what part of the code was missing and stopping it to work to understand a little more and report back but dont think I'll have time
I have a DB helper class which extends SQLiteOpenHelper and in onCreate, I want to read various text files which each contain a single SQL CREATE command. The text files are in my project's asset folder and I'm trying to use a FileReader as follows...
#Override
public void onCreate(SQLiteDatabase db) {
AssetManager am = context.getAssets();
FileReader tableListFileReader = new FileReader(am.openFd(context.getString(R.string.db_schema_filelist_filename)).getFileDescriptor());
I get an exception as follows...
java.io.FileNotFoundException: /npvr_db_schema_create_tables.txt
This obviously seems to be an absolute path from root ('/') whereas other AssetManager 'open' methods are documented as accessing files in the 'assets' folder. Unfortunately those methods return an InputStream which can't be used to directly instantiate a FileReader.
This doesn't make sense to me - surely AssetManager should be just what it says it is and simply give access to my assets folder. Am I missing something here? How should I approach this in a better way?
Here is an API demo of reading from an asset. The file name semantics are the same as for opening an FD:
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/content/ReadAsset.html
The asset is added by putting in an "assets" directory at the same level as your "res" directory. (Look at the ApiDemos full source code to see this.)
It is... unusual... to get the file name of an asset to load from a string resource. You probably don't want to be doing that.