Skip to content

Commit 4349b50

Browse files
Merge pull request #62 from landicefu/Development
allow accessing external databases or databases at special path
2 parents 21e7e33 + 25470e1 commit 4349b50

7 files changed

Lines changed: 210 additions & 34 deletions

File tree

app/src/main/AndroidManifest.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@
3434
<category android:name="android.intent.category.LAUNCHER" />
3535
</intent-filter>
3636
</activity>
37+
38+
<meta-data
39+
android:name="DatabaseFileProvider"
40+
android:value="com.sample.ExternalDatabaseFileProvider" />
41+
3742
</application>
3843

3944
</manifest>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.sample;
2+
3+
import android.content.Context;
4+
5+
import com.amitshekhar.utils.DatabaseFileProvider;
6+
import com.sample.database.ExtTestDBHelper;
7+
8+
import java.io.File;
9+
import java.util.HashMap;
10+
import java.util.Map;
11+
12+
public class ExternalDatabaseFileProvider extends DatabaseFileProvider {
13+
14+
public ExternalDatabaseFileProvider(Context context) {
15+
super(context);
16+
}
17+
18+
@Override
19+
protected Map<String, File> getDatabaseFiles() {
20+
Map<String, File> map = new HashMap<>();
21+
map.put(ExtTestDBHelper.DATABASE_NAME, new File(context.getFilesDir() + "/" + ExtTestDBHelper.DIR_NAME + "/" + ExtTestDBHelper.DATABASE_NAME));
22+
return map;
23+
}
24+
25+
}

app/src/main/java/com/sample/MainActivity.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import com.sample.database.CarDBHelper;
3131
import com.sample.database.ContactDBHelper;
32+
import com.sample.database.ExtTestDBHelper;
3233
import com.sample.utils.Utils;
3334

3435
import java.util.HashSet;
@@ -86,6 +87,14 @@ protected void onCreate(Bundle savedInstanceState) {
8687
carDBHelper.insertCar(name, color, mileage);
8788
}
8889
}
90+
91+
ExtTestDBHelper extTestDBHelper = new ExtTestDBHelper(getApplicationContext());
92+
if (extTestDBHelper.count() == 0) {
93+
for (int i = 0; i < 20; i++) {
94+
String value = "value_" + i;
95+
extTestDBHelper.insertTest(value);
96+
}
97+
}
8998
}
9099

