如何将google应用程序凭据指向我的json文件?

i34xakig  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(315)

我想在我的android应用程序中使用googletext-to-speech。
根据文件,我已经完成了所有这些步骤:
在云控制台中,转到创建服务帐户密钥页面。
从“服务帐户”列表中,选择“新建服务帐户”。
在服务帐户名称字段中,输入名称。
从“角色”列表中,选择“项目”>“所有者”。
单击“创建”。一个json文件,包含您的密钥下载到您的计算机。
我正在使用google的代码传递凭证,这是我下载的json文件:

public void main(String... args) throws Exception {
    // You can specify a credential file by providing a path to GoogleCredentials.
    // Otherwise credentials are read from the GOOGLE_APPLICATION_CREDENTIALS environment variable.
    InputStream stream = getResources().openRawResource(R.raw.credential); // R.raw.credential is credential.json
    GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(String.valueOf(stream)))
            .createScoped(Lists.newArrayList(Collections.singleton("https://www.googleapis.com/auth/cloud-platform")));
    Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

    System.out.println("Buckets:");
    Page<Bucket> buckets = storage.list();
    for (Bucket bucket : buckets.iterateAll()) {
        System.out.println(bucket.toString());
    }
}

不管怎样,我已经清理了gradle,重新启动了android studio,但我仍然得到以下日志:
java.io.ioexception:应用程序默认凭据不可用。如果在google计算引擎中运行,它们是可用的。否则,必须定义指向定义凭据的文件的环境变量google\u application\u credentials。看到了吗https://developers.google.com/accounts/docs/application-default-credentials 更多信息。
我做错什么了?

更新

我意识到只有当我点击一个按钮时才会收到这个日志消息。如果我点击一个按钮,方法 hello() 会跑的。查看完整代码:

package ch.yourclick.kitt;

import android.os.Build;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.tabs.TabLayout;
import com.google.api.client.util.Lists;
import com.google.api.gax.core.FixedCredentialsProvider;
import com.google.api.gax.paging.Page;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.cloud.texttospeech.v1.AudioConfig;
import com.google.cloud.texttospeech.v1.AudioEncoding;
import com.google.cloud.texttospeech.v1.SsmlVoiceGender;
import com.google.cloud.texttospeech.v1.SynthesisInput;
import com.google.cloud.texttospeech.v1.SynthesizeSpeechResponse;
import com.google.cloud.texttospeech.v1.TextToSpeechClient;
import com.google.cloud.texttospeech.v1.TextToSpeechSettings;
import com.google.cloud.texttospeech.v1.VoiceSelectionParams;
import com.google.protobuf.ByteString;
import androidx.annotation.RequiresApi;
import androidx.viewpager.widget.ViewPager;
import androidx.appcompat.app.AppCompatActivity;
import android.os.StrictMode;
import android.view.View;

import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.BucketInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collections;

