SWIK
SWIK

Reputation: 880

Edit/Modify Uri referenced file using FileOutputStream Android

I am using ActivityResultLauncher to fetch uri of a file. Now I want to modify that file using fileoutputStream but can't, since fileoutputstream need path string. Here is a code that I am using to get File Uri:

ActivityResultLauncher<Intent> someActivityResultLauncher = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
                if (result.getResultCode() == Activity.RESULT_OK) {
                    // There are no request codes
                    Intent data = result.getData();
                    Uri uri = data.getData();//this gets me URI
                    

                }
            }
      });

public void openFileChooser()
{
    Intent data = new Intent(Intent.ACTION_GET_CONTENT);
    data.addCategory(Intent.CATEGORY_OPENABLE);
    data.setType("*/*");
    data = Intent.createChooser(data, "Choose a file");
    Intent intent = Intent.createChooser(data, "Choose a file");
    someActivityResultLauncher.launch(intent);
}

The code works perfect for picking and reading file. But I am not able to use below mentioned function to write same file using:

static void writeToFile(String path,String data,Context context) {
    try {
        FileOutputStream output = null;
        output = new FileOutputStream(path, false);
        output.write(data.getBytes());
        output.close();
        Toast.makeText(getApplicationContext(),"SAVED",Toast.LENGTH_LONG).show();
    }
    catch (IOException e) {
        Toast.makeText(getApplicationContext(),"File write failed: " + e.toString(),Toast.LENGTH_LONG).show();
    }
}

I have tried uri.getPath() but it is returning /document/msf:21. That is some complicated uri string and can't be used as file path. I have also been trying to use realPath functions mentioned in stackflow and other forums but do not find it working (they may work but they are depending upon API levels that making them not reliable). So, what actually want to ask:

1- Is there any other way to pick file to get actual path?

2- If there is no way to pick path, how can I write to File using direct Uri? and not using getpath or path string.

3- Is there a way to use fileoutstream with Uri in this scenario where Uri is only available?

Thanks

Upvotes: 1

Views: 695

Answers (2)

J. M.
J. M.

Reputation: 115

You need to pass it through input stream amd buffer reader with output stream.

Try this on start intent

Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("application/pdf");
intent.putExtra(Intent.EXTRA_TITLE, "JWI.pdf");
startActivityForResult(intent, CREATE_FILE);

Try this on activity result

try {
uri = _data.getData();
muri = uri.toString();
t.edit().putString("Uri", muri).commit();
        
final int takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION | 
Intent.FLAG_GRANT_WRITE_URI_PERMISSION; 
getContentResolver().takePersistableUriPermission(uri, takeFlags);
        
        
DocumentFile doc = DocumentFile.fromSingleUri(this, uri);
boolean doo = doc.exists();
if (!doo) {
DocumentFile f = doc.createFile("pdf/plain", "JAMZ.pdf");}
        
ContentResolver cr = getContentResolver(); OutputStream output =
cr.openOutputStream(uri); 
java.io.InputStream asset = getAssets().open("JWI.pdf");


final byte[] buffer = new byte[1024];

int size;

while ((size = asset.read(buffer)) != -1) {

output.write(buffer, 0, size);

}

asset.close();

output.close();
} catch (Exception e) {}}}

Upvotes: 0

blackapps
blackapps

Reputation: 9292

OutputStream os = getContentResolver().openOutputStream(data.getData());

Upvotes: 1

Related Questions