91100
public void showDebugDbAddress(View view) {
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package com.sample.database;
2+
3+
import android.content.ContentValues;
4+
import android.content.Context;
5+
import android.content.ContextWrapper;
6+
import android.database.Cursor;
7+
import android.database.DatabaseErrorHandler;
8+
import android.database.sqlite.SQLiteDatabase;
9+
import android.database.sqlite.SQLiteOpenHelper;
10+
11+
import java.io.File;
12+
import java.util.Calendar;
13+
14+
public class ExtTestDBHelper extends SQLiteOpenHelper {
15+
16+
public static final String DIR_NAME = "custom_dir";
17+
public static final String DATABASE_NAME = "ExtTest.db";
18+
public static final String TEST_TABLE_NAME = "test";
19+
public static final String TEST_ID = "id";
20+
public static final String TEST_COLUMN_VALUE = "value";
21+
public static final String TEST_CREATED_AT = "createdAt";
22+
23+
public ExtTestDBHelper(Context context) {
24+
super(new CustomDatabasePathContext(context), DATABASE_NAME, null, 1);
25+
}
26+
27+
@Override
28+
public void onCreate(SQLiteDatabase db) {
29+
// TODO Auto-generated method stub
30+
db.execSQL(
31+
String.format(
32+
"create table %s (%s integer primary key, %s text, %s integer)",
33+
TEST_TABLE_NAME,
34+
TEST_ID,
35+
TEST_COLUMN_VALUE,
36+
TEST_CREATED_AT
37+
)
38+
);
39+
}
40+
41+
@Override
42+
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
43+
// TODO Auto-generated method stub
44+
db.execSQL("DROP TABLE IF EXISTS " + TEST_TABLE_NAME);
45+
onCreate(db);
46+
}
47+
48+
public boolean insertTest(String value) {
49+
SQLiteDatabase db = this.getWritableDatabase();
50+
ContentValues contentValues = new ContentValues();
51+
contentValues.put("value", value);
52+
contentValues.put(TEST_CREATED_AT, Calendar.getInstance().getTimeInMillis());
53+
db.insert(TEST_TABLE_NAME, null, contentValues);
54+
return true;
55+
}
56+
57+
public int count() {
58+
SQLiteDatabase db = getReadableDatabase();
59+
Cursor cursor = db.rawQuery("select COUNT(*) from " + TEST_TABLE_NAME, null);
60+
if (cursor != null && cursor.getCount() > 0) {
61+
cursor.moveToFirst();
62+
return cursor.getInt(0);
63+
} else {
64+
return 0;
65+
}
66+
}
67+
68+
private static class CustomDatabasePathContext extends ContextWrapper {
69+
70+
public CustomDatabasePathContext(Context base) {
71+
super(base);
72+
}
73+
74+
@Override
75+
public File getDatabasePath(String name) {
76+
File databaseDir = new File(String.format("%s/%s", getFilesDir(), ExtTestDBHelper.DIR_NAME));
77+
databaseDir.mkdirs();
78+
File databaseFile = new File(String.format("%s/%s/%s", getFilesDir(), ExtTestDBHelper.DIR_NAME, name));
79+
return databaseFile;
80+
}
81+
82+
@Override
83+
public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory) {
84+
return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);
85+
}
86+
87+
@Override
88+
public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {
89+
return SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name), null);
90+
}
91+
}
92+
}

