YouTube API 3 Video hochladen - Zugriff nicht konfiguriert - Android

Ich arbeite an einer Android-App, die Videos aufzeichnet und es dem Benutzer ermöglicht, sie mithilfe der YouTube Data API v3 direkt auf YouTube hochzuladen.

Ich habe meine App in der API-Konsole von Google eingerichtet. Unter Dienste habe ich YouTube Data API v3 aktiviert. Unter API-Zugriff habe ich sowohl einen Abschnitt "Client-ID für installierte Anwendungen" (einschließlich einer Client-ID und eines Client-Geheimnisses) als auch einen Abschnitt "Einfacher API-Zugriff" -> "Schlüssel für Android-Apps (mit Zertifikaten)" (der einen API-Schlüssel enthält) und einen Bereich "Android Apps", der vorerst leer gelassen wird, dh alle Android-Apps zulassen, aber ich habe es mit dem Setzen meines Android-Schlüssels versucht).

Ich habe meinen Code von einer Reihe von Stellen aus erstellt, hauptsächlich von:

https://developers.google.com/youtube/v3/code_samples/java#upload_a_video

und

https://code.google.com/p/google-api-java-client/source/browse/tasks-android-sample/src/main/java/com/google/api/services/samples/tasks/android/ TasksSample.java?repo=samples

Der Upload wird in Ordnung initialisiert, die AsyncTask wird gestartet, aber dann wird eine IOException ausgelöst, die besagt:

{
    "code": 403,
    "errors": [
        {
            "domain": "usageLimits",
            "message": "Access Not Configured",
            "reason": "accessNotConfigured"
        }
    ],
    "message": "Access Not Configured"
}

Ähnliche SO-Posts deuten darauf hin, dass dies mit den Einstellungen meiner Google API-Konsole zusammenhängt, aber ich kann nichts falsches finden. Irgendwelche Vorschläge? Ich frage mich, ob es daran liegt, dass ich nirgendwo meine Kundennummer oder mein Geheimnis preisgebe ...

Vielen Dank.

Mein Code wird von einem Fragment mit einer Liste von Videos ausgeführt. Die relevanten Abschnitte sind:

-- Drin

public class UploadFragment extends Fragment {

    private static GoogleAccountCredential credential;
    private static final HttpTransport transport = AndroidHttp.newCompatibleTransport();
    private static final JsonFactory jsonFactory = new GsonFactory();
    public YouTube youtube;
    List<String> scopes = Lists.newArrayList(YouTubeScopes.YOUTUBE_UPLOAD);
    private static String VIDEO_FILE_FORMAT = "video/*";

    static final int REQUEST_GOOGLE_PLAY_SERVICES = 0;
    static final int REQUEST_AUTHORIZATION = 1;
    static final int REQUEST_ACCOUNT_PICKER = 2;

- Anmeldeinformationen und YouTube einrichten

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        ...
        credential = googleAccountCredential(scopes);
        youtube = new YouTube.Builder(transport, jsonFactory, credential)
            .setApplicationName("MyAppName")
            .build();
        ...
    }

- Starten Sie beim Klicken auf die Schaltfläche den Upload

    @Override void onClick(View v) {
        ...
        if (hasGooglePlayServices()) {
            uploadYouTubeVideos();

        ...
    }

- Erstellen Sie Anmeldeinformationen

    /**
     * Get the credential to authorize the installed application to access user's protected data.
     *
     * @param scopes list of scopes needed to run YouTube upload.
     */
    private static GoogleAccountCredential googleAccountCredential(List<String> scopes) throws Exception {
        credential = GoogleAccountCredential.usingOAuth2(context, scopes)
            .setSelectedAccountName(PreferenceManager.getAccountName());
        return credential;
    }

- Fordern Sie einen Account beim Benutzer an

    /**
     * Fire intent to get user to choose account
     * Return to onActivityResult
     */
    private void chooseAccount() {
        startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
    }

- Bei Rückkehr des Benutzers Auswahl und Konto- / Antragsberechtigung

    /**
     * Returns from chooseAccount and from request authorization
     */
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_AUTHORIZATION:
                if (resultCode == Activity.RESULT_OK) {
                    uploadYouTubeVideos();
                } else {
                    chooseAccount();
                }
                break;
            case REQUEST_ACCOUNT_PICKER:
                if (resultCode == Activity.RESULT_OK && data != null && data.getExtras() != null) {
                    String accountName = data.getExtras().getString(AccountManager.KEY_ACCOUNT_NAME);
                    if (accountName != null) {
                        credential.setSelectedAccountName(accountName);
                        PreferenceManager.setAccountName(accountName);
                        uploadYouTubeVideos();
                    }
                }
                break;
        }
    }

