如何以编程方式更改文件/文件夹的权限在android系统 [英] How to change the file/folder permission programmatically in android

查看:327
本文介绍了如何以编程方式更改文件/文件夹的权限在android系统的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想换都被存储应用程序数据库文件夹的权限。

在谷歌搜索后,我发现这一点: -

 公众诠释CHMOD(文件路径,诠释模式)抛出异常{
  类文件实用=的Class.forName(android.os.FileUtils);
  方法setPermissions =
      fileUtils.getMethod(setPermissions,为String.class,int.class,int.class,int.class);
  返回(整数)setPermissions.invoke(空,path.getAbsolutePath(),模式,-1,-1);
}...
CHMOD(/富/酒吧/巴兹,0755);
...

下面的文件实用类应该是 android.os 包的一部分,但我没能找到它在导入包。

不知道如何使用文件实用或其他方式来改变文件夹?允许

我改变了权限,因为安装我的应用程序,当我尝试访问数据库之后,应用程序停止工作。由于我的设备是扎根所以当我更改数据库文件夹的权限从 771 777 使用根浏览器应用程序开始工作完美。

那么如何改变文件夹的权限,而在编程安装应用程序,即无根设备?

我的 DBHelper 类: -

 公共类DBHelper扩展SQLiteOpenHelper {公共SQLiteDatabase数据库= NULL;
公共文件databaseFile;
公共静态字符串的databaseName =Db1.sqlite;
公共字符串databasePath =;
上下文mContext;公共DBHelper(上下文paramContext){    超(paramContext,的databaseName,空,1);
    this.mContext = paramContext;    Log.d(数据,包名+ paramContext.getPackageName());    //this.databasePath =(数据/数据​​/+ paramContext.getPackageName()+/数据库/+的databaseName);
    this.databasePath = (Environment.getExternalStorageDirectory().getAbsolutePath()+\"/Android/data/\"+paramContext.getPackageName()+\"/\"+databaseName);
    的System.out.println(databasePath);
    this.databaseFile =新的文件(this.databasePath);
    如果(!this.databaseFile.exists())
        尝试{
            deployDataBase(DBHelper.databaseName,this.databasePath);
            返回;
        }赶上(IOException异常localIOException){
            localIOException.printStackTrace();
        }
}私人无效deployDataBase(DBNAME字符串,字符串DBPATH)
        抛出IOException
    InputStream的localInputStream = this.mContext.getAssets()开(数据库)。
    FileOutputStream中localFileOutputStream =新的FileOutputStream(DBPATH);
    字节[] = arrayOfByte新的字节[1024];
    而(真){
        INT I = localInputStream.read(arrayOfByte);
        如果(ⅰ&下; = 0){
            localFileOutputStream.flush();
            localFileOutputStream.close();
            localInputStream.close();
            返回;
        }
        localFileOutputStream.write(arrayOfByte,0,I);
    }
}@覆盖
公共同步无效的close(){    如果(数据库!= NULL)
        database.close();    super.close();}
@覆盖
公共无效的onCreate(SQLiteDatabase DB){
    // TODO自动生成方法存根}


解决方案

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


  • 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

这篇关于如何以编程方式更改文件/文件夹的权限在android系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