如何从 Android Document Provider c# Xamarin 中的 CreateDocument 获取创建的文件字节

How to get the created file bytes from CreateDocument in Android Document Provider c# Xamarin

我正在尝试在 Android Xamarin.

上创建自定义文档提供程序

我从这里得到了一个示例基本模板...

https://docs.microsoft.com/en-us/samples/xamarin/monodroid-samples/storageprovider/

这会使用 phone 的内部存储器创建一个虚拟提供程序,我想将其换出以使用云提供程序,然后 read/write 将数据存储到云存储。

我已经设法让它读取正常,但是当我尝试保存时,我无法弄清楚如何获取数据然后保存到云端。

当您在 phone 上按保存时,它会触发示例提供程序代码中的以下方法。

    public override string CreateDocument (string parentDocumentId, string mimeType, string displayName)
    {
        Log.Verbose(TAG, "createDocument");

        File parent = GetFileForDocId (parentDocumentId);
        var file = new File (parent, displayName);
        try {
            file.CreateNewFile ();
            file.SetWritable (true);
            file.SetReadable (true);
        } catch (IOException) {
            throw new FileNotFoundException ("Failed to create document with name " +
                displayName +" and documentId " + parentDocumentId);
        }
        return GetDocIdForFile (file);
    }

如果我跳过这个,它会转到外部代码,然后 returns 进入这个方法,我假设文件创建可能在这些步骤之间进行?

public override ICursor QueryDocument(string documentId, string[] projection)
{
    Log.Verbose(TAG, "queryDocument");

    // Create a cursor with the requested projection, or the default projection.
    var result = new MatrixCursor(ResolveDocumentProjection(projection));
    IncludeFile(result, documentId, null);
    return result;
}

我希望能够得到正在保存的文件的字节数组,这样我就可以调用API上传到云服务器。

这可能吗?有人 pointers/examples 知道如何做到这一点吗?我试过像这样获取字节..

var bytes = fullyReadFileToBytes(file);

使用下面的方法,但这总是returns 0字节。我假设此方法中的文件创建只是为文件创建占位符,而不是在此处实际创建它。有没有我可以覆盖的另一种方法,它在 CreateDocument 之后调用,也许我可以从哪里获取这个字节数组?

public byte[] fullyReadFileToBytes(File f)
{
    int size = (int)f.Length();
    byte[] bytes = new byte[size];
    byte[] tmpBuff = new byte[size];
    FileInputStream fis = new FileInputStream(f); ;
    try
    {

        int read = fis.Read(bytes, 0, size);
        if (read < size)
        {
            int remain = size - read;
            while (remain > 0)
            {
                read = fis.Read(tmpBuff, 0, remain);
                System.Array.Copy(tmpBuff, 0, bytes, size - remain, read);
                remain -= read;
            }
        }
    }
    catch (IOException e)
    {
        throw e;
    }
    finally
    {
        fis.Close();
    }

    return bytes;
}

如有任何帮助,我们将不胜感激。

提前致谢

我找到了答案文件只有在关闭它的句柄后才能正确写入。

因此,如果您尝试读取 OnClose 方法中的字节,这会带回所需的文件数据。

class MyOnCloseListener : Java.Lang.Object, ParcelFileDescriptor.IOnCloseListener
{
    string documentID;

    public MyOnCloseListener(string documentId)
    {
        documentID = documentId;
    }

    public void OnClose(Java.IO.IOException e)
    {
        // Update the file with the cloud server.  The client is done writing.
        var file = GetFileForDocId(documentID);
        var bytes = fullyReadFileToBytes(file);

        // do stuff here to save to cloud provider
    }
}