Search code examples
androidandroid-intentandroid-contentprovider

Send uri to text editor app and have it save


Conceptually what I'm looking to do is send a resource uri (which references my content provider (CP)) from my app (A) to a text editor app (B) (which the user picks) such that the text editor accesses the uri as a text stream and has the ability to edit and save the file. Some notification back from the text editor (B) would be desirable but I may be able to use the CP to become aware of "writes" for example.

Do intents and CPs support this level of interaction?

Essentially, I don't want to have to write my own text editor in my app - my app manages the data (via content provider) and the text editor manipulates.

Perhaps sending the data to a temporary external storage location and send the file path to the editor - but that seems more complicated than is needed.


Solution

  • Well I ended up using FileProvider class and walked through the supporting documentation resulting in the below code. Not quite what I was originally intending on doing but conceptually the result is the same (user presses button - edits file/saves - user returns back to app):

    (in AndroidManifest.xml>

        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="my.package.name.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
    

    and in res/xml/file_paths.xml:

    <?xml version="1.0" encoding="utf-8"?>
        <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <files-path name="notes" path="notes/"/>
    </paths>
    

    and in a button listener (which the user would expect to see/edit their notes):

    private class AddNoteListener implements View.OnClickListener {
    
        @Override
        public void onClick(View v) {
            File notesPath = new File(context.getFilesDir(), "notes");
            if (notesPath.exists() == false) {
                notesPath.mkdir();
            }
            File newFile = new File(notesPath, "my_note.txt");
            try {
                if (newFile.exists() == false) {
                    newFile.createNewFile();
                }
                Uri contentUri = FileProvider.getUriForFile(context, "my.package.name.fileprovider", newFile);
                Intent intent = new Intent(Intent.ACTION_EDIT);
                intent.setDataAndType(contentUri, "text/plain");
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    
                List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent,  PackageManager.MATCH_DEFAULT_ONLY);
                for (ResolveInfo resolveInfo : resInfoList) {
                    String packageName = resolveInfo.activityInfo.packageName;
                    context.grantUriPermission(packageName, contentUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
                }
                context.startActivity(Intent.createChooser(intent,"Title"));
            } catch (IOException ioe) {
                e.printStackTrace();
            }
        }
    }
    

    References:

    Granting permissions
    Proper mime type
    FileProvider