Вещи Android и API Календаря Google - PullRequest
0 голосов
/ 21 апреля 2019

Я пытаюсь получить события календаря пользователя на платформе Android Things и обнаружил следующее руководство, показывающее, как это сделать: https://medium.com/@F8Full/getaroom-android-things-google-calendar-api-2ab72a5b957f

Я получил код авторизации от пользователя на мобильном телефоне и отправил его на устройство Android Things. Затем я должен завершить поток OAuth на Android Things, но у меня возникла проблема. Вот ошибка, которую я получаю:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.subs.projecthera/com.subs.projecthera.MainActivity}: android.os.NetworkOnMainThreadException
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
    at android.app.ActivityThread.-wrap11(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
 Caused by: android.os.NetworkOnMainThreadException
    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1450)
    at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:102)
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:90)
    at java.net.InetAddress.getAllByName(InetAddress.java:787)
    at com.android.okhttp.Dns$1.lookup(Dns.java:39)
    at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:175)
    at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:141)
    at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:83)
    at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:174)
    at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:126)
    at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:95)
    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:281)
    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:224)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:461)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
    at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:258)
    at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218)
    at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(Unknown Source:0)
    at com.google.api.client.http.javanet.NetHttpRequest.execute(NetHttpRequest.java:77)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:981)
    at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:283)
    at com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest.execute(GoogleAuthorizationCodeTokenRequest.java:158)
    at com.subs.projecthera.Core.AuthHelper.<init>(AuthHelper.java:40)
    at com.subs.projecthera.MainActivity.onCreate(MainActivity.java:48)
    at android.app.Activity.performCreate(Activity.java:7010)
    at android.app.Activity.performCreate(Activity.java:7001)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731)

У меня есть класс AuthHelper:

Activity activity;
Context context;

public AuthHelper(String authCode) {
    // Exchange authCode for token
    if (authCode != null) {
        String CLIENT_SECRET_DATA = "{\"web\":{\"client_id\":\"529614308595-q103hbbbktc53tfrudofocg76a390bo1.apps.googleusercontent.com\",\"project_id\":\"smart-mirror-88c35\",\"auth_uri\":\"https://accounts.google.com/o/oauth2/auth\",\"token_uri\":\"https://oauth2.googleapis.com/token\",\"auth_provider_x509_cert_url\":\"https://www.googleapis.com/oauth2/v1/certs\"}}";

        try {
            GoogleClientSecrets GCS = GoogleClientSecrets.load(new JacksonFactory(), new StringReader(CLIENT_SECRET_DATA));
            GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(
                    new NetHttpTransport(),
                    new JacksonFactory(),
                    "https://www.googleapis.com/oauth2/v4/token",
                    GCS.getDetails().getClientId(),
                    GCS.getDetails().getClientSecret(),
                    authCode,
                    "" )
                    .execute();

            buildCredentialsAndUpdateActivityModel(tokenResponse);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public static GoogleCredential mGoogleCredential;

private void buildCredentialsAndUpdateActivityModel(GoogleTokenResponse tokenResponse) {
    String CLIENT_SECRET_DATA = "{\"web\":{\"client_id\":\"529614308595-q103hbbbktc53tfrudofocg76a390bo1.apps.googleusercontent.com\",\"project_id\":\"smart-mirror-88c35\",\"auth_uri\":\"https://accounts.google.com/o/oauth2/auth\",\"token_uri\":\"https://oauth2.googleapis.com/token\",\"auth_provider_x509_cert_url\":\"https://www.googleapis.com/oauth2/v1/certs\"}}";
    try {
        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(new JacksonFactory(), new StringReader(CLIENT_SECRET_DATA));

        mGoogleCredential = new GoogleCredential.Builder()
                                .setJsonFactory(new JacksonFactory())
                                .setTransport(new NetHttpTransport())
                                .setClientSecrets(clientSecrets).build().setFromTokenResponse(tokenResponse);
    } catch (IOException e) {
        e.printStackTrace();
    }

}

private boolean storeOAuth2TokenData(String storageID, GoogleCredential toStore) {
    boolean wasStored = false;

    try {
        File oauth2StorageFolder = new File(context.getFilesDir(), "oauth2StorageFolder");
        oauth2StorageFolder.mkdirs();

        FileDataStoreFactory fileDataStoreFactory = new FileDataStoreFactory(oauth2StorageFolder);

        DataStore storedCredentialDataStore = fileDataStoreFactory.getDataStore(storageID);//<new StoredCredential()>(storageID)

        //val oauth2Credential = Credential(BearerToken.authorizationHeaderAccessMethod()).setFromTokenResponse(tokenResponse)

        StoredCredential storedOAuth2Credential = new StoredCredential(toStore);
        storedCredentialDataStore.set(storageID, storedOAuth2Credential);

        wasStored = true;
    } catch (Exception exception) {
        //logInfo("Exception storing OAuth2TokenData :" + exception.localizedMessage)
    }

    return wasStored;
}




private TokenResponse getOAuth2TokenDataFromStore(String storageID) {
    TokenResponse tokenResponse = null;

    try {
        File oauth2StorageFolder = new File(context.getFilesDir(), "oauth2StorageFolder");
        oauth2StorageFolder.mkdirs();

        FileDataStoreFactory fileDataStoreFactory = new FileDataStoreFactory(oauth2StorageFolder);
        DataStore storedCredentialDataStore = fileDataStoreFactory.getDataStore(storageID);//<StoredCredential>(storageID);

        StoredCredential storedCredential = (StoredCredential) storedCredentialDataStore.get(storageID);

        if (storedCredential != null) {
            tokenResponse = new TokenResponse();
            tokenResponse.setAccessToken(storedCredential.getAccessToken());
            tokenResponse.setRefreshToken(storedCredential.getRefreshToken());

            if (storedCredential.getExpirationTimeMilliseconds() != null) {
                tokenResponse.setExpiresInSeconds(TimeUnit.MILLISECONDS.toSeconds(storedCredential.getExpirationTimeMilliseconds()));
            }
        }
    } catch (Exception exception) {
        //logInfo("Exception getting OAuth2TokenData :" + exception.localizedMessage)
    }

    return tokenResponse;
}

И у меня есть GoogleCalendarHelper:

public GoogleCalendarHelper() {
    Calendar calendarAPIClient = new Calendar(new NetHttpTransport(), new JacksonFactory(), AuthHelper.mGoogleCredential);

    calendarAPIClient.events();

    Log.e("SOMETHING", "");
}

Код вызывается из метода onCreate моей MainActivity.

    AuthHelper AH = new AuthHelper(GoogleSignIn.getAuthCode(this));
    GoogleCalendarHelper GCH = new GoogleCalendarHelper();

Я понимаю, что мне, возможно, придется использовать AsyncTask, но как это будет реализовано в этом? Это лучший способ получить информацию о событиях календаря, или есть лучший способ?

Спасибо

1 Ответ

1 голос
/ 22 апреля 2019

Журнал ошибок довольно прост: Сеть в главном потоке.

Вы выполняете запрос календаря, который является запросом сети, в главном потоке.

Вы должны это сделатьна заднем плане некоторыми распространенными решениями могут быть сопрограммы, RxJava, Callable / Runnable, использующие службу, управляющие потоками вручную или даже AsyncTask (что устарело).

Какое решение действительно зависит от вас, но долговыполнение операций в потоке пользовательского интерфейса запрещено как для Android, так и для Android.

...