In my android native java project, I want one functionality that will create a .txt file by taking input from user. Then, while saving the file, we will use file picker to open and select one directory. Here, it will ask for permission to allow write in that directory.
compileSdk = 34, targetSdk = 34
Here's the code:
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.documentfile.provider.DocumentFile;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.bjit.fliecreateshowread.model.FileInfo;
import com.bjit.fliecreateshowread.adapter.FileInfoListAdapter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class CreateFileActivity extends AppCompatActivity {
private EditText edtFileName;
private EditText edtFileDesc;
private Button btnSaveFile;
private static final int REQUEST_WRITE_EXTERNAL_STORAGE = 1;
private static final int PICK_DIRECTORY_REQUEST_CODE = 123;
private FilePicker filePicker;
private List<FileInfo> fileInfoList;
private RecyclerView rvFileInformationList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_file);
fileInfoList = new ArrayList<>();
filePicker = new FilePicker();
edtFileName = findViewById(R.id.edtFileName);
edtFileDesc = findViewById(R.id.edtFileDesc);
btnSaveFile = findViewById(R.id.btnSaveFile);
rvFileInformationList = findViewById(R.id.rvFileInformationList);
btnSaveFile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
filePicker.pickDirectory(CreateFileActivity.this);
}
});
}
@Override
public void onRequestPermissionsResult(
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_WRITE_EXTERNAL_STORAGE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted, you can proceed with file creation
} else {
Toast.makeText(this, "Permission Denied!", Toast.LENGTH_SHORT).show();
}
}
}
private void createAndSaveTextFileOnSDCard(Intent data, String fileName, String fileDesc) {
Uri uri = data.getData();
if (uri != null) {
DocumentFile documentFile = DocumentFile.fromTreeUri(this, uri);
if (documentFile != null && documentFile.exists()) {
DocumentFile file = documentFile.createFile("text/plain", fileName + ".txt");
try (OutputStream outputStream = getContentResolver().openOutputStream(file.getUri())) {
if (outputStream != null) {
String content = fileDesc;
outputStream.write(content.getBytes());
Log.e("##PATH", file.getUri().toString());
Toast.makeText(this, "File saved: " + file.getUri().toString(), Toast.LENGTH_SHORT).show();
// Read the file content after saving
String fileContent = readTextFile(file.getUri());
Log.e("##FILE_CONTENT", fileContent);
FileInfo fileInfo = new FileInfo(fileName, file.getUri().toString());
showFilesInDirectory(documentFile.getUri());
}
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "Error saving file: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, "Selected directory not found or does not exist", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, "Invalid URI", Toast.LENGTH_SHORT).show();
}
}
private String readTextFile(Uri fileUri) {
StringBuilder content = new StringBuilder();
try (InputStream inputStream = getContentResolver().openInputStream(fileUri);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = reader.readLine()) != null) {
content.append(line).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "Error reading file: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
return content.toString();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_DIRECTORY_REQUEST_CODE && resultCode == Activity.RESULT_OK && data != null) {
createAndSaveTextFileOnSDCard(data, edtFileName.getText().toString(), edtFileDesc.getText().toString());
}
}
private void showFilesInDirectory(Uri directoryUri) {
DocumentFile directory = DocumentFile.fromTreeUri(this, directoryUri);
if (directory != null && directory.exists() && directory.isDirectory()) {
DocumentFile[] files = directory.listFiles();
fileInfoList.clear();
if (files != null && files.length > 0) {
// Iterate through the list of files and display their names or perform other actions
for (DocumentFile file : files) {
Log.e("##FILE_IN_DIRECTORY", "File Name: " + file.getName() + ", File URI: " + file.getUri());
// You can display the file names in a ListView, RecyclerView, or perform other actions here
FileInfo fileInfo = new FileInfo(file.getName(), file.getUri().toString());
fileInfoList.add(fileInfo);
}
rvFileInformationList.setLayoutManager(new LinearLayoutManager(this));
FileInfoListAdapter adapter = new FileInfoListAdapter((ArrayList<FileInfo>) fileInfoList, CreateFileActivity.this);
rvFileInformationList.setAdapter(adapter);
adapter.notifyDataSetChanged();
} else {
Log.e("##FILE_IN_DIRECTORY", "No files in the directory");
}
} else {
Log.e("##FILE_IN_DIRECTORY", "Invalid directory or directory does not exist");
}
}
}
------- Now the problem is ---------
Even if I have allowed permission for one folder that I have already saved file and granted permission, whenever I am trying to save another file in the same directory, it is again asking me to allow permission. How can I avoid this and only ask for a single time permission for one folder?
