android sqllite cannot be accessed from outside package - android

I am making an Android app to learn sqllite. Because I use 7 tables, I decided to create 7 class files in a folder "DBHelper", and want to make 7 files in a folder "DBadapter". Here what the structure looks like:
root
DBHelper: 7 helper files (ex: PersonHelper.java)
DBadapter: 7 adapter files (ex: PersonDAO.java)
But I get an error message with PersonDAO.java: "cannot be accessed from outside package", when I declared the object: "PersonHelper personHelper = new PersonHelper(context);" in the constructor.
Anyone has an idea how to fix that without putting all files in one folder? What is the standard in the industry when creating multiple large tables?
PS: The error is gone once I place all files in one directory.
public class PersonDAO {
private Context context;
//Database info
private static final String DATABASE_NAME = "MyDB";
private static final int DATABASE_VERSION = 1;
//Table helper info
public PersonHelper databaseHelper;
private SQLiteDatabase db = null;
//Constructors
PersonDAO(Context context) {
this.context = context;
databaseHelper = new PersonHelper(context); //Error: "cannot be accessed from outside package"
}

Your constructor of your PersonHelper is probably default like it is in your PersonDAO class. So it can only be accessed from the same package. You have to change it to public to access it from PersonDAO:
public PersonHelper(Context context){
...
}

Related

How to write a database for an android app [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
In my app I need a database with different tables that I would write before and then just read in the app. I know how to create a new database, write and read it in the app using SQL but I actually don't know with what program (and in which format) I can write the database before adding it in the assets folder.
Would anyone help me with that, please?
You can use http://sqlitebrowser.org/ It run on Mac OS , Windows and Linux
You can use SQLite, which is an on-device SQL implementation. Be aware that this will only support a subset of SQL operations found in most traditional relational DBs. If you need full SQL support you'll have to write back-end web services hosted elsewhere.
You can use SQLiteOpenHelper for creating your database.
Here is my example to create simple database that have store City with 2 filed is City_ID and City_Name:
public class DiLiBusDatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "DiLiBusDB";
private static final String TBL_CITY = "City";
private static final String CITY_ID_FIELD = "City_ID";
private static final String CITY_NAME_FIEDL = "City_Name";
private SQLiteDatabase database;
private static DiLiBusDatabaseHelper mInstance = null;
Context context;
//synchronized to make sure have only one thread is run at the same time
public static DiLiBusDatabaseHelper getInstance(Context context){
if(mInstance == null){
mInstance = new DiLiBusDatabaseHelper(context.getApplicationContext());
}
return mInstance;
}
private DiLiBusDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 2);
this.context = context;
this.database = getWritableDatabase();
}
#Override
public void onCreate(SQLiteDatabase db) {
String query = "CREATE TABLE"+" "+TBL_CITY+"("+CITY_ID_FIELD+" "+"TEXT PRIMARY KEY,"+CITY_NAME_FIEDL+" "+"TEXT"+");";
String queryIndex = "CREATE INDEX city_name_idx ON"+ " "+TBL_CITY +"("+CITY_NAME_FIEDL+");";
db.execSQL(query);
db.execSQL(queryIndex);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
p/s: I using Singleton pattern to create my database. Moreover, if you want to save your db in SDCard, u can check this link
There are many libraries for database:
Realm
Active Android
Green DAO
This is the simplest way for creating database because you operates on your defined data models.

Is there a better way to pre-load items into a database?

In my Android app I have a
SQLiteHelper class that extends SQLIteOpenHelper, and takes care of things like table-creation and upgrades.
SQLiteDatasource class that performs CRUD operations on the SQLiteHelper object.
I want to pre-load one of the tables with certain items so there is something present when the user first uses the app. These items may change so I want to make them modular.
Right now I am doing it this way:
public class MyDefaults {
public static final ArrayList<HashMap<String, String>> MY_DEFAULTS;
static {
MY_DEFAULTS = new ArrayList<HashMap<String, String>>();
HashMap<String, String> map = new HashMap<String, String>();
//All the values below you change to whatever defaults you want
map.clear();
map.put(SQLiteHelper.KEY_1, "Value 1A");
map.put(SQLiteHelper.KEY_2, "Value 2A");
map.put(SQLiteHelper.KEY_3, "Value 3A");
MY_DEFAULTS.add(new HashMap<String, String>(map));
map.clear();
map.put(SQLiteHelper.KEY_1, "Value 1B");
map.put(SQLiteHelper.KEY_2, "Value 2B");
map.put(SQLiteHelper.KEY_3, "Value 3B");
MY_DEFAULTS.add(new HashMap<String, String>(map));
map.clear();
map.put(SQLiteHelper.KEY_1, "Value 1C");
map.put(SQLiteHelper.KEY_2, "Value 2C");
map.put(SQLiteHelper.KEY_3, "Value 3C");
MY_DEFAULTS.add(new HashMap<String, String>(map));
//and so on
}
}
And then in my SQLiteDatasource class I have a method that performs the insert of these default values:
public void preloadDefaults() {
mDatabase.beginTransaction();
try {
for (HashMap<String, String> map : MyDefaults.MY_DEFAULTS) {
ContentValues values = new ContentValues();
values.put(SQLiteHelper.KEY_1, map.get(SQLiteHelper.KEY_1));
values.put(SQLiteHelper.KEY_2, map.get(SQLiteHelper.KEY_2));
values.put(SQLiteHelper.KEY_3, map.get(SQLiteHelper.KEY_3));
mDatabase.insert(SQLiteHelper.SOME_TABLE, null, values);
}
}
finally {
mDatabase.endTransaction();
}
}
Is my way of doing this considered bad practice? Is there a better way to define the "defaults" that get inserted into a table after it gets created? Possibly through XML instead of a static class?
Note: I can't just copy an external DB because I'm actually inserting these fields with some other values created at runtime (the code above is a simplification of what my real code is).
As it is in this answer also
The SQLiteAssetHelper library makes this task really simple.
It's easy to add as a gradle dependency (but a Jar is also available for Ant/Eclipse), and together with the documentation it can be found at:
https://github.com/jgilfelt/android-sqlite-asset-helper
As explained in documentation:
Add the dependency to your module's gradle build file:
dependencies {
compile 'com.readystatesoftware.sqliteasset:sqliteassethelper:+'
}
Copy the database into the assets directory, in a subdirectory called assets/databases. For instance:
assets/databases/my_database.db
(Optionally, you may compress the database in a zip file such as assets/databases/my_database.zip. This isn't needed, since the APK is compressed as a whole already.)
Create a class, for example:
public class MyDatabase extends SQLiteAssetHelper {
private static final String DATABASE_NAME = "my_database.db";
private static final int DATABASE_VERSION = 1;
public MyDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
}
You can memorize your data, with Serialize Objects. Read here:
How do I serialize an object and save it to a file in Android?

can i specify a path to sqlite database

I created sqlite database in android as shown in the code below and i added some records to it. then i wanted to copy that database to use it in anothe
application, my database is called "GEOLOC.db" and i searched for it but it was not found despite it contains data.
please let me know
1-how to know where the sqlite database is saved
2-can i specify a path to which the databse will be saved?
code:
public class SQLiteHelper extends SQLiteOpenHelper {
private final String TAG = this.getClass().getSimpleName();
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_NAME = "GEOLOC.db";//can i specify a pth here??
private static final String DATABASE_TABLE_NAME = "NODE_00";
private Context mCtx = null;
public SQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.mCtx = context;
}
Usually, a particular sqlite database is specific to one single application. However you won't be able to view it unless the phone is rooted. In fact it is normally found in the following path:
//data/data/<Your-Application-Package-Name>/databases/<your-database-name>
The application package name can be accessed using the following code:
PACKAGE_NAME = getApplicationContext().getPackageName();
The database name is stored in the class which extends the SQLiteOpenHelperthrough the following declaration:
private static final String DATABASE_NAME = "buspass";
In order to share data between apps (provied that they have both been developed by you), you will need to specify a shared user id in the Manifest file of both apps.
Use the same DBAdapter in both apps. In the app that hosts the database, call the DBAdapter with the native context.
DBadapter hostDBAdapter = new DbAdapter(getApplicationContext());
performerDBadapter.open();
In the second app, access the database with the context of the database hosting app.
First, define the shared context:
Context sharedContext = null;
try {
sharedContext = this.createPackageContext("replace.with.host.package.name", Context.CONTEXT_INCLUDE_CODE);
if (sharedContext == null) {
return;
}
} catch (Exception e) {
String error = e.getMessage();
return;
}
Then open the DBAdapter with the shared context:
DbAdapter sharedDBadapter = new PerformerDbAdapter(sharedContext);
sharedDBadapter.open();
The manifest file should have the following code:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:sharedUserId="my.app" ... >
Hope this helps :)

Can you use the DBFlow Android ORM with an existng Database Packaged with the app?

Can you use the DbFlow ORM with an existing SQLite Database. That is packaged with the app and copied (from assets folder) over on initial install?
Add your db foo.db in the assets folder and set your database class FooDatabase as the follow:
#Database(name = FooDatabase.NAME, version = FooDatabase.VERSION)
public class FooDatabase {
public static final String NAME = "foo";
public static final int VERSION = 1;
}
note the name is the same without the .db.
Now suppose you have a table FooTable with a column id and a column fooName, we needs to represent that table as the follow:
import com.raizlabs.android.dbflow.structure.BaseModel;
#Table(databaseName = FooDatabase.NAME)
public class FooTable extends BaseModel {
#Column #PrimaryKey(autoincrement = true) long id;
#Column String fooName;
}
it is all, test it, add some values to db and log it to show:
List foo = new Select().from(FooTable.class).queryList()

Get databases directory for my app programmatically

I want to use a "pre loaded" database in my app. There are tons of questions about this and most point to this blog article here or similars.
So far so good. I just want to know if there is a better way to get the default databases directory so you don't have to use something like this:
private static String DB_PATH = "/data/data/YOUR_PACKAGE/databases/";
I mean, maybe that is changed in the future or maybe a device or rom could place it elsewhere... so is there a way to get this path programatically?
In Context exists a method to getDatabasePath(name), but you need to give it an existing db name and well... it doesn't exist yet, I want to move it there :P
I used...
String destPath = getFilesDir().getPath();
destPath = destPath.substring(0, destPath.lastIndexOf("/")) + "/databases";
Create an empty DB, get the path with getDatabasePath(), then overwrite it with your own.
Used by SQLiteAssetHelper:
String path = mContext.getDatabasePath(mName).getPath();
At this time, the database doesn't exist. I think the String just takes the internal path and adds the appropriate modifiers. In fact, this seems to work just fine:
context.getDatabasePath("a").getParentFile()
Basically, you don't need to have a real database created, just ask it for one.
You can use the Method getFilesDir() or getDatabasePath in an Activity-Class to get this Folder.
More info here
You can use getDatabasePath method in your Helper class:
public class MyDatabase extends SQLiteAssetHelper {
private static final String DATABASE_NAME = "wl.db";
private static final int DATABASE_VERSION = 1;
public String databasePath = "";
public MyDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// you can use an alternate constructor to specify a database location
// (such as a folder on the sd card)
// you must ensure that this folder is available and you have permission
// to write to it
// super(context, DATABASE_NAME, context.getExternalFilesDir(null).getAbsolutePath(), null, DATABASE_VERSION);
databasePath = context.getDatabasePath("wl.db").getPath();
}

Categories

Resources