如何在Android中从Firebase同步文件? [英] How do I get files synchronized from Firebase in Android?

查看:36
本文介绍了如何在Android中从Firebase同步文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个可以处理音频文件的应用程序.我必须在应用程序的一部分中从Firebase导入和合并音频文件.

I am trying to make an application that works with audio files. I have to import and merge audio files from Firebase in a part of the application.

这是合并操作中的代码块;

Here is the code block from merge operations;

protected void combine() {
    String randomFileName = String.valueOf(System.currentTimeMillis());
    lastRecordedFilePath = Environment.getExternalStorageDirectory() + "/MueasycoCombinedAudios/" + randomFileName + ".wav";
    lastRecordedFileName = randomFileName + ".wav";

    File folder = new File(Environment.getExternalStorageDirectory() + "/MueasycoCombinedAudios");
    File folder1 = new File(Environment.getExternalStorageDirectory() + "/MueasycoDownloadedAudios");


    if (!folder.exists()) {
        folder.mkdirs();
    }

    if (!folder1.exists()) {
        folder1.mkdirs();
    }

    int counter = 0;
    int counter1 = 0;
    int counter2 = 0;

    try {
        DataOutputStream amplifyOutputStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(Environment.getExternalStorageDirectory() + "/MueasycoCombinedAudios/" + randomFileName + ".wav")));
        DataInputStream[] mergeFilesStream = new DataInputStream[trackList.size()];

        long[] sizes = new long[trackList.size()];

        for (Iterator<TrackModel> i = trackList.iterator(); i.hasNext(); ) {

            TrackModel item = i.next();
            final StorageReference fileReference = mStorageRef.child("AudioRecords/" + item.fileName);

            final File file = new File(Environment.getExternalStorageDirectory() + "/MueasycoDownloadedAudios/" + item.fileName);

            fileReference.getFile(file).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
                @Override
                public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
                    Log.e("firebase ", ";local tem file created  created " + file.toString());
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception exception) {
                    // Handle any errors
                }
            });
            sizes[counter] = (file.length() - 44) / 2;
            counter++;
        }


        for (Iterator<TrackModel> i = trackList.iterator(); i.hasNext(); ) {

            TrackModel item = i.next();


            while (true) {
                File control = new File(Environment.getExternalStorageDirectory() + "/MueasycoDownloadedAudios/" + item.fileName);
                if (control.exists()) {
                    mergeFilesStream[counter1] = new DataInputStream(new BufferedInputStream(new FileInputStream(Environment.getExternalStorageDirectory() + "/MueasycoDownloadedAudios/" + item.fileName)));
                    break;
                } else {
                    Log.e("mueasyco ", "Dosya yok" + control.getName());
                }
            }

            if (counter1 == trackList.size() - 1) {
                mergeFilesStream[counter1].skip(24);
                byte[] sampleRt = new byte[4];
                mergeFilesStream[counter1].read(sampleRt);
                ByteBuffer bbInt = ByteBuffer.wrap(sampleRt).order(ByteOrder.LITTLE_ENDIAN);
                RECORDER_SAMPLERATE = bbInt.getInt();
                mergeFilesStream[counter1].skip(16);
            } else {
                mergeFilesStream[counter1].skip(44);
            }

            counter1++;
        }

        for (Iterator<TrackModel> i = trackList.iterator(); i.hasNext(); ) {
            TrackModel item = i.next();
            final StorageReference fileReference = mStorageRef.child("AudioRecords/" + item.fileName);

            for (int a = 0; a < (int) sizes[counter2]; counter2++) {
                byte[] dataBytes = new byte[2];
                try {
                    dataBytes[0] = mergeFilesStream[counter2].readByte();
                    dataBytes[1] = mergeFilesStream[counter2].readByte();
                } catch (EOFException e) {
                    amplifyOutputStream.close();
                }

                short dataInShort = ByteBuffer.wrap(dataBytes).order(ByteOrder.LITTLE_ENDIAN).getShort();
                float dataInFloat = (float) dataInShort / 37268.0f;

                short outputSample = (short) (dataInFloat * 37268.0f);
                byte[] dataFin = new byte[2];

                dataFin[0] = (byte) (outputSample & 0xff);
                dataFin[1] = (byte) ((outputSample >> 8) & 0xff);

                amplifyOutputStream.write(dataFin, 0, 2);
            }

            counter2++;
        }

        amplifyOutputStream.close();

        for (int a = 0; a < trackList.size(); a++) {
            mergeFilesStream[a].close();
        }

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    long size = 0;

    try {
        FileInputStream fileSize = new FileInputStream(Environment.getExternalStorageDirectory() + "/MueasycoCombinedAudios/" + randomFileName + ".wav");
        size = fileSize.getChannel().size();
        fileSize.close();
    } catch (FileNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    final int RECORDER_BPP = 16;

    long datasize = size + 36;
    long byteRate = (RECORDER_BPP * RECORDER_SAMPLERATE) / 8;
    long longSampleRate = RECORDER_SAMPLERATE;
    byte[] header = new byte[44];


    header[0] = 'R';  // RIFF/WAVE header
    header[1] = 'I';
    header[2] = 'F';
    header[3] = 'F';
    header[4] = (byte) (datasize & 0xff);
    header[5] = (byte) ((datasize >> 8) & 0xff);
    header[6] = (byte) ((datasize >> 16) & 0xff);
    header[7] = (byte) ((datasize >> 24) & 0xff);
    header[8] = 'W';
    header[9] = 'A';
    header[10] = 'V';
    header[11] = 'E';
    header[12] = 'f';  // 'fmt ' chunk
    header[13] = 'm';
    header[14] = 't';
    header[15] = ' ';
    header[16] = 16;  // 4 bytes: size of 'fmt ' chunk
    header[17] = 0;
    header[18] = 0;
    header[19] = 0;
    header[20] = 1;  // format = 1
    header[21] = 0;
    header[22] = (byte) 1;
    header[23] = 0;
    header[24] = (byte) (longSampleRate & 0xff);
    header[25] = (byte) ((longSampleRate >> 8) & 0xff);
    header[26] = (byte) ((longSampleRate >> 16) & 0xff);
    header[27] = (byte) ((longSampleRate >> 24) & 0xff);
    header[28] = (byte) (byteRate & 0xff);
    header[29] = (byte) ((byteRate >> 8) & 0xff);
    header[30] = (byte) ((byteRate >> 16) & 0xff);
    header[31] = (byte) ((byteRate >> 24) & 0xff);
    header[32] = (byte) ((RECORDER_BPP) / 8);  // block align
    header[33] = 0;
    header[34] = RECORDER_BPP;  // bits per sample
    header[35] = 0;
    header[36] = 'd';
    header[37] = 'a';
    header[38] = 't';
    header[39] = 'a';
    header[40] = (byte) (size & 0xff);
    header[41] = (byte) ((size >> 8) & 0xff);
    header[42] = (byte) ((size >> 16) & 0xff);
    header[43] = (byte) ((size >> 24) & 0xff);

    try {
        RandomAccessFile rFile = new RandomAccessFile(Environment.getExternalStorageDirectory() + "/MueasycoCombinedAudios/" + randomFileName + ".wav", "rw");
        rFile.seek(0);
        rFile.write(header);
        rFile.close();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    uploadFile();
}

问题在于,下载firebase文件的代码继续起作用.如您所见,我尝试使用无限循环修复此问题,但是Firebase在未正确加载时会创建文件,因此解决方案未成功.

The problem is that the code that downloads firebase files continues to work. As you can see, I tried to repair this with an infinite loop, but the Firebase creates files when it did not load properly, so the solution was not successful.

fileReference.getFile(file).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
    @Override
    public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
        Log.e("firebase ", ";local tem file created  created " + file.toString());
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        // Handle any errors
    }
});

