Search code examples
androidcallbackdropbox

onFileChange(DbxFile file) called multiple times(exaclty 8 times) when a file change


I am using Drop-Box sync API for Android platform, where following scenario is occuring:

  1. UserA has opened some file( say A.xls).
  2. While userA's file is still open, userB made some changes on same file and pushed the file on Dropbox.
  3. Now userA gets callback on onFileChange(DbxFile file). This method is called exactly 8 time every time for every update.

I need to confirm is multiple callbacks for an update is a feature of SyncAPI.

If it is a feature, is there any way i can disable it to get exactly 1 callback per update.

If it is not a feature, can you suggest any possibility why this is happening.

From my side, i checked that listener is registered only once and class which implements Listener is singleton.

I hope following code and log may provide you some more information.

@Override
    public void onFileChange(DbxFile oldFile) {
        try {
            Log.d(tag, "onFileChange count = " + count);

            if (count % 8 == 0) {
                Date oldFileDate = oldFile.getInfo().modifiedTime;
                Log.d(tag, "current file modification time = " + oldFileDate + "\t file status = " + getStatus(oldFile));
                DbxPath mpath = oldFile.getPath();
                Log.d(tag, "Kicking thread");
                Runnable newFileStatusCheckRunnable = new CheckNewFileUpdateTask(context.getDbxFs(), mpath, oldFile);
                Thread newFileStatusCheckThread = new Thread(newFileStatusCheckRunnable);
                newFileStatusCheckThread.start();
            }
            Log.d(tag, "Incrmenting counter");
            count++;

        } catch (DbxException e) {

            e.printStackTrace();
        }
    }

Logs ( only relevant part of logs are added )

01-11 18:22:12.515: D/FileChangeListener(6127): onFileChange count = 0
01-11 18:22:12.515: D/FileChangeListener(6127): current file modification time = Sat Jan 11 17:43:17 GMT+05:30 2014  file status = isLatestDOWNLOAD
01-11 18:22:12.515: D/FileChangeListener(6127): Kicking thread
01-11 18:22:12.525: D/FileChangeListener(6127): Incrmenting counter
01-11 18:22:12.525: D/FileChangeListener(6127): trying first time
01-11 18:22:12.525: D/FileChangeListener(6127): checking, if downloding then wait
01-11 18:22:14.908: D/FileChangeListener(6127): onFileChange count = 1
01-11 18:22:14.908: D/FileChangeListener(6127): Incrmenting counter
01-11 18:22:14.908: D/FileChangeListener(6127): onFileChange count = 2
01-11 18:22:14.908: D/FileChangeListener(6127): Incrmenting counter
01-11 18:22:15.308: D/FileChangeListener(6127): onFileChange count = 3
01-11 18:22:15.308: D/FileChangeListener(6127): Incrmenting counter
01-11 18:22:15.308: D/FileChangeListener(6127): onFileChange count = 4
01-11 18:22:15.308: D/FileChangeListener(6127): Incrmenting counter
01-11 18:22:15.688: D/FileChangeListener(6127): onFileChange count = 5
01-11 18:22:15.688: D/FileChangeListener(6127): Incrmenting counter
01-11 18:22:15.688: D/FileChangeListener(6127): onFileChange count = 6
01-11 18:22:15.688: D/FileChangeListener(6127): Incrmenting counter
01-11 18:22:15.719: D/FileChangeListener(6127): onFileChange count = 7
01-11 18:22:15.719: D/FileChangeListener(6127): Incrmenting counter
01-11 18:22:15.719: D/FileChangeListener(6127): wait over
01-11 18:22:15.719: E/libDropboxSync.so(ERR)(6127): DROPBOX_ERROR_ALREADYOPEN: file.cpp:246: p(/p3.xls) already open (0)
01-11 18:22:15.729: D/FileChangeListener(6127): closing file
01-11 18:22:15.729: D/FileChangeListener(6127): Re-trying to open
01-11 18:22:15.759: D/FileChangeListener(6127): New file time: Sat Jan 11 18:23:08 GMT+05:30 2014
01-11 18:22:15.759: D/gaurav(6127): UtilityBillAppActivity onNotice

Solution

  • I need to check whether the file has been downloaded and is cached in the system, before caching completes, i need to ignore all the callbacks.

    @Override
    public void onFileChange(DbxFile oldFile) {
        Log.d(tag, "onFileChange");
    
        try {
            if (false == oldFile.getSyncStatus().isLatest) {
                if (oldFile.getNewerStatus().isCached) {
                    Log.d(tag, "file downloaded, and is ready to use, status=" + getStatus(oldFile));
                    boolean isFileUpdated = oldFile.update();
                    if (isFileUpdated) {
                        Log.d(tag, "New file updated successfully");
                        DbXFileHolder.getInstance().setDropBoxFile(oldFile);
                        context.setFilePath(oldFile.getPath());
                        Intent foundNewFileIntent = new Intent(CommonUtil.ACTION);
                        LocalBroadcastManager.getInstance(context).sendBroadcast(foundNewFileIntent);
                    }else{
                        Log.d(tag, "New file could not update successfully");
                    }
                } else {
                    Log.d(tag, "file downloading, byte transferred = " + oldFile.getNewerStatus().bytesTransferred + "\tstatus = " + getStatus(oldFile));
                }
            } else {
                Log.d(tag, "Sync status is latest. status = " + getSyncStatus(oldFile));
            }
    
        } catch (DbxException e) {
            for (StackTraceElement ste : e.getStackTrace()) {
                Log.d(tag, ste.toString());
            }
        }
    
    }
    
    
    private String getStatus(DbxFile newFile) {
        StringBuilder statusBuilder = new StringBuilder();
        try {
            DbxFileStatus fStatus = newFile.getNewerStatus();
            if (fStatus.isCached) {
                statusBuilder.append("isCached");
            }
            if (fStatus.isLatest) {
                statusBuilder.append("isLatest");
            }
            if (fStatus.failure != null) {
                statusBuilder.append("failure");
    
            }
            if (PendingOperation.DOWNLOAD.equals(fStatus.pending)) {
                statusBuilder.append("DOWNLOAD");
    
            }
            if (PendingOperation.UPLOAD.equals(fStatus.pending)) {
                statusBuilder.append("UPLOAD");
    
            }
            if (PendingOperation.NONE.equals(fStatus.pending)) {
                statusBuilder.append("NONE");
            }
        } catch (DbxException e) {
            statusBuilder.append("Exception: " + e.getMessage());
        }
        return statusBuilder.toString();
    }
    
    private String getSyncStatus(DbxFile newFile) {
        StringBuilder statusBuilder = new StringBuilder();
        try {
            DbxFileStatus fStatus = newFile.getSyncStatus();
            if (fStatus.isCached) {
                statusBuilder.append("isCached");
            }
            if (fStatus.isLatest) {
                statusBuilder.append("isLatest");
            }
            if (fStatus.failure != null) {
                statusBuilder.append("failure");
    
            }
            if (PendingOperation.DOWNLOAD.equals(fStatus.pending)) {
                statusBuilder.append("DOWNLOAD");
    
            }
            if (PendingOperation.UPLOAD.equals(fStatus.pending)) {
                statusBuilder.append("UPLOAD");
    
            }
            if (PendingOperation.NONE.equals(fStatus.pending)) {
                statusBuilder.append("NONE");
            }
        } catch (DbxException e) {
            statusBuilder.append("Exception: " + e.getMessage());
        }
        return statusBuilder.toString();
    }