import ch.yourclick.kitt.ui.main.SectionsPagerAdapter;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
        ViewPager viewPager = findViewById(R.id.view_pager);
        viewPager.setAdapter(sectionsPagerAdapter);
        TabLayout tabs = findViewById(R.id.tabs);
        tabs.setupWithViewPager(viewPager);
        FloatingActionButton fab = findViewById(R.id.fab);

        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    public void main(String... args) throws Exception {
        // You can specify a credential file by providing a path to GoogleCredentials.
        // Otherwise credentials are read from the GOOGLE_APPLICATION_CREDENTIALS environment variable.
        InputStream stream = getResources().openRawResource(R.raw.credential); // R.raw.credential is credential.json
        GoogleCredentials credentials = GoogleCredentials.fromStream(stream)
                .createScoped(Lists.newArrayList(Collections.singleton("https://www.googleapis.com/auth/cloud-platform")));
        Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

        System.out.println("Buckets:");
        Page<Bucket> buckets = storage.list();
        for (Bucket bucket : buckets.iterateAll()) {
            System.out.println(bucket.toString());
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public void onClick(View view) {
        int SDK_INT = android.os.Build.VERSION.SDK_INT;
        if (SDK_INT > 8)
        {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
                    .permitAll().build();
            StrictMode.setThreadPolicy(policy);

            try {
                hello();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    /**Demonstrates using the Text-to-Speech API. */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public void hello() throws Exception {
        InputStream stream = getResources().openRawResource(R.raw.credential); // R.raw.credential is credential.json
        GoogleCredentials credentials = GoogleCredentials.fromStream(stream);
        TextToSpeechSettings textToSpeechSettings =
                TextToSpeechSettings.newBuilder()
                        .setCredentialsProvider(
                                FixedCredentialsProvider.create(credentials)
                        ).build()
                ;

        // Instantiates a client
        try (TextToSpeechClient textToSpeechClient = TextToSpeechClient.create(textToSpeechSettings)) {
            // Set the text input to be synthesized
            SynthesisInput input = SynthesisInput.newBuilder().setText("Hello, World!").build();

            // Build the voice request, select the language code ("en-US") and the ssml voice gender
            // ("neutral")
            VoiceSelectionParams voice =
                    VoiceSelectionParams.newBuilder()
                            .setLanguageCode("en-US")
                            .setSsmlGender(SsmlVoiceGender.NEUTRAL)
                            .build();

            // Select the type of audio file you want returned
            AudioConfig audioConfig =
                    AudioConfig.newBuilder().setAudioEncoding(AudioEncoding.MP3).build();

            // Perform the text-to-speech request on the text input with the selected voice parameters and
            // audio file type
            SynthesizeSpeechResponse response =
                    textToSpeechClient.synthesizeSpeech(input, voice, audioConfig);

            // Get the audio contents from the response
            ByteString audioContents = response.getAudioContent();

            // Write the response to the output file.
            try (OutputStream out = new FileOutputStream("output.mp3")) {
                out.write(audioContents.toByteArray());
                System.out.println("Audio content written to file \"output.mp3\"");
            }
        }
    }

}

依赖项

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation group: 'io.grpc', name: 'grpc-okhttp', version: '1.0.1'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.2.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    implementation 'com.google.cloud:google-cloud-storage:1.113.3'
    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'com.google.cloud:libraries-bom:4.3.0'
    implementation 'com.google.cloud:google-cloud-texttospeech:1.2.1'
    implementation 'com.google.android.gms:play-services:12.0.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
qfe3c7zg

qfe3c7zg1#

可能是 GoogleCredentials 类找不到有效的凭据json文件,因为它是以何种方式提供给它的。
请,而不是:

InputStream stream = getResources().openRawResource(R.raw.credential); // R.raw.credential is credential.json
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(String.valueOf(stream)))
            .createScoped(Lists.newArrayList(Collections.singleton("https://www.googleapis.com/auth/cloud-platform")));

尝试:

InputStream stream = getResources().openRawResource(R.raw.credential); // R.raw.credential is credential.json
GoogleCredentials credentials = GoogleCredentials.fromStream(stream)
            .createScoped(Lists.newArrayList(Collections.singleton("https://www.googleapis.com/auth/cloud-platform")));
``` `getResources().openRawResource` 将为您提供 `stream` 必须的,你可以用它 `stream` 创建 `GoogleCredentials` :

GoogleCredentials.fromStream(stream)

关于您的更新,似乎您正在创建 `TextToSpeechClient` 没有提供任何显式凭据,因此库正在环境中查找它们。
正如你在照片中看到的 `TechToSpeechClient` javadocs,您可以向客户端提供您的凭据。
而不是这样:

TextToSpeechClient textToSpeechClient = TextToSpeechClient.create()

使用类似的方法初始化您的客户机(请根据您的需要进行修改):

import com.google.api.gax.core.FixedCredentialsProvider;

// In your method...

InputStream stream = getResources().openRawResource(R.raw.credential); // R.raw.credential is credential.json
GoogleCredentials credentials = GoogleCredentials.fromStream(stream);
TextToSpeechSettings textToSpeechSettings =
TextToSpeechSettings.newBuilder()
.setCredentialsProvider(
FixedCredentialsProvider.create(credentials)
).build()
;

TextToSpeechClient textToSpeechClient =
TextToSpeechClient.create(textToSpeechSettings);

// The rest of your code

请确保您的服务帐户凭据为您提供了访问请求的API的正确授权。
事实上,正如我在您的问题中意识到的,如果您将项目所有者角色授予服务帐户,则您已经拥有这些权限。在任何情况下,请小心,项目所有者角色使您可以完全控制项目中的每一个资源:对于服务帐户来说,最好限制性更强。理想情况下,应该只授予它执行为其创建的操作所必需的权限。

相关问题