我试图编写为加入onSuccess事件而创建的数组,但是在这种情况下,我将无法完全准备好要使用的数组.

I tried to write the array I created for joining in the onSuccess event but in this case I will not be able to fully prepare the arrays to use.

我正在使用这篇文章进行合并./p>

I am using this post to merge.

推荐答案

您的代码中发生了很多事情,因此,我仅关注其中一部分.

There's a bit much going on in your code, so I'm going to focus on one part of it only.

该问题是由Firebase异步从服务器下载文件引起的.在下载文件时,它不会阻止代码,而是继续运行您的代码.因此,如果您不考虑这种异步行为,则会在实际下载文件数据之前合并文件.

The problem is caused by the fact that Firebase downloads the files from the server asynchronously. And while the file is downloading, instead of blocking your code, it continues to run your code. So if you don't take this asynchronous behavior into account, you'll be merging the files before their data has actually been downloaded.

查看正在发生的事情的最简单方法是使用一些日志语句:

The easiest way to see what's happening is with a few log statements:

Log.i("Firebase", "Starting downloading from storage");
fileReference.getFile(file).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
    @Override
    public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
        Log.i("Firebase", "Download done");
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception exception) {
        Log.e("Firebase", "Download failed: "+exception.toString());
    }
});
Log.i("Firebase", "After starting download from storage");

如果运行此代码,您将得到:

If you run this code you'll get:

开始从存储下载

开始从存储下载

下载完成

这可能不是您所期望的,但是可以完美地解释您的合并代码失败的原因:要合并的数据尚不可用.

This is probably not what you expected, but perfectly explains why your merging code fails: the data that it wants to merge is not available yet.

解决方案是更改调用代码的顺序.文件下载完成后,检查该文件是否为最终文件.如果是这样,请开始合并:

The solution is to change the order in which you invoke the code. After the download of a file is completed, check if that was the final file. If so, start the merge:

for (Iterator<TrackModel> i = trackList.iterator(); i.hasNext(); ) {
    TrackModel item = i.next();
    final StorageReference fileReference = mStorageRef.child("AudioRecords/" + item.fileName);

    final File file = new File(Environment.getExternalStorageDirectory() + "/MueasycoDownloadedAudios/" + item.fileName);

    fileReference.getFile(file).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
            sizes[counter] = (file.length() - 44) / 2;
            counter++;
            if (counter == trackList.size()) {
                Log.i("Firebase", "Downloads completed");
                // TODO: merge the downloaded files here
            }
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            Log.e("Firebase", "Download failed: "+exception.toString());
        }
    });
}

这篇关于如何在Android中从Firebase同步文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