I want to change the permission of a folder were application database is being stored.
After searching on Google I found this:-
public int chmod(File path, int mode) throws Exception {
Class fileUtils = Class.forName("android.os.FileUtils");
Method setPermissions =
fileUtils.getMethod("setPermissions", String.class, int.class, int.class, int.class);
return (Integer) setPermissions.invoke(null, path.getAbsolutePath(), mode, -1, -1);
}
...
chmod("/foo/bar/baz", 0755);
...
Here the FileUtils
class should be a part of android.os
package but I wasn't able to find it while importing the package.
Any idea how to use FileUtils
or some other way to change the permission of folder?
I am changing the permission because after installing my app when I try to access the database, app stops working. As my device is rooted
so when I change the permission of the database folder from 771
to 777
using Root Browser
the app starts working perfectly.
So how to change the permission of the folder while installation of app i.e. programmatically in unrooted
devices?
My DBHelper
class:-
public class DBHelper extends SQLiteOpenHelper {
public SQLiteDatabase database = null;
public File databaseFile;
public static String databaseName = "Db1.sqlite";
public String databasePath = "";
Context mContext;
public DBHelper(Context paramContext) {
super(paramContext, databaseName, null, 1);
this.mContext = paramContext;
Log.d("data", "package name:" + paramContext.getPackageName());
//this.databasePath = ("data/data/" + paramContext.getPackageName() + "/databases/"+databaseName);
this.databasePath = (Environment.getExternalStorageDirectory().getAbsolutePath()+"/Android/data/"+paramContext.getPackageName()+"/"+databaseName);
System.out.println(databasePath);
this.databaseFile = new File(this.databasePath);
if (!this.databaseFile.exists())
try {
deployDataBase(DBHelper.databaseName, this.databasePath);
return;
} catch (IOException localIOException) {
localIOException.printStackTrace();
}
}
private void deployDataBase(String dbNAme, String dbPath)
throws IOException {
InputStream localInputStream = this.mContext.getAssets().open(dbNAme);
FileOutputStream localFileOutputStream = new FileOutputStream(dbPath);
byte[] arrayOfByte = new byte[1024];
while (true) {
int i = localInputStream.read(arrayOfByte);
if (i <= 0) {
localFileOutputStream.flush();
localFileOutputStream.close();
localInputStream.close();
return;
}
localFileOutputStream.write(arrayOfByte, 0, i);
}
}
@Override
public synchronized void close() {
if (database != null)
database.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
}
Do not play with db path and file permissions for your case.
IMO Rooted and Normal Device are mutually exclusive audience.
Only For your testing rooted devices create db on sd card with path derived from Environment.getExternalStorage** method.
TO HAVE YOUR DB ON SD CARD. DO SOMETHING LIKE THIS.
Put this class in your code packages.
package com.test.db;
import java.io.File;
import android.content.Context;
import android.content.ContextWrapper;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.os.Environment;
/**
* Custom context wrapper to proxy the database file path.
* Instead of storing data on internal storage for app
* we will storing the data on external sd card.
*/
public class DatabaseContext extends ContextWrapper {
/*
* Used for logging.
*/
private static final String DEBUG_CONTEXT = "DatabaseContext";
/*
* Constructor wrapping given app context.
*/
public DatabaseContext(Context base) {
super(base);
}
/**
* Proxy the path to data base file for every operation
* @see android.content.ContextWrapper#getDatabasePath(java.lang.String)
*/
@Override
public File getDatabasePath(String name) {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
File sdcard = Environment.getExternalStorageDirectory();
String dbfile = sdcard.getAbsolutePath() + File.separator + "com.test" + File.separator + "database" + File.separator
+ name;
if (!dbfile.endsWith(".db")) {
dbfile += ".db";
}
File result = new File(dbfile);
if (!result.getParentFile().exists()) {
if(!result.getParentFile().mkdirs()){
result = new File(sdcard, name);
}
}
if (android.util.Log.isLoggable(DEBUG_CONTEXT, android.util.Log.WARN)) {
android.util.Log.w(DEBUG_CONTEXT,
"getDatabasePath(" + name + ") = " + result.getAbsolutePath());
}
return result;
} else {
// Something else is wrong. It may be one of many other states,
// Writing data on internal storage
return super.getDatabasePath(name);
}
}
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode,
CursorFactory factory) {
return openOrCreateDatabase(name, mode, factory, null);
}
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
DatabaseErrorHandler errorHandler) {
SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(getDatabasePath(name)
.getAbsolutePath(), null, errorHandler);
return result;
}
}
Extend SqliteOpenHelper class like this
package com.test.db;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
/**
* Custom SqliteOpenHelper.
*/
public class MySQLiteOpenHelper extends SQLiteOpenHelper {
private static final String TAG = My.class.getSimpleName();
private final Context context;
public MySQLiteOpenHelper(Context context, String name, int version, String mResourceName) {
super(new DatabaseContext(context), name, /*factory*/null, version);
this.context = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
// Create tables here
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
This is tested piece to create db in sd card. Please check