从Android访问云存储



我一直找不到有关如何使用Android应用程序使用云存储的任何具体文档。

我确实从Google Cloud SDK遇到了这个客户库库,但是遇到了许多问题,并且尚未使其正常工作。

我按照上述链接中的建议添加了以下代码:

build.gradle

compile group: 'com.google.cloud', name: 'google-cloud-storage', version: '0.9.3-beta'

我添加了一些简单的代码,尽管这与这个问题并不相关,因为我还可以使用上述依赖项运行我的应用程序:

在活动中:

Storage storage = StorageOptions.getDefaultInstance().getService();
Page<Bucket> buckets = storage.list();
Iterator<Bucket> bucketIterator = buckets.iterateAll();
while (bucketIterator.hasNext()) {
    Bucket bucket = bucketIterator.next();
    Log.d(TAG, "Bucket name: " + bucket.getName());
}

解决了无数的依赖性问题(与Gradle的Netty,DuplicateFileException的冲突等),我能够构建该项目,尽管有以下错误:

Warning:WARNING: Dependency org.apache.httpcomponents:httpclient:4.0.1 is ignored for debug as it may be conflicting with the internal version provided by Android. Warning:WARNING: Dependency org.json:json:20151123 is ignored for debug as it may be conflicting with the internal version provided by Android.

我可以尝试运行,这将因几百个错误而失败,其中大多数看起来像以下内容:

Error:warning: Ignoring InnerClasses attribute for an anonymous inner class
Error:(com.google.inject.internal.cglib.reflect.$FastClassEmitter$3) that doesn't come with an
Error:associated EnclosingMethod attribute. This class was probably produced by a
Error:compiler that did not target the modern .class file format. The recommended
Error:solution is to recompile the class from source, using an up-to-date compiler
Error:and without specifying any "-target" type options. The consequence of ignoring
Error:this warning is that reflective operations on this class will incorrectly
Error:indicate that it is *not* an inner class.

经过相当多的classNames之后,错误的结尾包含以下内容:

麻烦处理" Javax/transaction/HeuristicCommitexception.class":

不明智或错误使用核心类(Java。*或Javax。*) 不建立核心库。

这通常是由于无意中的包含一个核心库文件 使用IDE(例如Eclipse)时,您的应用程序的项目。如果 您确定自己不是故意定义核心类,然后 是最有可能解释发生的事情。

但是,您实际上可能正在尝试在核心中定义类 名称空间,例如,您可能从一个 非Android虚拟机项目。肯定不会 工作。至少,它危害您的应用程序的兼容性 平台的未来版本。这也经常有疑问 合法性。

如果您真的打算构建一个核心库 - 只是 作为创建完整虚拟机分配的一部分,适当 而不是编译应用程序 - 然后使用 抑制此错误消息的" - 核心图"选项。

如果您继续使用" - 核心图书馆",但实际上正在建造一个 申请,请注意您的申请仍然会失败 在某个时候建造或运行。请为生气的客户做好准备 例如,谁发现您的应用程序停止运行一次 他们升级了操作系统。你会为此而怪 问题。

如果您正合法地使用某些恰好位于核心的代码 包装,那么您最简单的替代方案是重新包装 该代码。也就是说,将有关的课程移至您自己的软件包中 名称空间。这意味着他们永远不会与核心冲突 系统类。Jarjar是一种可以帮助您进行这项工作的工具。 如果您发现自己不能这样做,那表明 您所处的道路最终会导致痛苦,痛苦,悲伤, 和哀叹。

一些问题:

  1. 这个客户端库是从我的Android应用程序访问我的Google Cloud存储的正确方法吗?
  2. 有原因我不应该尝试从移动应用程序访问云存储吗?例如,更好的体系结构是将REST API调用到我的App Engine应用程序(使用Cloud Enpoints)并传递IT媒体对象,然后将App Engine App访问并将媒体存储在云存储中,然后最终返回结果到移动应用?
  3. 如果我使用上述客户端库正确访问云存储,这些错误是什么意思,修复了什么?

您不应该从无法通过安全令牌信任的客户端应用程序中直接写入云存储。听起来您不是在计划直接作为用户进行身份验证,而是在您自己的项目中通常。

如果您不打算进行基于用户的OAuth2 Flow(用户必须拥有已启用存储的云控制台项目),那么您正在考虑通过自己的后端(例如App Engine)来代理请求。

这种方法可以将存储凭据保留在服务器端,而不是在客户端应用程序的APK中存储,该凭据可能会被拆除,提取,然后恶意的参与者可以使用这些凭据以任何方式将其写入您的存储桶。哦,存储桶和存储是一种可计费的资源,因此公开这些凭据可能会花费您。

这是您要通过自己的后端或API路由请求的许多云服务的常见模式。

我猜想,但是我想 firebase存储API是您应该这样做的方式:https://firebase.google.com/docs/storage/

这可能是一个较晚的答案。但是我认为,这对某人很有用。

首先,您应该通过在GCP控制台中注册您的应用程序来获取以下信息。

private final String pkcsFile = "xxx.json";//private key file
private final String bucketName = "your_gcp_bucket_name";
private final String projectId = "your_gcp_project_id";

获得凭据后,您应该将私钥(.p12或.json)放在资产文件夹中。我正在使用JSON格式私有密钥文件。另外,您应该更新图像位置以上传。

@RequiresApi(api = Build.VERSION_CODES.O)
    public void uploadImageFile(String srcFileName, String newName) {
            Storage storage = getStorage();
        File file = new File(srcFileName);//Your image loaction
        byte[] fileContent;
        try {
            fileContent = Files.readAllBytes(file.toPath());
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }
        if (fileContent == null || fileContent.length == 0)
            return;
        BlobInfo.Builder newBuilder = Blob.newBuilder(BucketInfo.of(bucketName), newName);
        BlobInfo blobInfo = newBuilder.setContentType("image/png").build();
        Blob blob = storage.create(blobInfo, fileContent);
        String bucket = blob.getBucket();
        String contentType = blob.getContentType();
        Log.e("TAG", "Upload File: " + contentType);
        Log.e("File ", srcFileName + " uploaded to bucket " + bucket + " as " + newName);
    }
private Storage getStorage() {
        InputStream credentialsStream;
        Credentials credentials;
        try {
            credentialsStream = mContext.getAssets().open(pkcsFile);
            credentials = GoogleCredentials.fromStream(credentialsStream);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return StorageOptions.newBuilder()
                .setProjectId(projectId).setCredentials(credentials)
                .build().getService();
    }

最新更新