外部存储的安全途径

对于我的应用程序,我有一个相当大的数据库,需要存储在用户的设备上。 我打算将来改变它。 但是,现在,我想将它存储到用户的外部存储(如果可用),而不是填满他们的内部存储。 我可以使用什么方法来获得外部存储的安全(意味着,可以在大多数设备上工作)?

您可以获得存储数据的根路径。 我认为这将是最安全的案例。

String root = Environment.getExternalStorageDirectory().toString(); File dir = new File(root + "/your_folder"); dir.mkdirs(); dir.setReadOnly(); 

我用

 File rootPath = Environment.getExternalStorageDirectory(); String StorageDir = new File(rootPath.getPath()+"/"+DirectoryName); 

其中DirectoryName是要使用的ExternalStorage中子目录的名称。 没有人向我报告任何问题。

我有一个三星galaxy s3(运行android 4.1.2),我的内存名为sdCard0,我的外部SD卡名为extSdCard。

所以Environment.getExternalStorageDirectory()返回了我内部手机内存的sdCard0路径

在这种情况下,您可以使用以下内容来获取外部存储的实际路径。 但是不建议这样做。 我建议你按照文档进行操作

http://developer.android.com/guide/topics/data/data-storage.html

 String externalpath = new String(); String internalpath = new String(); public void getExternalMounts() { Runtime runtime = Runtime.getRuntime(); try { Process proc = runtime.exec("mount"); InputStream is = proc.getInputStream(); InputStreamReader isr = new InputStreamReader(is); String line; BufferedReader br = new BufferedReader(isr); while ((line = br.readLine()) != null) { if (line.contains("secure")) continue; if (line.contains("asec")) continue; if (line.contains("fat")) {//external card String columns[] = line.split(" "); if (columns != null && columns.length > 1) { externalpath = externalpath.concat("*" + columns[1] + "\n"); } } else if (line.contains("fuse")) {//internal storage String columns[] = line.split(" "); if (columns != null && columns.length > 1) { internalpath = internalpath.concat(columns[1] + "\n"); } } } } catch(Exception e) { e.printStackTrace(); } System.out.println("Path of sd card external............"+externalpath); System.out.println("Path of internal memory............"+internalpath); } 

在大多数情况下,上述工作

  File dir = new File(externalpath + "/MyFolder"); if(!dir.exists) { dir.mkdirs(); dir.setReadOnly(); } 

不要忘记在清单文件中添加权限

   

您还应该检查SD卡是否已安装在您的设备上

  if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED) { // sdcard mounted } 

我们可能想要考虑获取父目录……

 String myPath = Environment.getExternalStorageDirectory().getParent(); //mypath = /storage 

就我而言,我有一个GS4和一个Note 10.1。 上面返回了一个名为“storage”的文件夹,其中包含sdCard0(内部)和extSdCard(存储卡)文件夹。

我正在玩一个文件浏览器类型的应用程序,但我只对显示坐骑感兴趣。 在使用.isHidden()和.canRead()方法过滤掉系统文件夹后,这会在ListView中显示extCard和sdcard0。

 public class MainActivity extends Activity { private ListView lvFiles; private TextView label; private List item = null; private List path = null; private String intRoot, extRoot; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); lvFiles = (ListView) findViewById(R.id.lvFiles); label = (TextView) findViewById(R.id.tvLabel); extRoot = Environment.getExternalStorageDirectory().getParent(); label.setText(extRoot); displayFiles(extRoot); } /** Inflate menu */ @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater m = getMenuInflater(); m.inflate(R.menu.main_menu, menu); return super.onCreateOptionsMenu(menu); } private void displayFiles(String p) { File f = new File(p); File[] files = f.listFiles(); item = new ArrayList(); path = new ArrayList(); for (int i=0; i filelist = new ArrayAdapter(this, R.layout.row, item); lvFiles.setAdapter(filelist); } 

当然,我没有用非三星设备测试这个。 不能等待KitKat,因为它将包括开发人员轻松找到存储卡的方法。

是的,KitKat现在提供用于与辅助外部存储设备交互的API:

新的Context.getExternalFilesDirs()Context.getExternalCacheDirs()方法可以返回多个路径,包括主设备和辅助设备。 然后,您可以迭代它们并检查Environment.getStorageState()File.getFreeSpace()以确定存储文件的最佳位置。 这些方法也可以在support-v4库中的ContextCompat上使用。

另请注意,如果您只对使用Context返回的目录感兴趣,则不再需要READ_WRITE_EXTERNAL_STORAGE权限。 outlook未来,您将始终拥有对这些目录的读/写访问权限,而无需其他权限。

应用程序还可以通过终止其权限请求继续处理旧设备,如下所示: