当前位置: 首页 > 知识库问答 >
问题:

如何避免总是从Google Drive加载缓存的应用程序数据

陈松
2023-03-14
    null
public static boolean saveToGoogleDrive(GoogleApiClient googleApiClient, File file, HandleStatusable h, PublishProgressable p) {
    // Should we new or replace?

    GoogleCloudFile googleCloudFile = searchFromGoogleDrive(googleApiClient, h, p);

    try {
        p.publishProgress(JStockApplication.instance().getString(R.string.uploading));

        final long checksum = org.yccheok.jstock.gui.Utils.getChecksum(file);
        final long date = new Date().getTime();
        final int version = org.yccheok.jstock.gui.Utils.getCloudFileVersionID();
        final String title = getGoogleDriveTitle(checksum, date, version);

        DriveContents driveContents;
        DriveFile driveFile = null;

        if (googleCloudFile == null) {
            DriveApi.DriveContentsResult driveContentsResult = Drive.DriveApi.newDriveContents(googleApiClient).await();

            if (driveContentsResult == null) {
                return false;
            }

            Status status = driveContentsResult.getStatus();
            if (!status.isSuccess()) {
                h.handleStatus(status);
                return false;
            }

            driveContents = driveContentsResult.getDriveContents();

        } else {
            driveFile = googleCloudFile.metadata.getDriveId().asDriveFile();
            DriveApi.DriveContentsResult driveContentsResult = driveFile.open(googleApiClient, DriveFile.MODE_WRITE_ONLY, null).await();

            if (driveContentsResult == null) {
                return false;
            }

            Status status = driveContentsResult.getStatus();
            if (!status.isSuccess()) {
                h.handleStatus(status);
                return false;
            }

            driveContents = driveContentsResult.getDriveContents();
        }

        OutputStream outputStream = driveContents.getOutputStream();
        InputStream inputStream = null;

        byte[] buf = new byte[8192];

        try {
            inputStream = new FileInputStream(file);
            int c;

            while ((c = inputStream.read(buf, 0, buf.length)) > 0) {
                outputStream.write(buf, 0, c);
            }

        } catch (IOException e) {
            Log.e(TAG, "", e);
            return false;
        } finally {
            org.yccheok.jstock.file.Utils.close(outputStream);
            org.yccheok.jstock.file.Utils.close(inputStream);
        }

        if (googleCloudFile == null) {
            // Create the metadata for the new file including title and MIME
            // type.
            MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
                    .setTitle(title)
                    .setMimeType("application/zip").build();

            DriveFolder driveFolder = Drive.DriveApi.getAppFolder(googleApiClient);
            DriveFolder.DriveFileResult driveFileResult = driveFolder.createFile(googleApiClient, metadataChangeSet, driveContents).await();

            if (driveFileResult == null) {
                return false;
            }

            Status status = driveFileResult.getStatus();
            if (!status.isSuccess()) {
                h.handleStatus(status);
                return false;
            }
        } else {
            MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
                    .setTitle(title).build();

            DriveResource.MetadataResult metadataResult = driveFile.updateMetadata(googleApiClient, metadataChangeSet).await();
            Status status = metadataResult.getStatus();
            if (!status.isSuccess()) {
                h.handleStatus(status);
                return false;
            }
        }

        Status status;
        try {
            status = driveContents.commit(googleApiClient, null).await();
        } catch (java.lang.IllegalStateException e) {
            // java.lang.IllegalStateException: DriveContents already closed.
            Log.e(TAG, "", e);
            return false;
        }

        if (!status.isSuccess()) {
            h.handleStatus(status);
            return false;
        }

        status = Drive.DriveApi.requestSync(googleApiClient).await();
        if (!status.isSuccess()) {
            // Sync request rate limit exceeded.
            //
            //h.handleStatus(status);
            //return false;
        }

        return true;
    } finally {
        if (googleCloudFile != null) {
            googleCloudFile.metadataBuffer.release();
        }
    }
}
private static String getGoogleDriveTitle(long checksum, long date, int version) {
    return "jstock-" + org.yccheok.jstock.gui.Utils.getJStockUUID() + "-checksum=" + checksum + "-date=" + date + "-version=" + version + ".zip";
}

// https://stackoverflow.com/questions/1360113/is-java-regex-thread-safe
private static final Pattern googleDocTitlePattern = Pattern.compile("jstock-" + org.yccheok.jstock.gui.Utils.getJStockUUID() + "-checksum=([0-9]+)-date=([0-9]+)-version=([0-9]+)\\.zip", Pattern.CASE_INSENSITIVE);

private static GoogleCloudFile searchFromGoogleDrive(GoogleApiClient googleApiClient, HandleStatusable h, PublishProgressable p) {
    DriveFolder driveFolder = Drive.DriveApi.getAppFolder(googleApiClient);

    // https://stackoverflow.com/questions/34705929/filters-ownedbyme-doesnt-work-in-drive-api-for-android-but-works-correctly-i
    final String titleName = ("jstock-" + org.yccheok.jstock.gui.Utils.getJStockUUID() + "-checksum=");
    Query query = new Query.Builder()
            .addFilter(Filters.and(
                Filters.contains(SearchableField.TITLE, titleName),
                Filters.eq(SearchableField.TRASHED, false)
            ))
            .build();

    DriveApi.MetadataBufferResult metadataBufferResult = driveFolder.queryChildren(googleApiClient, query).await();

    if (metadataBufferResult == null) {
        return null;
    }

    Status status = metadataBufferResult.getStatus();

    if (!status.isSuccess()) {
        h.handleStatus(status);
        return null;
    }

    MetadataBuffer metadataBuffer = null;
    boolean needToReleaseMetadataBuffer = true;

    try {
        metadataBuffer = metadataBufferResult.getMetadataBuffer();
        if (metadataBuffer != null ) {
            long checksum = 0;
            long date = 0;
            int version = 0;
            Metadata metadata = null;

            for (Metadata md : metadataBuffer) {
                if (p.isCancelled()) {
                    return null;
                }

                if (md == null || !md.isDataValid()) {
                    continue;
                }

                final String title = md.getTitle();

                // Retrieve checksum, date and version information from filename.
                final Matcher matcher = googleDocTitlePattern.matcher(title);
                String _checksum = null;
                String _date = null;
                String _version = null;
                if (matcher.find()){
                    if (matcher.groupCount() == 3) {
                        _checksum = matcher.group(1);
                        _date = matcher.group(2);
                        _version = matcher.group(3);
                    }
                }
                if (_checksum == null || _date == null || _version == null) {
                    continue;
                }

                try {
                    checksum = Long.parseLong(_checksum);
                    date = Long.parseLong(_date);
                    version = Integer.parseInt(_version);
                } catch (NumberFormatException ex) {
                    Log.e(TAG, "", ex);
                    continue;
                }

                metadata = md;

                break;

            }   // for

            if (metadata != null) {
                // Caller will be responsible to release the resource. If release too early,
                // metadata will not readable.
                needToReleaseMetadataBuffer = false;
                return GoogleCloudFile.newInstance(metadataBuffer, metadata, checksum, date, version);
            }
        }   // if
    } finally {
        if (needToReleaseMetadataBuffer) {
            if (metadataBuffer != null) {
                metadataBuffer.release();
            }
        }
    }

    return null;
}
    null
public static CloudFile loadFromGoogleDrive(GoogleApiClient googleApiClient, HandleStatusable h, PublishProgressable p) {
    final java.io.File directory = JStockApplication.instance().getExternalCacheDir();
    if (directory == null) {
        org.yccheok.jstock.gui.Utils.showLongToast(R.string.unable_to_access_external_storage);
        return null;
    }

    Status status = Drive.DriveApi.requestSync(googleApiClient).await();
    if (!status.isSuccess()) {
        // Sync request rate limit exceeded.
        //
        //h.handleStatus(status);
        //return null;
    }

    GoogleCloudFile googleCloudFile = searchFromGoogleDrive(googleApiClient, h, p);

    if (googleCloudFile == null) {
        return null;
    }

    try {
        DriveFile driveFile = googleCloudFile.metadata.getDriveId().asDriveFile();
        DriveApi.DriveContentsResult driveContentsResult = driveFile.open(googleApiClient, DriveFile.MODE_READ_ONLY, null).await();

        if (driveContentsResult == null) {
            return null;
        }

        status = driveContentsResult.getStatus();
        if (!status.isSuccess()) {
            h.handleStatus(status);
            return null;
        }

        final long checksum = googleCloudFile.checksum;
        final long date = googleCloudFile.date;
        final int version = googleCloudFile.version;

        p.publishProgress(JStockApplication.instance().getString(R.string.downloading));

        final DriveContents driveContents = driveContentsResult.getDriveContents();

        InputStream inputStream = null;
        java.io.File outputFile = null;
        OutputStream outputStream = null;

        try {
            inputStream = driveContents.getInputStream();
            outputFile = java.io.File.createTempFile(org.yccheok.jstock.gui.Utils.getJStockUUID(), ".zip", directory);
            outputFile.deleteOnExit();
            outputStream = new FileOutputStream(outputFile);

            int read = 0;
            byte[] bytes = new byte[1024];

            while ((read = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read);
            }
        } catch (IOException ex) {
            Log.e(TAG, "", ex);
        } finally {
            org.yccheok.jstock.file.Utils.close(outputStream);
            org.yccheok.jstock.file.Utils.close(inputStream);
            driveContents.discard(googleApiClient);
        }

        if (outputFile == null) {
            return null;
        }

        return CloudFile.newInstance(outputFile, checksum, date, version);
    } finally {
        googleCloudFile.metadataBuffer.release();
    }
}
Status status = Drive.DriveApi.requestSync(googleApiClient).await()
    null

    null

我为测试目的编写了一个APK-https://github.com/yccheok/google-drive-bug/releases/download/1.0/demo.APK

共有1个答案

易琛
2023-03-14
    null
 类似资料:
  • 我正在使用Guava缓存热数据。当缓存中不存在数据时,我必须从数据库中获取数据: 我的问题是当数据不存在于数据库中时,我希望它返回并且不做任何缓存。但Guava保存与缓存中的关键字,并抛出一个异常,当我得到它: com.google.common.cache.CacheLoader$InvalidCacheLoadExcION: CacheLoader为shisoft键返回null。 我们如何避免

  • 当您单击应用程序中的一个按钮时,浮动应用程序小部件就会打开。 我写了一个函数,当点击Widget时应该打开应用程序屏幕。(代码如下) 我在下面列出了两种方法 问题: 点击后,应用程序打开需要几秒钟的时间。 我想在点击后打开内存栏中的应用程序

  • 我的web项目一旦有前端页面的更新就需要清理浏览器缓存后才能看到最新效果,有时不清理不但不能看到最新效果还会出现页面布局错乱,如何能避免这种情况,我想要更新前端页面,用户也不需要清理浏览器缓存,页面关闭重新打开就能显示最新效果

  • 问题内容: 这个问题已经在这里有了答案 : 如何使用pip从本地缓存安装? (10个答案) 7年前关闭。 如何防止PIP重新下载以前下载的软件包?我正在测试matplotlib的安装,这是一个11MB的软件包,它依赖于多个发行版特定的软件包。每次运行时,它都会重新下载matplotlib。如何停止呢? 问题答案: 您可以使用特定的环境变量 PIP_DOWNLOAD_CACHE 并使其指向要存储软件

  • 我试图开发一个android应用程序,可以擦除其他应用程序的缓存数据,我试图浏览所有的博客,但没有一个对我有效,我可以通过以下代码清除我的应用程序的缓存 我想清除其他应用程序的缓存,可以任何机构请帮助我,如果我错了请纠正我,提前谢谢。