- Wird mehrmals aufgerufen, je nachdem, über welche Informationen wir verfügen - Konto, Autorisierung usw.

    /**
     * Uploads user selected video to the user's YouTube account using OAuth2
     * for authentication.
     *
     * @param videoFile file to be uploaded
     */
    public void uploadYouTubeVideos() {
        if (credential.getSelectedAccountName() == null) {
            chooseAccount();
        } else {
            File videoFile = getVideoFile();
            Insert videoInsert = prepareUpload(videoFile);
            new VideoUploadAsyncTask().execute(videoInsert);
        }
    }

- Upload vorbereiten - Alles zusammenfügen

    /**
     * Prepare upload. Just leaves execute to be run in AsyncTask.
     *
     * @param videoFile file to be uploaded
     * @return 
     */
    public Insert prepareUpload( File videoFile ) {
        try {
            // Add extra information to the video before uploading.
            Video videoObjectDefiningMetadata = new Video();

            // Set the video to public (default).
            VideoStatus status = new VideoStatus();
            status.setPrivacyStatus("public");
            videoObjectDefiningMetadata.setStatus(status);

            // We set a majority of the metadata with the VideoSnippet object.
            VideoSnippet snippet = new VideoSnippet();

            // Video file name.
            snippet.setTitle(videoFile.getName());
            snippet.setDescription("Test description");

            // Set keywords.
            List<String> tags = new ArrayList<String>();
            tags.add("test");
            snippet.setTags(tags);

            // Set completed snippet to the video object.
            videoObjectDefiningMetadata.setSnippet(snippet);

            InputStreamContent mediaContent = new InputStreamContent(
                    VIDEO_FILE_FORMAT, new BufferedInputStream(new FileInputStream(videoFile)));
            mediaContent.setLength(videoFile.length());

            /*
             * The upload command includes: 1. Information we want returned after file is successfully
             * uploaded. 2. Metadata we want associated with the uploaded video. 3. Video file itself.
             */
            YouTube.Videos.Insert videoInsert = youtube.videos()
                    .insert("snippet,statistics,status", videoObjectDefiningMetadata, mediaContent);

            // Set the upload type and add event listener.
            MediaHttpUploader uploader = videoInsert.getMediaHttpUploader();

            /*
             * Sets whether direct media upload is enabled or disabled. True = whole media content is
             * uploaded in a single request. False (default) = resumable media upload protocol to upload
             * in data chunks.
             */
            uploader.setDirectUploadEnabled(false);

            MediaHttpUploaderProgressListener progressListener = new MediaHttpUploaderProgressListener() {
                public void progressChanged(MediaHttpUploader uploader) throws IOException {
                    switch (uploader.getUploadState()) {
                        case INITIATION_STARTED:
                            Log.d(TAG, "Upload file: Initiation Started");
                            break;
                        case INITIATION_COMPLETE:
                            Log.d(TAG, "Upload file: Initiation Completed");
                            break;
                        case MEDIA_IN_PROGRESS:
                            Log.d(TAG, "Upload file: Upload in progress");
                            Log.d(TAG, "Upload file: Upload percentage: " + uploader.getProgress());
                            break;
                        case MEDIA_COMPLETE:
                            Log.d(TAG, "Upload file: Upload Completed!");
                            break;
                        case NOT_STARTED:
                            Log.d(TAG, "Upload file: Upload Not Started!");
                            break;
                    }
                }
            };
            uploader.setProgressListener(progressListener);

            return videoInsert;
        } catch (FileNotFoundException e) {
            Log.e(TAG, "File not found: " + e.getMessage());
            return null;
        } catch (IOException e) {
            Log.e(TAG, "IOException: " + e.getMessage());
            return null;
        }
    }

- Google Play-Dienste erfordern

    /** 
     * Pop up dialog requesting user to download Google Play Services.
     * Returns to onActivityResult
     */
    void showGooglePlayServicesAvailabilityErrorDialog(final int connectionStatusCode) {
        getActivity().runOnUiThread(new Runnable() {
            public void run() {
                Dialog dialog = 
                        GooglePlayServicesUtil.getErrorDialog(connectionStatusCode, getActivity(),
                        REQUEST_GOOGLE_PLAY_SERVICES);
                dialog.show();
            }
        });
    }

- AsyncTask, die ausgeführt wird, wird beim Hochladen ausgeführt

    public class VideoUploadAsyncTask extends AsyncTask<Insert, Void, Void> {
        @Override
        protected Void doInBackground( Insert... inserts ) {
            Insert videoInsert = inserts[0];
            try {
                Video returnVideo = videoInsert.execute();
            } catch (final GooglePlayServicesAvailabilityIOException availabilityException) {
                showGooglePlayServicesAvailabilityErrorDialog(
                        availabilityException.getConnectionStatusCode());
            } catch (UserRecoverableAuthIOException userRecoverableException) {
                startActivityForResult(
                        userRecoverableException.getIntent(), UploadFragment.REQUEST_AUTHORIZATION);
            } catch (IOException e) {
                Log.e(TAG, "IOException: " + e.getMessage());
            }
            return null;
        }
    }

}

Antworten auf die Frage(2)

Ihre Antwort auf die Frage