Android Open Source - youtubeAPI Main Activity






From Project

Back to project page youtubeAPI.

License

The source code is released under:

Apache License

If you think the Android project youtubeAPI listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (c) 2013 Google Inc.//  w w w. ja  v a2s.  c  o  m
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.sickboots.ytube;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.GooglePlayServicesAvailabilityIOException;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.util.ExponentialBackOff;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.ChannelListResponse;
import com.google.api.services.youtube.model.PlaylistItem;
import com.google.api.services.youtube.model.PlaylistItemListResponse;
import com.google.api.services.youtube.model.Video;
import com.google.api.services.youtube.model.VideoListResponse;
import com.google.api.services.youtube.model.VideoSnippet;
import com.sickboots.ytube.util.ImageFetcher;
import com.sickboots.ytube.util.Upload;
import com.sickboots.ytube.util.Utils;
import com.sickboots.ytube.util.VideoData;

/**
 * @author Ibrahim Ulukaya <ulukaya@google.com>
 *         <p/>
 *         Main activity class which handles authorization and intents.
 */
public class MainActivity extends Activity implements
    UploadsListFragment.Callbacks {
  private static final int REQUEST_GOOGLE_PLAY_SERVICES = 0;
  private static final int REQUEST_GMS_ERROR_DIALOG = 1;
  private static final int REQUEST_ACCOUNT_PICKER = 2;
  private static final int REQUEST_AUTHORIZATION = 3;
  private static final int RESULT_PICK_IMAGE_CROP = 4;
  private static final int RESULT_VIDEO_CAP = 5;
  private static final int REQUEST_DIRECT_TAG = 6;
  // private static final int MEDIA_TYPE_VIDEO = 7;
  public static final String ACCOUNT_KEY = "accountName";
  public static final String MESSAGE_KEY = "message";
  public static final String YOUTUBE_ID = "youtubeId";
  public static final String YOUTUBE_WATCH_URL_PREFIX = "http://www.youtube.com/watch?v=";
  private static final String TAG = "MainActivity";

  static final String REQUEST_AUTHORIZATION_INTENT = "com.google.example.yt.RequestAuth";
  static final String REQUEST_AUTHORIZATION_INTENT_PARAM = "com.google.example.yt.RequestAuth.param";

  private ImageFetcher mImageFetcher;

  private String mChosenAccountName;
  private Uri mFileURI = null;

  private VideoData mVideoData;

  private UploadBroadcastReceiver broadcastReceiver;

  private UploadsListFragment mUploadsListFragment;

  GoogleAccountCredential credential;
  final HttpTransport transport = AndroidHttp.newCompatibleTransport();
  final JsonFactory jsonFactory = new GsonFactory();

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    getWindow().requestFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
    super.onCreate(savedInstanceState);

    // Check to see if the proper keys and playlist IDs have been set up
    if (!isCorrectlyConfigured()) {
      setContentView(R.layout.developer_setup_required);
      showMissingConfigurations();
    } else {
      setContentView(R.layout.activity_main);

      ensureFetcher();

      credential = GoogleAccountCredential.usingOAuth2(
          getApplicationContext(), Arrays.asList(Auth.SCOPES));
      // set exponential backoff policy
      credential.setBackOff(new ExponentialBackOff());

      if (savedInstanceState != null) {
        mChosenAccountName = savedInstanceState.getString(ACCOUNT_KEY);
      } else {
        loadAccount();
      }

      credential.setSelectedAccountName(mChosenAccountName);

      mUploadsListFragment = (UploadsListFragment) getFragmentManager()
          .findFragmentById(R.id.list_fragment);
    }
  }

  /**
   * This method checks various internal states to figure out at startup time
   * whether certain elements have been configured correctly by the developer.
   * Checks that:
   * <ul>
   * <li>the API key has been configured</li>
   * <li>the playlist ID has been configured</li>
   * </ul>
   * 
   * @return true if the application is correctly configured for use, false if
   *         not
   */
  private boolean isCorrectlyConfigured() {
    // This isn't going to internationalize well, but we only really need
    // this for the sample app.
    // Real applications will remove this section of code and ensure that
    // all of these values are configured.
    if (Auth.KEY.startsWith("Replace")) {
      return false;
    }
    if (Constants.UPLOAD_PLAYLIST.startsWith("Replace")) {
      return false;
    }
    return true;
  }

  /**
   * Private class representing a missing configuration and what the developer
   * can do to fix the issue.
   */
  private class MissingConfig {

    public final String title;
    public final String body;

    public MissingConfig(String title, String body) {
      this.title = title;
      this.body = body;
    }
  }

  /**
   * This method renders the ListView explaining what the configurations the
   * developer of this application has to complete. Typically, these are
   * static variables defined in {@link Auth} and {@link Constants}.
   */
  private void showMissingConfigurations() {
    List<MissingConfig> missingConfigs = new ArrayList<MissingConfig>();

    // Make sure an API key is registered
    if (Auth.KEY.startsWith("Replace")) {
      missingConfigs
          .add(new MissingConfig(
              "API key not configured",
              "KEY constant in Auth.java must be configured with your Simple API key from the Google API Console"));
    }

    // Make sure a playlist ID is registered
    if (Constants.UPLOAD_PLAYLIST.startsWith("Replace")) {
      missingConfigs
          .add(new MissingConfig(
              "Playlist ID not configured",
              "UPLOAD_PLAYLIST constant in Constants.java must be configured with a Playlist ID to submit to. (The playlist ID typically has a prexix of PL)"));
    }

    // Renders a simple_list_item_2, which consists of a title and a body
    // element
    ListAdapter adapter = new ArrayAdapter<MissingConfig>(this,
        android.R.layout.simple_list_item_2, missingConfigs) {
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
        View row;
        if (convertView == null) {
          LayoutInflater inflater = (LayoutInflater) getApplicationContext()
              .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
          row = inflater.inflate(android.R.layout.simple_list_item_2,
              null);
        } else {
          row = convertView;
        }

        TextView titleView = (TextView) row
            .findViewById(android.R.id.text1);
        TextView bodyView = (TextView) row
            .findViewById(android.R.id.text2);
        MissingConfig config = getItem(position);
        titleView.setText(config.title);
        bodyView.setText(config.body);
        return row;
      }
    };

    // Wire the data adapter up to the view
    ListView missingConfigList = (ListView) findViewById(R.id.missing_config_list);
    missingConfigList.setAdapter(adapter);
  }

  @Override
  protected void onResume() {
    super.onResume();
    if (broadcastReceiver == null)
      broadcastReceiver = new UploadBroadcastReceiver();
    IntentFilter intentFilter = new IntentFilter(
        REQUEST_AUTHORIZATION_INTENT);
    LocalBroadcastManager.getInstance(this).registerReceiver(
        broadcastReceiver, intentFilter);
  }

  private void ensureFetcher() {
    if (mImageFetcher == null) {
      mImageFetcher = new ImageFetcher(this, 512, 512);
      mImageFetcher.addImageCache(getFragmentManager(),
          new com.sickboots.ytube.util.ImageCache.ImageCacheParams(this,
              "cache"));
    }
  }

  private void loadAccount() {
    SharedPreferences sp = PreferenceManager
        .getDefaultSharedPreferences(this);
    mChosenAccountName = sp.getString(ACCOUNT_KEY, null);
    invalidateOptionsMenu();
  }

  private void saveAccount() {
    SharedPreferences sp = PreferenceManager
        .getDefaultSharedPreferences(this);
    sp.edit().putString(ACCOUNT_KEY, mChosenAccountName).commit();
  }

  private void loadData() {
    if (mChosenAccountName == null) {
      return;
    }

    loadUploadedVideos();
  }

  @Override
  protected void onPause() {
    super.onPause();
    if (broadcastReceiver != null) {
      LocalBroadcastManager.getInstance(this).unregisterReceiver(
          broadcastReceiver);
    }
    if (isFinishing()) {
      // mHandler.removeCallbacksAndMessages(null);
    }
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return super.onCreateOptionsMenu(menu);
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.menu_refresh:
      loadData();
      break;
    case R.id.menu_accounts:
      chooseAccount();
      return true;
    }
    return super.onOptionsItemSelected(item);
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
    case REQUEST_GMS_ERROR_DIALOG:
      break;
    case RESULT_PICK_IMAGE_CROP:
      if (resultCode == RESULT_OK) {
        mFileURI = data.getData();
        if (mFileURI != null) {
          Intent intent = new Intent(this, ReviewActivity.class);
          intent.setData(mFileURI);
          startActivity(intent);
        }
      }
      break;

    case RESULT_VIDEO_CAP:
      if (resultCode == RESULT_OK) {
        mFileURI = data.getData();
        if (mFileURI != null) {
          Intent intent = new Intent(this, ReviewActivity.class);
          intent.setData(mFileURI);
          startActivity(intent);
        }
      }
      break;
    case REQUEST_GOOGLE_PLAY_SERVICES:
      if (resultCode == Activity.RESULT_OK) {
        haveGooglePlayServices();
      } else {
        checkGooglePlayServicesAvailable();
      }
      break;
    case REQUEST_AUTHORIZATION:
      if (resultCode != Activity.RESULT_OK) {
        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) {
          mChosenAccountName = accountName;
          credential.setSelectedAccountName(accountName);
          saveAccount();
        }
      }
      break;
    case REQUEST_DIRECT_TAG:
      if (resultCode == Activity.RESULT_OK && data != null
          && data.getExtras() != null) {
        String youtubeId = data.getStringExtra(YOUTUBE_ID);
        if (youtubeId.equals(mVideoData.getYouTubeId())) {
          directTag(mVideoData);
        }
      }
      break;
    }
  }

  private void directTag(final VideoData video) {
    final Video updateVideo = new Video();
    VideoSnippet snippet = video
        .addTags(Arrays.asList(
            Constants.DEFAULT_KEYWORD,
            Upload.generateKeywordFromPlaylistId(Constants.UPLOAD_PLAYLIST)));
    updateVideo.setSnippet(snippet);
    updateVideo.setId(video.getYouTubeId());

    new AsyncTask<Void, Void, Void>() {
      @Override
      protected Void doInBackground(Void... voids) {

        YouTube youtube = new YouTube.Builder(transport, jsonFactory,
            credential).setApplicationName(Constants.APP_NAME)
            .build();
        try {
          youtube.videos().update("snippet", updateVideo).execute();
        } catch (IOException e) {
          Log.e(TAG, e.getMessage());
        }
        return null;
      }

    }.execute((Void) null);
        Toast.makeText(this,
                R.string.video_submitted_to_ytdl, Toast.LENGTH_LONG)
                .show();
  }

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString(ACCOUNT_KEY, mChosenAccountName);
  }

  private void loadUploadedVideos() {
    if (mChosenAccountName == null) {
      return;
    }

    setProgressBarIndeterminateVisibility(true);
    new AsyncTask<Void, Void, List<VideoData>>() {
      @Override
      protected List<VideoData> doInBackground(Void... voids) {

        YouTube youtube = new YouTube.Builder(transport, jsonFactory,
            credential).setApplicationName(Constants.APP_NAME)
            .build();

        try {
          /*
           * Now that the user is authenticated, the app makes a
           * channels list request to get the authenticated user's
           * channel. Returned with that data is the playlist id for
           * the uploaded videos.
           * https://developers.google.com/youtube
           * /v3/docs/channels/list
           */
          ChannelListResponse clr = youtube.channels()
              .list("contentDetails").setMine(true).execute();

          // Get the user's uploads playlist's id from channel list
          // response
          String uploadsPlaylistId = clr.getItems().get(0)
              .getContentDetails().getRelatedPlaylists()
              .getUploads();

          List<VideoData> videos = new ArrayList<VideoData>();

          // Get videos from user's upload playlist with a playlist
          // items list request
          PlaylistItemListResponse pilr = youtube.playlistItems()
              .list("id,contentDetails")
              .setPlaylistId(uploadsPlaylistId)
              .setMaxResults(20l).execute();
          List<String> videoIds = new ArrayList<String>();

          // Iterate over playlist item list response to get uploaded
          // videos' ids.
          for (PlaylistItem item : pilr.getItems()) {
            videoIds.add(item.getContentDetails().getVideoId());
          }

          // Get details of uploaded videos with a videos list
          // request.
          VideoListResponse vlr = youtube.videos()
              .list("id,snippet,status")
              .setId(TextUtils.join(",", videoIds)).execute();

          // Add only the public videos to the local videos list.
          for (Video video : vlr.getItems()) {
            if ("public".equals(video.getStatus()
                .getPrivacyStatus())) {
              VideoData videoData = new VideoData();
              videoData.setVideo(video);
              videos.add(videoData);
            }
          }

          // Sort videos by title
          Collections.sort(videos, new Comparator<VideoData>() {
            @Override
            public int compare(VideoData videoData,
                VideoData videoData2) {
              return videoData.getTitle().compareTo(
                  videoData2.getTitle());
            }
          });

          return videos;

        } catch (final GooglePlayServicesAvailabilityIOException availabilityException) {
          showGooglePlayServicesAvailabilityErrorDialog(availabilityException
              .getConnectionStatusCode());
        } catch (UserRecoverableAuthIOException userRecoverableException) {
          startActivityForResult(
              userRecoverableException.getIntent(),
              REQUEST_AUTHORIZATION);
        } catch (IOException e) {
          Utils.logAndShow(MainActivity.this, Constants.APP_NAME, e);
        }
        return null;
      }

      @Override
      protected void onPostExecute(List<VideoData> videos) {
        setProgressBarIndeterminateVisibility(false);

        if (videos == null) {
          return;
        }

        mUploadsListFragment.setVideos(videos);
      }

    }.execute((Void) null);
  }

  @Override
  public void onBackPressed() {
    // if (mDirectFragment.popPlayerFromBackStack()) {
    // super.onBackPressed();
    // }
  }

  @Override
  public ImageFetcher onGetImageFetcher() {
    ensureFetcher();
    return mImageFetcher;
  }

  @Override
  public void onVideoSelected(VideoData video) {
    mVideoData = video;
    Intent intent = new Intent(this, PlayActivity.class);
    intent.putExtra(YOUTUBE_ID, video.getYouTubeId());
    startActivityForResult(intent, REQUEST_DIRECT_TAG);
  }

  @Override
  public void onConnected(String connectedAccountName) {
    // Make API requests only when the user has successfully signed in.
    loadData();
  }

  public void pickFile(View view) {
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType("video/*");
    startActivityForResult(intent, RESULT_PICK_IMAGE_CROP);
  }

  public void recordVideo(View view) {
    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

    // Workaround for Nexus 7 Android 4.3 Intent Returning Null problem
    // create a file to save the video in specific folder (this works for
    // video only)
    // mFileURI = getOutputMediaFile(MEDIA_TYPE_VIDEO);
    // intent.putExtra(MediaStore.EXTRA_OUTPUT, mFileURI);

    // set the video image quality to high
    intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);

    // start the Video Capture Intent
    startActivityForResult(intent, RESULT_VIDEO_CAP);
  }

  public void showGooglePlayServicesAvailabilityErrorDialog(
      final int connectionStatusCode) {
    runOnUiThread(new Runnable() {
      public void run() {
        Dialog dialog = GooglePlayServicesUtil.getErrorDialog(
            connectionStatusCode, MainActivity.this,
            REQUEST_GOOGLE_PLAY_SERVICES);
        dialog.show();
      }
    });
  }

  /** Check that Google Play services APK is installed and up to date. */
  private boolean checkGooglePlayServicesAvailable() {
    final int connectionStatusCode = GooglePlayServicesUtil
        .isGooglePlayServicesAvailable(this);
    if (GooglePlayServicesUtil.isUserRecoverableError(connectionStatusCode)) {
      showGooglePlayServicesAvailabilityErrorDialog(connectionStatusCode);
      return false;
    }
    return true;
  }

  private void haveGooglePlayServices() {
    // check if there is already an account selected
    if (credential.getSelectedAccountName() == null) {
      // ask user to choose account
      chooseAccount();
    }
  }

  private void chooseAccount() {
    startActivityForResult(credential.newChooseAccountIntent(),
        REQUEST_ACCOUNT_PICKER);
  }

  // public Uri getOutputMediaFile(int type)
  // {
  // // To be safe, you should check that the SDCard is mounted
  // if(Environment.getExternalStorageState() != null) {
  // // this works for Android 2.2 and above
  // File mediaStorageDir = new
  // File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES),
  // "SMW_VIDEO");
  //
  // // This location works best if you want the created images to be shared
  // // between applications and persist after your app has been uninstalled.
  //
  // // Create the storage directory if it does not exist
  // if (! mediaStorageDir.exists()) {
  // if (! mediaStorageDir.mkdirs()) {
  // Log.d(TAG, "failed to create directory");
  // return null;
  // }
  // }
  //
  // // Create a media file name
  // String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
  // Locale.getDefault()).format(new Date());
  // File mediaFile;
  // if(type == MEDIA_TYPE_VIDEO) {
  // mediaFile = new File(mediaStorageDir.getPath() + File.separator +
  // "VID_"+ timeStamp + ".mp4");
  // } else {
  // return null;
  // }
  //
  // return Uri.fromFile(mediaFile);
  // }
  //
  // return null;
  // }

  private class UploadBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
      if (intent.getAction().equals(REQUEST_AUTHORIZATION_INTENT)) {
        Log.d(TAG, "Request auth received - executing the intent");
        Intent toRun = intent
            .getParcelableExtra(REQUEST_AUTHORIZATION_INTENT_PARAM);
        startActivityForResult(toRun, REQUEST_AUTHORIZATION);
      }
    }
  }
}




Java Source Code List

com.sickboots.ytube.Auth.java
com.sickboots.ytube.Constants.java
com.sickboots.ytube.MainActivity.java
com.sickboots.ytube.PlayActivity.java
com.sickboots.ytube.ResumableUpload.java
com.sickboots.ytube.ReviewActivity.java
com.sickboots.ytube.UploadService.java
com.sickboots.ytube.UploadsListFragment.java
com.sickboots.ytube.util.AsyncTask.java
com.sickboots.ytube.util.DiskLruCache.java
com.sickboots.ytube.util.ImageCache.java
com.sickboots.ytube.util.ImageFetcher.java
com.sickboots.ytube.util.ImageResizer.java
com.sickboots.ytube.util.ImageWorker.java
com.sickboots.ytube.util.RecyclingBitmapDrawable.java
com.sickboots.ytube.util.Upload.java
com.sickboots.ytube.util.Utils.java
com.sickboots.ytube.util.VideoData.java