debug-db/src/main/java/com/amitshekhar/server/RequestHandler.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import com.amitshekhar.model.TableDataResponse;
3131
import com.amitshekhar.model.UpdateRowResponse;
3232
import com.amitshekhar.utils.Constants;
33-
import com.amitshekhar.utils.DatabaseFileProvider;
33+
import com.amitshekhar.utils.InternalDatabaseFileProvider;
3434
import com.amitshekhar.utils.DatabaseHelper;
3535
import com.amitshekhar.utils.PrefHelper;
3636
import com.amitshekhar.utils.Utils;
@@ -160,7 +160,8 @@ private void writeServerError(PrintStream output) {
160160

161161
private void openDatabase(String database) {
162162
closeDatabase();
163-
mDatabase = mContext.openOrCreateDatabase(database, 0, null);
163+
File databaseFile = databaseFiles.get(database);
164+
mDatabase = SQLiteDatabase.openOrCreateDatabase(databaseFile.getAbsolutePath(), null);
164165
isDbOpened = true;
165166
}
166167

@@ -173,7 +174,7 @@ private void closeDatabase() {
173174
}
174175

175176
private String getDBListResponse() {
176-
databaseFiles = DatabaseFileProvider.getDatabaseFiles(mContext);
177+
databaseFiles = InternalDatabaseFileProvider.getDatabaseFiles(mContext);
177178
Response response = new Response();
178179
if (databaseFiles != null) {
179180
for (HashMap.Entry<String, File> entry : databaseFiles.entrySet()) {
Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,37 @@
1-
/*
2-
*
3-
* * Copyright (C) 2016 Amit Shekhar
4-
* * Copyright (C) 2011 Android Open Source Project
5-
* *
6-
* * Licensed under the Apache License, Version 2.0 (the "License");
7-
* * you may not use this file except in compliance with the License.
8-
* * You may obtain a copy of the License at
9-
* *
10-
* * http://www.apache.org/licenses/LICENSE-2.0
11-
* *
12-
* * Unless required by applicable law or agreed to in writing, software
13-
* * distributed under the License is distributed on an "AS IS" BASIS,
14-
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15-
* * See the License for the specific language governing permissions and
16-
* * limitations under the License.
17-
*
18-
*/
19-
201
package com.amitshekhar.utils;
212

223
import android.content.Context;
4+
import android.content.pm.ApplicationInfo;
5+
import android.content.pm.PackageManager;
236

247
import java.io.File;
25-
import java.util.HashMap;
8+
import java.util.Map;
269

27-
/**
28-
* Created by amitshekhar on 06/02/17.
29-
*/
10+
public abstract class DatabaseFileProvider {
3011

31-
public class DatabaseFileProvider {
12+
public static final String METADATA_TAG = "DatabaseFileProvider";
13+
protected final Context context;
3214

33-
private DatabaseFileProvider() {
34-
// This class in not publicly instantiable
15+
public DatabaseFileProvider(Context context) {
16+
this.context = context;
3517
}
3618

37-
public static HashMap<String, File> getDatabaseFiles(Context context) {
38-
HashMap<String, File> databaseFiles = new HashMap<>();
19+
public static DatabaseFileProvider fromMetadata(Context context) {
20+
DatabaseFileProvider databaseFileProvider = null;
3921
try {
40-
for (String databaseName : context.databaseList()) {
41-
databaseFiles.put(databaseName, context.getDatabasePath(databaseName));
22+
ApplicationInfo appInfo = context.getPackageManager()
23+
.getApplicationInfo(context.getPackageName(),
24+
PackageManager.GET_META_DATA);
25+
String className = appInfo.metaData.getString(METADATA_TAG);
26+
if (className != null) {
27+
Class<DatabaseFileProvider> databaseFileProviderClass = (Class<DatabaseFileProvider>) Class.forName(className);
28+
databaseFileProvider = databaseFileProviderClass.getConstructor(Context.class).newInstance(context);
4229
}
4330
} catch (Exception e) {
4431
e.printStackTrace();
4532
}
46-
return databaseFiles;
33+
return databaseFileProvider;
4734
}
35+
36+
protected abstract Map<String, File> getDatabaseFiles();
4837
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
*
3+
* * Copyright (C) 2016 Amit Shekhar
4+
* * Copyright (C) 2011 Android Open Source Project
5+
* *
6+
* * Licensed under the Apache License, Version 2.0 (the "License");
7+
* * you may not use this file except in compliance with the License.
8+
* * You may obtain a copy of the License at
9+
* *
10+
* * http://www.apache.org/licenses/LICENSE-2.0
11+
* *
12+
* * Unless required by applicable law or agreed to in writing, software
13+
* * distributed under the License is distributed on an "AS IS" BASIS,
14+
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* * See the License for the specific language governing permissions and
16+
* * limitations under the License.
17+
*
18+
*/
19+
20+
package com.amitshekhar.utils;
21+
22+
import android.content.Context;
23+
24+
import java.io.File;
25+
import java.util.HashMap;
26+
import java.util.List;
27+
28+
/**
29+
* Created by amitshekhar on 06/02/17.
30+
*/
31+
32+
public class InternalDatabaseFileProvider {
33+
34+
private InternalDatabaseFileProvider() {
35+
// This class in not publicly instantiable
36+
}
37+
38+
public static HashMap<String, File> getDatabaseFiles(Context context) {
39+
HashMap<String, File> databaseFiles = new HashMap<>();
40+
try {
41+
for (String databaseName : context.databaseList()) {
42+
databaseFiles.put(databaseName, context.getDatabasePath(databaseName));
43+
}
44+
45+
DatabaseFileProvider databaseFileProvider = DatabaseFileProvider.fromMetadata(context);
46+
if (databaseFileProvider != null) {
47+
databaseFiles.putAll(databaseFileProvider.getDatabaseFiles());
48+
}
49+
} catch (Exception e) {
50+
e.printStackTrace();
51+
}
52+
return databaseFiles;
53+
}
54+
55+
}

0 commit comments

Comments
 (0)