可编辑特定应用文件

时间:2018-06-01 08:34:13

标签: android file storage

我正在创建一个应用程序,该应用程序需要特定于应用程序的文件,我称之为#34; conf.cfg "例如。我的应用程序需要读取此文件以创建一些对象等...文件的主体看起来像这样:

#activation, level, type, regex or array 0, "critic", 0,"\\d{4}\\w\\d{3}" 1, "critic", 1, [word1,word2] 1,"minor", 0,"\\d{2}-\\w{3}-\\d{4}\\s?\\/?\\s?\\d{2}:\\d{2}"

进行我的研究我发现android中有两种类型的存储:

  1. 内部存储:
  2.   

    如果您想确保用户和其他应用都无法访问您的文件,则最好使用内部存储。

    1. 外部情况:
    2.   

      外部存储空间是不需要访问限制的文件以及您希望与其他应用共享或允许用户通过计算机访问的文件的最佳位置。

      由于我希望用户能够编辑/下载/上传/使用此文件,因此外部存储似乎是一个不错的选择。但是在Developper Android,他们说:

        

      警告:如果用户卸下SD卡或将设备连接到计算机,外部存储可能会变得不可用。并且文件仍然对用户和具有READ_EXTERNAL_STORAGE权限的其他应用程序可见。因此,如果您的应用程序的功能取决于这些文件,或者您需要完全限制访问,则应将文件写入内部存储。

           

      警告:外部存储上的文件并非始终可访问,因为用户可以将外部存储装载到计算机以用作存储设备。因此,如果您需要存储对应用程序功能至关重要的文件,则应将其存储在内部存储中。

      由于此文件需要始终可用,并且对我的应用的功能至关重要 所以...内部存储似乎更好。但我需要用户查看并能够使用该文件。在这里,我被困住了。

      任何人都知道放置/创建此文件的位置和方式?

      编辑:关注@greenapps回答

      heer是我写过的一段代码。我使用getExternalFilesDir(null)命令来编写和存储我的文件

          String folderName = "Innovation";
          String confFileName = "conf.txt";
          String commentSymbol = "#";
          String commentLine = commentSymbol + " activation, level, type , regex or array";
      
          File storage = getExternalFilesDir(null);
          File folder = new File(storage, folderName);
          File conf = new File(folder, confFileName);
      
          Log.d(TAG, "Folder action!");
          if (!folder.exists()) {
              if (folder.mkdirs()) {
                  Log.d(TAG, "Created : " + folder.getAbsolutePath());
              } else {
                  Log.e(TAG, "folder not created!");
              }
          }
      
          Log.d(TAG, "File action!");
          if (!conf.exists()) {
              try {
                  Log.d(TAG, "opening...");
                  FileOutputStream fos = new FileOutputStream(conf);
                  fos.write(commentLine.getBytes());
                  fos.close();
                  Log.d(TAG, "Created : " + conf.getAbsolutePath());
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      
          if (conf.exists()) {
              Log.d(TAG, "File exist at : " + conf.getAbsolutePath());
          }
      

      创建文件,如上一个日志所示

        

      已创建:/storage/emulated/0/Android/data/com.aralex.innovation/files/Innovation/conf.txt

      但是当我使用手机的原生文件浏览器应用程序搜索文件时,我无法找到它。我可以去文件夹,但文件夹" Innovation /"是隐藏的。

      这是一个问题,因为我希望文件可见。

      电话:三星s7,s7edge,s9 +

      Default File Explorer Icon

      Default File Explorer Oppened

2 个答案:

答案 0 :(得分:0)

所以外部存储。

没有内部资源,因为文件资源管理器无法访问您的应用专用内存。

您可以使用getExternalFilesDir(null),因为您不需要读写权限

答案 1 :(得分:0)

我终于找到了答案。

在这篇文章Android create folders in Internal Memory @prodev中指定Environment.getExternalStorageDirectory()是一个好地方,因为该文件可以访问并且:

  

请注意,Environment.getExternalStorageDirectory()中的ExternalStorage不一定是指sdcard,它返回手机主存储器

它需要权限(仅适用于构建版本> = M):

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />

所以这是一个回答我的问题的代码(它在运行时询问权限):

private ArrayList<Rule> ruleList; 

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    [...]

    // Check for the storage permission before accessing the camera.  If the
    // permission is not granted yet, request permission.
    if (hasPermissions(this, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
            || Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        ruleList = createRules();
    } else {
        requestStoragePermission();
    }
}

private boolean hasPermissions(Context context, String... permissions) {
    if (context != null && permissions != null) {
        for (String permission : permissions) {
            Log.d(TAG, "Checking permission : " + permission);
            if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                Log.w(TAG, "not granted : " + permission);
                return false;
            } else {
                Log.d(TAG, "granted : " + permission);
            }
        }
    }
    return true;
}

/**
 * Handles the requesting of the storage permission.  This includes
 * showing a "Snackbar" errorMessage of why the permission is needed then
 * sending the request.
 */
private void requestStoragePermission() {
    Log.w(TAG, "Storage permission is not granted. Requesting permission");

    final String[] permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE};

    if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
        ActivityCompat.requestPermissions(this, permissions, RC_HANDLE_EXTERNAL_PERM);
        return;
    }

    final Activity thisActivity = this;

    View.OnClickListener listener = view -> ActivityCompat.requestPermissions(thisActivity, permissions,
            RC_HANDLE_EXTERNAL_PERM);

    Snackbar.make(findViewById(android.R.id.content), R.string.permission_storage_rationale,
            Snackbar.LENGTH_INDEFINITE)
            .setAction(R.string.ok, listener)
            .show();
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    if (requestCode != RC_HANDLE_EXTERNAL_PERM) {
        Log.d(TAG, "Got unexpected permission result: " + requestCode);
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        return;
    }

    if (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED
            && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
        Log.d(TAG, "Storage permission granted");
        // We have permission
        ruleList = createRules();
        return;
    }

    Log.e(TAG, "Permission not granted: results len = " + grantResults.length +
            " Result code = " + (grantResults.length > 1 ? grantResults[0] + " " + grantResults[1] : grantResults.length > 0 ? grantResults[0] : "(empty)"));

    DialogInterface.OnClickListener listener = (dialog, id) -> finish();

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Assisting Tool")
            .setMessage(R.string.no_storage_permission)
            .setPositiveButton(R.string.ok, listener)
            .show();
}

