Sunday, 21 February 2021

new BlobStoreManager read write on Android 11

I previously used external storage to store specific data that I would like to share between my applications (without having any contentprovider "host")

That is why I am trying to use BlobStoreManager, as suggested in google's recommendation for targeting 30 (https://developer.android.com/training/data-storage/shared/datasets)

The read & write are based on a BlobHandle with 4 parameters, one being MessageDigest based on a "content". BlobHandle must use the same 4 parameters, or read will fail (SecurityException).

I managed to write data, and to read it, but it makes no sense: It seems that in order to write, I need to use the data I want to write to generate the BlobHandle.

Then, to read, as BlobHandle must use the same 4 parameters, I also need the data I wrote to be able to read. Totally illogic, as I wanted to read this data, I don't have it!

I must miss something or just do not understand how it work. If someone can help :)

Here are my sample:

If I set the following:

  • createBlobHandle: content = "mydata"
  • write: data = "mydata"
  • Then write will success, and read will success too. But it I can not know the value before reading it in a normal usecase :(

If I set the following (which would be logic, at least to me):

  • createBlobHandle: content = "somekey"
  • write: data = "mydata"
  • Then write will fail :(
@RequiresApi(api = Build.VERSION_CODES.R)
private BlobHandle createBlobHandle() {
    //Transfer object
    String content = "SomeContentToWrite";
    String label = "label123";
    String tag = "test";

    //Sha256 summary of the transmission object
    try {
        byte[] contentByte = content.getBytes("utf-8");

        MessageDigest md = MessageDigest.getInstance("sha256");
        byte[] contentHash = md.digest(contentByte);

        return BlobHandle.createWithSha256(contentHash, label,0, tag);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return null;
}

private void write() {
    String data = "SomeContentToWrite";
    @SuppressLint("WrongConstant") final BlobStoreManager blobStoreManager = ((BlobStoreManager) applicationContext.getSystemService(Context.BLOB_STORE_SERVICE));

    //Generate the session of this operation
    try {
        BlobHandle blobHandle = createBlobHandle();
        if (blobHandle == null)
            return;
        long sessionId = blobStoreManager.createSession(blobHandle);
        try (BlobStoreManager.Session session = blobStoreManager.openSession(sessionId)) {
            try (OutputStream pfd = new ParcelFileDescriptor.AutoCloseOutputStream(session.openWrite(0, data.getBytes().length))) {
                //The abstract of the written object must be consistent with the above, otherwise it will report SecurityException
                Log.d(TAG, "writeFile: >>>>>>>>>>text = " + data);
                pfd.write(data.getBytes());
                pfd.flush();

                //Allow public access
                session.allowPublicAccess();
                session.commit(applicationContext.getMainExecutor(), new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) {
                        //0 success 1 failure
                        Log.d(TAG, "accept: >>>>>>>>" + integer);
                    }
                });
            }
        }
    } catch (IOException e) {
            e.printStackTrace();
    }
}

private String read() {
    String data = "";
    @SuppressLint("WrongConstant") final BlobStoreManager blobStoreManager = ((BlobStoreManager) applicationContext.getSystemService(Context.BLOB_STORE_SERVICE));

    BlobHandle blobHandle = createBlobHandle();
    if (blobHandle != null) {
        try (InputStream pfd = new ParcelFileDescriptor.AutoCloseInputStream(blobStoreManager.openBlob(createBlobHandle()))) {
            //Read data
            byte[] buffer = new byte[pfd.available()];
            pfd.read(buffer);
            String text = new String(buffer, Charset.forName("UTF-8"));
            Log.d(TAG, "readFile: >>>>>>>>>>>>>>>>>>>>" + text);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }
    return data;
}


from new BlobStoreManager read write on Android 11

No comments:

Post a Comment