且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何以编程方式更改文件/文件夹的权限在android系统

更新时间:2023-02-10 23:15:44


  • 不要与你的情况数据库的路径和文件权限玩。


  • IMO扎根和正常的设备是互斥的观众。


  • 仅供测试植根设备创建与Environment.getExternalStorage得到的路径SD卡上的分贝**方法。


让你的DB在SD卡上。做这样的事情。

将这个类在code包。

 包com.test.db;进口的java.io.File;进口android.content.Context;
进口android.content.ContextWrapper;
进口android.database.DatabaseErrorHandler;
进口android.database.sqlite.SQLiteDatabase;
进口android.database.sqlite.SQLiteDatabase.CursorFactory;
进口android.os.Environment;/ **
 *自定义上下文包装代理数据库文件的路径。
 *而不是存储上的应用程序内部存储的数据
 *我们将存储在外接SD卡中的数据。
 * /
公共类DatabaseContext扩展ContextWrapper {    / *
     *用于记录。
     * /
    私有静态最后弦乐DEBUG_CONTEXT =DatabaseContext;    / *
     *给定应用程序上下文构造包装。
     * /
    公共DatabaseContext(上下文基地){
        超(底座);
    }    / **
     *代理的路径数据的每个操作的基本文件
     * @see android.content.ContextWrapper#getDatabasePath(java.lang.String中)
     * /
    @覆盖
    公共文件getDatabasePath(字符串名称){        字符串状态= Environment.getExternalStorageState();        如果(Environment.MEDIA_MOUNTED.equals(州)){
            //我们可以读取和写入媒体
            文件SD卡= Environment.getExternalStorageDirectory();
            字符串DBFILE = sdcard.getAbsolutePath()+文件分割符+com.test+文件分割符+数据库+文件分割符
                +名;
            如果(!dbfile.endsWith(DB)){
                DBFILE + =.db的;
            }            文件的结果=新的文件(DBFILE);            如果(!result.getParentFile()。存在()){
                如果(!result.getParentFile()。mkdirs()){
                    结果=新的文件(SD卡,名);
                }
            }            如果(android.util.Log.isLoggable(DEBUG_CONTEXT,android.util.Log.WARN)){
                android.util.Log.w(DEBUG_CONTEXT,
                    getDatabasePath(+名称+)=+ result.getAbsolutePath());
            }            返回结果;        }其他{
            //别的东西是错误的。这可能是很多其他的国家之一,
            //在内部存储数据的写入
            返回super.getDatabasePath(名);
        }    }    @覆盖
    公共SQLiteDatabase openOrCreateDatabase(字符串名称,诠释方式,
            CursorFactory厂){
        返回openOrCreateDatabase(名称,模式,工厂,NULL);
    }    @覆盖
    公共SQLiteDatabase openOrCreateDatabase(字符串名称,诠释方式,CursorFactory厂,
        DatabaseErrorHandler的ErrorHandler){
        SQLiteDatabase结果= SQLiteDatabase.openOrCreateDatabase(getDatabasePath(名)
            .getAbsolutePath(),空,的ErrorHandler);        返回结果;
    }
}

扩展SqliteOpenHelper类像这样

 包com.test.db;进口java.io.IOException异常;
进口java.io.InputStreamReader中;
进口java.util.StringTokenizer的;进口android.content.Context;
进口android.database.sqlite.SQLiteDatabase;
进口android.database.sqlite.SQLiteOpenHelper;
进口android.util.Log;/ **
 *自定义SqliteOpenHelper。
 * /
公共类MySQLiteOpenHelper扩展SQLiteOpenHelper {    私有静态最后弦乐TAG = My.class.getSimpleName();    私人最终上下文的背景下;    公共MySQLiteOpenHelper(上下文的背景下,字符串名称,诠释的版本,弦乐mResourceName){
        超(新DatabaseContext(上下文),名称,/ * *工厂/ null的版本);
        this.context =背景;
    }    @覆盖
    公共无效的onCreate(SQLiteDatabase DB){
      //这里创建表
    }    @覆盖
    公共无效onUpgrade(SQLiteDatabase分贝,INT oldVersion,诠释静态网页){
    }}

这是一张测试SD卡来创建数据库。请查看

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