private ArrayList<Rule> createRules() {
    Log.d(TAG, "=========================READING FILE======================");

    ArrayList<Rule> ruleList = new ArrayList<>();

    String folderName = "Innovation";
    String confFileName = "conf.txt";
    String commentSymbol = "#";
    String commentLine = commentSymbol + " activation, level, type , regex or array";

    File storage = Environment.getExternalStorageDirectory();
    File folder = new File(storage, folderName);
    File conf = new File(folder, confFileName);

    Log.d(TAG, "Folder action!");
    if (!folder.exists()) {
        if (folder.mkdirs()) {
            Log.d(TAG, "Created : " + folder.getAbsolutePath());
        } else {
            Log.e(TAG, "folder not created!");
        }
    }

    Log.d(TAG, "File action!");
    if (!conf.exists()) {
        try {
            Log.d(TAG, "opening...");
            FileOutputStream fos = new FileOutputStream(conf);
            fos.write(commentLine.getBytes());
            fos.close();
            Log.d(TAG, "Created : " + conf.getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    if (conf.exists()) {
        Log.d(TAG, "File exist at : " + conf.getAbsolutePath());
    } else {
        Log.e(TAG, "The file doesn't exist...");
    }
}

现在它创建了一个特定于应用程序的文件

  

/storage/emulated/0/Innovation/conf.txt

用户可以访问!