4.6.1.2 使用公共只读文件
这是使用文件向未指定的大量应用公开内容的情况。 如果通过遵循以下几点来实现,那么它也是比较安全的文件使用方法。 请注意,在 API 级别 1 7及更高版本中,不推荐使用MODE_WORLD_READABLE变量来创建公共文件,并且在 API 级别 24 及更高版本中,会触发安全异常; 因此使用内容供应器的文件共享方法更可取。
要点:
文件必须在应用目录中创建。
文件的访问权限必须设置为其他应用只读。
敏感信息不得存储。
对于要存储在文件中的信息,请仔细和安全地处理文件数据。
PublicFileActivity.java
package org.jssec.android.file.publicfile.readonly;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.TextView;public class PublicFileActivity extends Activity {private TextView mFileView;private static final String FILE_NAME = "public_file.dat";@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.file);mFileView = (TextView) findViewById(R.id.file_view);}/*** Create file process** @param view*/public void onCreateFileClick(View view) {FileOutputStream fos = null;try {// *** POINT 1 *** Files must be created in application directory.// *** POINT 2 *** The access privilege of file must be set to read only to other applications.// (MODE_WORLD_READABLE is deprecated API Level 17,// don't use this mode as much as possible and exchange data by using ContentProvider().)fos = openFileOutput(FILE_NAME, MODE_WORLD_READABLE);// *** POINT 3 *** Sensitive information must not be stored.// *** POINT 4 *** Regarding the information to be stored in files, handle file data carefully and securely.// Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."fos.write(new String("Not sensitive information (Public File Activity)¥n").getBytes());} catch (FileNotFoundException e) {mFileView.setText(R.string.file_view);} catch (IOException e) {android.util.Log.e("PublicFileActivity", "failed to read file");} finally {if (fos != null) {try {fos.close();} catch (IOException e) {android.util.Log.e("PublicFileActivity", "failed to close file");}}}finish();}/*** Read file process** @param view*/public void onReadFileClick(View view) {FileInputStream fis = null;try {fis = openFileInput(FILE_NAME);byte[] data = new byte[(int) fis.getChannel().size()];fis.read(data);String str = new String(data);mFileView.setText(str);} catch (FileNotFoundException e) {mFileView.setText(R.string.file_view);} catch (IOException e) {android.util.Log.e("PublicFileActivity", "failed to read file");} finally {if (fis != null) {try {fis.close();} catch (IOException e) {android.util.Log.e("PublicFileActivity", "failed to close file");}}}}/*** Delete file process** @param view*/public void onDeleteFileClick(View view) {File file = new File(this.getFilesDir() + "/" + FILE_NAME);file.delete();mFileView.setText(R.string.file_view);}}
PublicUserActivity.java
package org.jssec.android.file.publicuser.readonly;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import android.app.Activity;import android.content.ActivityNotFoundException;import android.content.Context;import android.content.Intent;import android.content.pm.PackageManager.NameNotFoundException;import android.os.Bundle;import android.view.View;import android.widget.TextView;public class PublicUserActivity extends Activity {private TextView mFileView;private static final String TARGET_PACKAGE = "org.jssec.android.file.publicfile.readonly";private static final String TARGET_CLASS = "org.jssec.android.file.publicfile.readonly.PublicFileActivity";private static final String FILE_NAME = "public_file.dat";@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.user);mFileView = (TextView) findViewById(R.id.file_view);}private void callFileActivity() {Intent intent = new Intent();intent.setClassName(TARGET_PACKAGE, TARGET_CLASS);try {startActivity(intent);} catch (ActivityNotFoundException e) {mFileView.setText("(File Activity does not exist)");}}/*** Call file Activity process** @param view*/public void onCallFileActivityClick(View view) {callFileActivity();}/*** Read file process** @param view*/public void onReadFileClick(View view) {FileInputStream fis = null;try {File file = new File(getFilesPath(FILE_NAME));fis = new FileInputStream(file);byte[] data = new byte[(int) fis.getChannel().size()];fis.read(data);// *** POINT 4 *** Regarding the information to be stored in files, handle file data carefully and securely.// Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."String str = new String(data);mFileView.setText(str);} catch (FileNotFoundException e) {android.util.Log.e("PublicUserActivity", "no file");} catch (IOException e) {android.util.Log.e("PublicUserActivity", "failed to read file");} finally {if (fis != null) {try {fis.close();} catch (IOException e) {android.util.Log.e("PublicUserActivity", "failed to close file");}}}}/*** Rewrite file process** @param view*/public void onWriteFileClick(View view) {FileOutputStream fos = null;boolean exception = false;try {File file = new File(getFilesPath(FILE_NAME));// Fail to write in. FileNotFoundException occurs.fos = new FileOutputStream(file, true);fos.write(new String("Not sensitive information (Public User Activity)¥n").getBytes());} catch (IOException e) {mFileView.setText(e.getMessage());exception = true;} finally {if (fos != null) {try {fos.close();} catch (IOException e) {exception = true;}}}if (!exception)callFileActivity();}private String getFilesPath(String filename) {String path = "";try {Context ctx = createPackageContext(TARGET_PACKAGE,Context.CONTEXT_RESTRICTED);File file = new File(ctx.getFilesDir(), filename);path = file.getPath();} catch (NameNotFoundException e) {android.util.Log.e("PublicUserActivity", "no file");}return path;}}
