android – ContentProvider and openFile: serving files based on URI

Question:

Hello!

There is an inherited LocalFileContentProvider in it openFile. The content provider is used to work with the WebView in order to throw scripts, styles, data, pictures on the loaded page … And it looked like this in the HTML page:

content://com.example/images/picture.jpg
content://com.example/scripts/main.js
content://com.example/styles/main.css

The URI needs to "decompose": / images, / scripts, / styles … all Files will be stored in Assets / Provider_html. Or if you can do it in the subfolders: / images, / scripts, / styles … And in Java code, so that the page load in the WebView looks like this:

mWebView.loadUrl("content://com.example/TList2.htm?Status=Good");

those. so that the URI is decomposed as follows: the TList2.htm page in the WebView is loaded, then the URI looked Status =, if we assume it is Good, then this corresponds to Data2.txt, if it is NoGood, then it corresponds to Data4.txt. And it was transferred to an HTML page, let's say Data2.txt, in order for it to be in JavaScript: var sd = read the Data2.txt file. Or send the URI to the HTML page and read there: var sd = read content: //com.example/TList2.htm? Status = Good or so content: //com.example/? Status = Good

Now it works like this: files are loaded like this

content://com.example/picture.jpg
content://com.example/main.js
content://com.example/main.css

Page is loading into WebView

mWebView.loadUrl("content://com.example/TList2.htm");

No data is being transferred yet …

How to implement these things in openFile, so that, depending on the URI, it gives the necessary files + loads the data … This is what we have now:

public static final String AUTHORITY = "com.example.LocalFileContentProvider";

private static final String IMAGES_FOLDER_STR = "images/*";
private static final String SCRIPTS_FOLDER_STR = "scripts/*";
private static final String STYLES_FOLDER_STR = "styles/*";
private static final String T_LIST_STR = "*?Status=*";
private static final String T_STR = "*?id=#";

private static final int IMAGES_FOLDER_ID = 15;
private static final int SCRIPTS_FOLDER_ID = 16;
private static final int STYLES_FOLDER_ID = 17;
private static final int T_LIST_ID = 18;
private static final int T_ID = 19;

private static final UriMatcher sUriMatcher;
static
{
    sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    sUriMatcher.addURI(AUTHORITY, IMAGES_FOLDER_STR, IMAGES_FOLDER_ID);
    sUriMatcher.addURI(AUTHORITY, SCRIPTS_FOLDER_STR, SCRIPTS_FOLDER_ID);
    sUriMatcher.addURI(AUTHORITY, STYLES_FOLDER_STR, STYLES_FOLDER_ID);
    sUriMatcher.addURI(AUTHORITY, T_LIST_STR, T_LIST_ID);
    sUriMatcher.addURI(AUTHORITY, T_STR, T_ID);

}

@Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
{

    Log.d("LocalFileContentProvider","fetching: " + uri);

    String path = getContext().getFilesDir().getAbsolutePath() + "/" + uri.getPath();
    File file = new File(path);
    ParcelFileDescriptor parcel = null;
    try
    {
        parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
    }
    catch (FileNotFoundException e)
    {
        Log.d("LocalFileContentProvider", "uri " + uri.toString(), e);
    }
    return parcel;
}

As I understand it, you need to insert a piece of such a plan into the public ParcelFileDescriptor openFile; how to do it correctly?

    switch (sUriMatcher.match(uri))
    {
        case IMAGES_FOLDER_ID:
            //открытие папки с картинками если указано в URI images/
            break;
        case SCRIPTS_FOLDER_ID:
            //открытие папки со скриптами если указано в URI scripts/
            break;
        case STYLES_FOLDER_ID:
            //.....
            break;
        case TRIP_LIST_ID:
            //открытие нужного файла...
            break;
        case TRIP_ID:
            //открытие нужного файла...
            break;
        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
    }

In the main Java code, the following piece is added:

try
{
    for (String fileName : getAssets().list("Provider_html"))
    {
        File outputFile = new File(getFilesDir().getPath() + "/" + fileName);

        FileOutputStream out = new FileOutputStream(outputFile);
        InputStream in = getAssets().open( "Provider_html/" +fileName);

        copy(in,out);
        out.close();
        in.close();
    }
}
catch (Exception e)
{
    Log.d(LOG, "error with copying files", e);
}

Answer:

It is not very clear why there is such difficulty with the ContentProvider, if you can load pages from / assets in this way:

mWebView.loadUrl ("file: ///android_asset/Provider_html/TList2.htm");

And do the rest using HTML / JS …

Perhaps I did not understand the purpose of the author, tk. described rather chaotically.

Scroll to Top