How do I get files synchronized from Firebase in Android?

回眸只為那壹抹淺笑 提交于 2021-02-11 14:43:04

问题


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();
}

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
    }
});

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.

I am using this post to merge.


回答1:


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

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:

Starting downloading from storage

After starting download from storage

Download done

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());
        }
    });
}


来源:https://stackoverflow.com/questions/50681215/how-do-i-get-files-synchronized-from-firebase-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!