android关于data/data/目录下,各应用之间的私有数据读写

下面简单介绍一下,我的方法,可能有点笨拙。

我主要用的是Context.openFileOutput()和Context.openFileInput()方法。

测试部分,被用到的应用先存入一个文件,做好被调用准备。代码如下:

    //定义文件的名称  
    String oldfileName = "/data/data/com.data.datatest/files/hy.txt";  

    //写入和读出的数据信息  
    String message = "来,战个痛快!";  
    TextView test;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        test = (TextView) findViewById(R.id.testTextview);
        File aFile = new File(oldfileName);
        writeDatabaseFile(aFile, message);
        test.setText(message);
    }
    
    public void writeDatabaseFile(File fileName,String fileContext){
    	try {
    		Log.e("1111", "fileName.getName()= "+fileName.getName());		//设置文件权限
    		FileOutputStream fileOutputStream = openFileOutput("hh.txt",
    				Context.MODE_WORLD_READABLE+ Context.MODE_WORLD_WRITEABLE);
			byte[] temBytes = fileContext.getBytes();
			fileOutputStream.write(temBytes);
			fileOutputStream.close(); 
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
    }

至此在应用程序里的/data/data/包名/files/路径下有个hh.txt文件了。权限为


下面为调用该文件的应用代码:

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		try {
			Context c = createPackageContext("com.data.datatest",
					Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
			readFileData(c);
		} catch (NameNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		setContentView(R.layout.activity_main);
		TextView aTextView = (TextView) findViewById(R.id.useText);
		aTextView.setText(result);
	}
	
	// 打开指定文件,读取其数据,返回字符串对象
	public String readFileData(Context tempContext) {
		try {
			FileInputStream fin = tempContext.openFileInput("hh.txt");
			FileOutputStream outputStream = openFileOutput("hy.txt",
					Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);
			int lenght = fin.available(); // 获取文件长度
			byte[] buffer = new byte[lenght];
			int c;
			while ((c = fin.read(buffer)) > 0) {
				outputStream.write(buffer, 0, c);
			}
			fin.close();
			outputStream.close();
			// 将byte数组转换成指定格式的字符串
			result = EncodingUtils.getString(buffer, ENCODING);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

Context c = createPackageContext("com.data.datatest",Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);

Context有个createPackageContext方法,可以创建另外一个包的上下文,这个实例不同于它本身的Context实例,但是功能是一样的。

这个方法有两个参数:

1. packageName 包名,要得到的应用的包名

2. flags 标志位,有CONTEXT_INCLUDE_CODE和CONTEXT_IGNORE_SECURITY两个选项。CONTEXT_INCLUDE_CODE的意思是包括代码,即可以执行这个包里面的代码。CONTEXT_IGNORE_SECURITY的意思是忽略安全警告,如果不加这个歌标志位的话,有些功能就用不了的,会出现安全警告。

代码里将Context  c 作为参数传入readFileData里面,由于Context 有openFileInput函数,通过这个函数就可以直接得到你想得到的应用程序包里面的Files文件夹下的文件,而这里的openFileOutput("hy.txt",Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);则是在自己应用里建立hy.txt文件,然后通过输入流写进输出流,就实现了拷贝别的应用里的文件到自己的应用里。


接下来就是写别的应用里的数据,方法类似,主要是context的使用。

	public void writeFileAndSave(Context tempContext) throws IOException{
		String testStr = "美得不得了";
		FileOutputStream outputStream = tempContext.openFileOutput("hh.txt",
				Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);
		byte[] buffer = testStr.getBytes();
		outputStream.write(buffer);
		outputStream.close();
	}

各应用之间数据读写主要是context的使用。另外,应用中的cache,files的权限是一样的。都能互相访问,但是如果是自己创建的文件夹则只有被自己应用调用的权限。

另外一种方法,比较简单:就是设置文件夹和文件权限。

网上有可以修改自己建的文件夹和文件的权限,我又测试了一下,发现也能实现,被调用的程序包的文件,设置权限:

    public void initChmodDir(){
		File destDir = new File("/data/data/com.data.datatest/test/mmp.txt");
		if (!destDir.exists()) {
			destDir.getParentFile().mkdirs();
		}
		writeDatabaseFile(destDir, "你比大S多个B,大SB!");
		Process p;
		int status = -1;
		try {
			p = Runtime.getRuntime().exec("chmod 777 " + destDir);
			p = Runtime.getRuntime().exec("chmod 777 " + destDir.getParentFile());
			status = p.waitFor();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (status == 0) {    
			//chmod succeed   
		    Toast.makeText(this, "chmod succeed", Toast.LENGTH_LONG).show();
		} else {    
			//chmod failed 
			Toast.makeText(this, "chmod failed", Toast.LENGTH_LONG).show();
		}
    }
    public void writeDatabaseFile(File fileName,String fileContext){
    	try {
    		Log.e("1111", "fileName.getName()= "+fileName.getName());
    		FileOutputStream fileOutputStream = new FileOutputStream(fileName);
//    		FileOutputStream fileOutputStream = openFileOutput("hh.txt",
//    				Context.MODE_WORLD_READABLE+ Context.MODE_WORLD_WRITEABLE);
			byte[] temBytes = fileContext.getBytes();
			fileOutputStream.write(temBytes);
			fileOutputStream.close(); 
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
    }

然后是调用者部分:

	public String readTestFileData(Context tempContext) {
		File oldFile = new File("/data/data/com.data.datatest/test/mmp.txt");
		if (oldFile.exists()) {
			File newfile = new File("/data/data/com.usedata.usefile/huyi/hy.txt");
			if (!newfile.exists()) {
				newfile.getParentFile().mkdirs();
			}
			writeDatabaseFile(newfile, oldFile);
		}
		return result;
	}
	
	public void writeDatabaseFile(File fileName,File oldFile){
    	try {
    		FileInputStream inputStream = new FileInputStream(oldFile);
    		FileOutputStream fileOutputStream = new FileOutputStream(fileName);
    		int lenght = inputStream.available(); // 获取文件长度
			byte[] buffer = new byte[lenght];
			int c;
			while ((c = inputStream.read(buffer)) > 0) {
				fileOutputStream.write(buffer, 0, c);
			}
			fileOutputStream.close(); 
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
    }

前后截图为:



验证过后发现权限确实改了,而且文件也复制过来了,包括文件内容。

总结,如果用openFileInput或者openFileOutput就需要获取被调用的context。如果不用就需要修改被调用文件夹和文件的权限。



你可能感兴趣的:(Android)