Skip to content

Instantly share code, notes, and snippets.

@agungf
Created February 27, 2017 12:00
Show Gist options
  • Select an option

  • Save agungf/bffd41f7caf26de6b2b27bf48d47a131 to your computer and use it in GitHub Desktop.

Select an option

Save agungf/bffd41f7caf26de6b2b27bf48d47a131 to your computer and use it in GitHub Desktop.

Revisions

  1. agungf created this gist Feb 27, 2017.
    660 changes: 660 additions & 0 deletions dacast-snippet-android
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,660 @@
    package com.ruangguru.livestudents.ui.onlinevideo;

    import android.content.Context;
    import android.content.DialogInterface;
    import android.content.Intent;
    import android.content.res.Configuration;
    import android.os.Build;
    import android.os.Bundle;
    import android.support.v7.widget.Toolbar;
    import android.util.Log;
    import android.view.Gravity;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.WindowManager;
    import android.view.animation.Animation;
    import android.view.animation.AnimationUtils;
    import android.webkit.ConsoleMessage;
    import android.webkit.JavascriptInterface;
    import android.webkit.WebSettings;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;
    import android.widget.Button;
    import android.widget.ImageButton;
    import android.widget.ImageView;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    import android.widget.Toast;
    import android.widget.ViewFlipper;

    import com.birbit.android.jobqueue.Params;
    import com.ruangguru.livestudents.R;
    import com.ruangguru.livestudents.RGStudentsApplication;
    import com.ruangguru.livestudents.events.onlinevideo.IGetUaIpFailed;
    import com.ruangguru.livestudents.events.onlinevideo.IGetUaIpSuccess;
    import com.ruangguru.livestudents.events.onlinevideo.videodetail.IGetVideoDetailFailed;
    import com.ruangguru.livestudents.events.onlinevideo.videodetail.IGetVideoDetailSuccess;
    import com.ruangguru.livestudents.events.onlinevideo.sendlikevideo.ISendLikeVideoFailed;
    import com.ruangguru.livestudents.events.onlinevideo.sendlikevideo.ISendLikeVideoSuccess;
    import com.ruangguru.livestudents.events.onlinevideo.watched.ISendWatchedVideoFailed;
    import com.ruangguru.livestudents.events.onlinevideo.watched.ISendWatchedVideoSuccess;
    import com.ruangguru.livestudents.models.http.Pagination;
    import com.ruangguru.livestudents.models.http.onlinevideo.VideoDetail;
    import com.ruangguru.livestudents.models.http.onlinevideo.VideoItem;
    import com.ruangguru.livestudents.services.APIClient;
    import com.ruangguru.livestudents.services.UserService;
    import com.ruangguru.livestudents.services.jobs.onlinevideo.GetUserAgentIpJob;
    import com.ruangguru.livestudents.services.jobs.onlinevideo.GetVideoDetailJob;
    import com.ruangguru.livestudents.services.jobs.onlinevideo.SendLikeVideoJob;
    import com.ruangguru.livestudents.services.jobs.onlinevideo.SendWatchedVideoJob;
    import com.ruangguru.livestudents.ui.BaseActivity;
    import com.ruangguru.livestudents.ui.onlinevideo.fragments.VideoPlayListFragment;
    import com.ruangguru.livestudents.ui.widget.webview.VideoEnabledWebChromeClient;
    import com.ruangguru.livestudents.ui.widget.webview.VideoEnabledWebView;
    import com.ruangguru.livestudents.utils.DeviceUtil;
    import com.ruangguru.livestudents.utils.ExtrasKeys;
    import com.ruangguru.livestudents.utils.PrefUtil;

    import org.greenrobot.eventbus.EventBus;
    import org.greenrobot.eventbus.Subscribe;

    import java.util.ArrayList;
    import java.util.HashMap;

    public class VideoPlayerActivity extends BaseActivity implements View.OnClickListener {

    private static final String TAG = VideoPlayerActivity.class.getSimpleName();

    private static final String JOB_SEND_LIKE_TAG = "job_send_like_tag";
    private static final String JOB_SEND_WATCHED_TAG = "job_send_watched_tag";



    private TextView descriptionTextView, titleTextView, topicTextView;
    private ImageView caretImageView;
    private ArrayList<VideoItem> allVideos;
    private Button summaryButton;
    private Toolbar mToolbar;

    private ImageButton btnLike;
    private ImageButton btnLiked;
    private ImageButton btnShare;

    private ViewFlipper flipperBtnLike;

    private boolean isJobAdded = false;

    private VideoItem chosenVideo;
    private VideoDetail videoDetail;

    private final int NOT_LIKED = 0;
    private final int LIKED = 1;

    private String fileId, description, topicName;
    private int chosenIndex;

    private VideoEnabledWebView webView;
    private VideoEnabledWebChromeClient webChromeClient;
    private View nonVideoLayout; // Your own view, read class comments
    private ViewGroup videoLayout; // Your own view, read class comments
    private View loadingView;
    private View scrollView;
    private ProgressBar mProgressBarVideo;
    private boolean isVideoFullyLoaded;
    private boolean isVideoWatched;

    public static final String END_OF_VIDEO_LOG_MESSAGE = "VIDEOEND";

    private Bundle mData;
    private int mPage, totalVideo;
    private Pagination mPagination;

    private String mUserAgent;
    private String mIp;

    private String getVideoUrl(String fileId) {
    return APIClient.getExternalUrl(this) + "video/player?file_id=" + fileId;
    }

    private String getVideoUrl(String fileId, String userAgent, String ip) {
    String url = APIClient.getExternalUrl(this) + "video/player?file_id=" + fileId + "&ip=" +ip +"&ua=" + userAgent;
    return url;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_online_video_player);

    mData = getIntent().getExtras();

    allVideos = mData.getParcelableArrayList(ExtrasKeys.KEY_RELATED_VIDEOS);
    chosenIndex = mData.getInt(ExtrasKeys.KEY_CHOSEN_INDEX);
    mPagination = mData.getParcelable(ExtrasKeys.KEY_PAGINATION);
    topicName = mData.getString(ExtrasKeys.KEY_TOPIC_NAME, "");

    mPage = mPagination.getCurrentPage();
    totalVideo = mPagination.getTotal();

    chosenVideo = allVideos.get(chosenIndex);
    fileId = chosenVideo.getFileId();

    initUi(savedInstanceState);

    setExpWebView();
    manageUserAgentIp();
    }

    private void initUi(Bundle savedInstanceState) {
    mToolbar = (Toolbar) findViewById(R.id.toolbar_player);
    if (mToolbar != null) {
    setSupportActionBar(mToolbar);
    showBackArrow();
    }

    mProgressBarVideo = (ProgressBar) findViewById(R.id.progress_video);
    if (mProgressBarVideo != null) {
    mProgressBarVideo.setVisibility(View.VISIBLE);
    }

    titleTextView = (TextView) findViewById(R.id.tv_video_title);
    if (titleTextView != null) {
    titleTextView.setText(chosenVideo.getTitleDisplayName());
    }

    descriptionTextView = (TextView) findViewById(R.id.tv_video_description);
    if (descriptionTextView != null) {
    descriptionTextView.setVisibility(View.GONE);
    }

    caretImageView = (ImageView) findViewById(R.id.iv_caret_sign);
    if (caretImageView != null) {
    caretImageView.setOnClickListener(this);
    caretImageView.setVisibility(View.GONE);
    }

    summaryButton = (Button) findViewById(R.id.btn_show_summary);
    if (summaryButton != null) {
    summaryButton.setOnClickListener(this);
    }

    topicTextView = (TextView) findViewById(R.id.tv_player_topic);
    int chosenIndexShown = chosenIndex + 1;
    String topicTitle = topicName + " " + "(" + chosenIndexShown + "/" + totalVideo + " " + "video" + ")";

    if (topicTextView != null) {
    topicTextView.setText(topicTitle);
    }

    btnLike = (ImageButton) findViewById(R.id.btn_video_like);
    btnLiked = (ImageButton) findViewById(R.id.btn_video_liked);
    btnShare = (ImageButton) findViewById(R.id.btn_video_share);

    flipperBtnLike = (ViewFlipper) findViewById(R.id.vf_video_like);
    if (flipperBtnLike != null) {
    if (chosenVideo.isLiked()) {
    flipperBtnLike.setDisplayedChild(LIKED);
    }
    }

    if (btnLike != null)
    btnLike.setOnClickListener(this);
    if (btnLiked != null)
    btnLiked.setOnClickListener(this);
    if (btnShare != null)
    btnShare.setOnClickListener(this);


    if (savedInstanceState != null) {
    mData.putParcelableArrayList(ExtrasKeys.KEY_RELATED_VIDEOS, savedInstanceState.getParcelableArrayList(ExtrasKeys.KEY_LIST_VIDEO));
    } else {
    mData.putParcelableArrayList(ExtrasKeys.KEY_RELATED_VIDEOS, allVideos);
    }

    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
    VideoPlayListFragment newFragment = VideoPlayListFragment.newInstance(mData, VideoPlayListFragment.MODE_PLAYER);
    getSupportFragmentManager().beginTransaction().add(R.id.related_videos_container, newFragment).commit();
    }
    nonVideoLayout = findViewById(R.id.nonVideoLayout);
    videoLayout = (ViewGroup) findViewById(R.id.videoLayout);
    loadingView = getLayoutInflater().inflate(R.layout.view_loading_video, null);
    scrollView = findViewById(R.id.video_info_scroll);
    }

    @Override
    protected void onResume() {
    super.onResume();
    if (webView != null)
    webView.onResume();

    EventBus.getDefault().register(this);

    if (!isJobAdded) {
    GetVideoDetailJob job = new GetVideoDetailJob(new Params(1).requireNetwork().addTags(this.toString()), chosenVideo.getFileId());
    jobManager.addJobInBackground(job);
    isJobAdded = true;
    }

    }

    private void loadVideoUrl(String url) {
    final HashMap<String, String> params = new HashMap<String, String>() {
    {
    put("Authorization", "Bearer " + UserService.getCurrentUser().getAccessToken());
    }
    };

    webView.loadUrl(url, params);
    }

    private void manageUserAgentIp(){
    RGStudentsApplication app = RGStudentsApplication.getInstance();
    if (app.getUserAgent() == null || app.getIp() == null) {
    GetUserAgentIpJob getUaIpjob = new GetUserAgentIpJob(new Params(1).requireNetwork().addTags("getUaIpjob"));
    jobManager.addJobInBackground(getUaIpjob);
    } else {
    mUserAgent = app.getUserAgent();
    mIp = app.getIp();

    loadVideoUrl(getVideoUrl(fileId, mUserAgent, mIp));
    }
    }
    @Override
    protected void onPause() {
    super.onPause();
    if (webView != null)
    webView.onPause();
    EventBus.getDefault().unregister(this);
    }

    @Override
    protected void onDestroy() {
    super.onDestroy();
    if (webView != null) {
    webView.destroy();
    }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
    scrollView.setVisibility(View.GONE);

    ViewGroup.LayoutParams params = webView.getLayoutParams();
    params.height = ViewGroup.LayoutParams.MATCH_PARENT;
    params.width = ViewGroup.LayoutParams.MATCH_PARENT;
    webView.setLayoutParams(params);
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
    scrollView.setVisibility(View.VISIBLE);

    ViewGroup.LayoutParams params = webView.getLayoutParams();
    params.height = (int) getResources().getDimension(R.dimen.video_webview_height);
    params.width = ViewGroup.LayoutParams.MATCH_PARENT;
    webView.setLayoutParams(params);
    }
    }

    @Override
    protected void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putInt(ExtrasKeys.KEY_CHOSEN_INDEX, chosenIndex);
    savedInstanceState.putString(ExtrasKeys.KEY_FILE_ID, fileId);
    savedInstanceState.putParcelableArrayList(ExtrasKeys.KEY_LIST_VIDEO, allVideos);
    savedInstanceState.putString(ExtrasKeys.KEY_VIDEO_DESCRIPTION, description);

    super.onSaveInstanceState(savedInstanceState);
    }

    @Override
    public void onBackPressed() {
    // Notify the VideoEnabledWebChromeClient, and handle it ourselves if it doesn't handle it
    if (!webChromeClient.onBackPressed()) {
    if (webView.canGoBack()) {
    webView.goBack();
    } else {
    // Standard back button implementation (for example this could close the app)
    super.onBackPressed();
    }
    }
    }

    @Override
    public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn_show_summary:
    showSummary();
    break;
    case R.id.iv_caret_sign:
    toggleDescription(v);
    break;
    case R.id.btn_video_like:
    likeVideo();
    break;
    case R.id.btn_video_liked:
    unlikeVideo();
    break;
    case R.id.btn_video_share:
    share();
    break;
    }
    }

    private void showSummary() {
    if (videoDetail.getSummaryData() != null) {
    Bundle data = new Bundle();
    data.putParcelableArrayList(SummaryActivity.SUMMARY_LIST, (ArrayList) videoDetail.getSummaryData());
    data.putString(SummaryActivity.VIDEO_TITLE, videoDetail.getVideoItem().getTitle());
    data.putString(SummaryActivity.VIDEO_ID, videoDetail.getVideoItem().getId());

    Intent intent = new Intent(this, SummaryActivity.class);
    intent.putExtras(data);
    startActivity(intent);
    }
    }

    private void share() {
    String message = getString(R.string.msg_share_video);
    Intent shareIntent = new Intent(Intent.ACTION_SEND);

    shareIntent.setType("text/plain");
    shareIntent.putExtra(Intent.EXTRA_TEXT, message);

    startActivity(Intent.createChooser(shareIntent, getString(R.string.title_share_intent)));
    }

    private void watchedVideo() {
    if (videoDetail != null) {
    jobManager.addJobInBackground(new SendWatchedVideoJob(
    new Params(2).addTags(JOB_SEND_WATCHED_TAG),
    videoDetail.getVideoItem().getFileId(),
    "Y"));
    }
    }

    private void likeVideo() {
    jobManager.addJobInBackground(new SendLikeVideoJob(
    new Params(2).addTags(JOB_SEND_LIKE_TAG),
    videoDetail.getVideoItem().getFileId(),
    "Y"));
    }

    private void unlikeVideo() {
    jobManager.addJobInBackground(new SendLikeVideoJob(
    new Params(2).addTags(JOB_SEND_LIKE_TAG),
    videoDetail.getVideoItem().getFileId(),
    "N"));
    }


    @Subscribe
    public void onEvent(IGetUaIpSuccess event){
    RGStudentsApplication app = RGStudentsApplication.getInstance();
    app.setIp(event.getIp());
    app.setUserAgent(DeviceUtil.getUdid(this));

    Log.d("iy", "udid : " +DeviceUtil.getUdid(this));
    mIp = event.getIp();
    mUserAgent = DeviceUtil.getUdid(this);

    loadVideoUrl(getVideoUrl(fileId, mUserAgent, mIp));
    }

    @Subscribe
    public void onEvent(IGetUaIpFailed event){
    loadVideoUrl(getVideoUrl(fileId));
    setExpWebView(); // initialize video anyway without UserAgent and Ip
    }

    @Subscribe
    public void onEvent(IGetVideoDetailSuccess event) {
    videoDetail = event.getVideoDetail();
    runOnUiThread(new Runnable() {
    @Override
    public void run() {
    if (videoDetail.getDescription() != null && !videoDetail.getDescription().equals("")) {
    caretImageView.setVisibility(View.VISIBLE);
    description = videoDetail.getDescription();
    descriptionTextView.setText(description);
    descriptionTextView.setVisibility(View.VISIBLE);

    if (videoDetail.getVideoItem().isLiked()) {
    flipperBtnLike.setDisplayedChild(LIKED);
    }
    }

    if (videoDetail.getSummaryData() != null && videoDetail.getSummaryData().size() > 0) {
    summaryButton.setVisibility(View.VISIBLE);
    }
    }
    });
    }

    @Subscribe
    public void onEvent(IGetVideoDetailFailed event) {
    hideProgressDialog();
    if (event != null) {
    showToast(this, event.getErrorMessage());
    Log.e(TAG, event.getLogErrorMessage());
    }
    }

    @Subscribe
    public void onEvent(ISendLikeVideoSuccess event) {
    if (event != null) {
    if (event.getLikeStatus().equals("Y")) {
    showToast(this, getString(R.string.msg_like_video_sucess));
    flipperBtnLike.setDisplayedChild(LIKED);
    } else {
    showToast(this, getString(R.string.msg_unlike_video_success));
    flipperBtnLike.setDisplayedChild(NOT_LIKED);
    }
    }
    }

    @Subscribe
    public void onEvent(ISendWatchedVideoSuccess event) {
    if (event != null) {
    if (event.getWatchedStatus().equals("Y")) {
    Log.d(TAG, "watched success");
    isVideoWatched = true;
    // showToast(this, getString(R.string.msg_like_video_sucess));
    }
    }
    }

    @Subscribe
    public void onEvent(ISendWatchedVideoFailed event) {
    if (event != null) {
    Log.d(TAG, event.getErrorMessage());
    }
    }

    @Subscribe
    public void onEvent(ISendLikeVideoFailed event) {
    if (event != null) {
    showToast(this, event.getErrorMessage());
    Log.e(TAG, event.getLogErrorMessage());
    }
    }

    public void toggleDescription(View v) {
    if (descriptionTextView.isShown()) {
    animSlideUp(descriptionTextView);
    descriptionTextView.setVisibility(View.GONE);
    caretImageView.setImageResource(R.drawable.ic_caret_down);
    } else {
    descriptionTextView.setVisibility(View.VISIBLE);
    caretImageView.setImageResource(R.drawable.ic_caret_up);
    animSlideDown(descriptionTextView);
    }
    }

    public void animSlideDown(View v) {
    Animation a = AnimationUtils.loadAnimation(this, R.anim.slide_down);
    if (a != null) {
    a.reset();
    if (v != null) {
    v.clearAnimation();
    v.startAnimation(a);
    }
    }
    }

    public void animSlideUp(View v) {
    Animation a = AnimationUtils.loadAnimation(this, R.anim.slide_up);
    if (a != null) {
    a.reset();
    if (v != null) {
    v.clearAnimation();
    v.startAnimation(a);
    }
    }
    }

    public class WebAppInterface {
    Context mContext;

    /**
    * Instantiate the interface and set the context
    */
    WebAppInterface(Context c) {
    mContext = c;
    }

    /**
    * Show a toast from the web page
    */
    @JavascriptInterface
    public void showToast(String toast) {
    Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
    }

    @JavascriptInterface
    public void toggleFullscreen(boolean state) {
    Toast.makeText(mContext, state ? "FULLSCREEN TRUE" : "FULLSCREEN FALSE", Toast.LENGTH_SHORT).show();
    }
    }

    private void setExpWebView() {

    webView = (VideoEnabledWebView) findViewById(R.id.wv_video);

    WebSettings settings = webView.getSettings();
    settings.setJavaScriptEnabled(true);
    settings.setPluginState(WebSettings.PluginState.ON);
    settings.setSupportMultipleWindows(true);
    settings.setJavaScriptCanOpenWindowsAutomatically(true);
    settings.setLoadsImagesAutomatically(true);
    settings.setDomStorageEnabled(true);
    settings.setLoadWithOverviewMode(true);
    settings.setAllowUniversalAccessFromFileURLs(true);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    settings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
    }

    webChromeClient = new VideoEnabledWebChromeClient(nonVideoLayout, videoLayout, loadingView, webView) // See all available constructors...
    {

    public boolean onConsoleMessage(ConsoleMessage cm) {
    ConsoleMessage.MessageLevel ml = cm.messageLevel();

    if (cm.message().equals(END_OF_VIDEO_LOG_MESSAGE) && PrefUtil.hasWatchedFirstVideoUntilEnd(VideoPlayerActivity.this)) {
    showCustomDialog(getLayoutInflater().inflate(R.layout.dialog_video_finish, null), null, null,
    getString(R.string.action_see_summary), new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
    showSummary();
    }
    });

    PrefUtil.setHasWatchedVideoUntilEnd(VideoPlayerActivity.this);
    }

    Log.d(TAG, cm.message() + " " + " -- From line "
    + cm.lineNumber() + "Message Level name: " + ml.name());
    return true;
    }

    // Subscribe to standard events, such as onProgressChanged()...
    @Override
    public void onProgressChanged(WebView view, int progress) {
    // if progress == 100, hide progress bar
    if (progress == 100) {
    if (mProgressBarVideo != null) {
    mProgressBarVideo.setVisibility(View.GONE);
    }

    showFullscreenGuideToast();
    isVideoFullyLoaded = true;
    }
    }
    };

    webChromeClient.setOnToggledFullscreen(new VideoEnabledWebChromeClient.ToggledFullscreenCallback() {
    @Override
    public void toggledFullscreen(boolean fullscreen) {
    // Your code to handle the full-screen change, for example showing and hiding the title bar. Example:
    if (fullscreen) {
    WindowManager.LayoutParams attrs = getWindow().getAttributes();
    attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
    attrs.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
    getWindow().setAttributes(attrs);
    if (android.os.Build.VERSION.SDK_INT >= 14) {
    //noinspection all
    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
    }
    } else {
    WindowManager.LayoutParams attrs = getWindow().getAttributes();
    attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
    attrs.flags &= ~WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
    getWindow().setAttributes(attrs);
    if (android.os.Build.VERSION.SDK_INT >= 14) {
    //noinspection all
    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
    }
    }

    }
    });
    webView.setWebChromeClient(webChromeClient);
    // Call private class InsideWebViewClient
    webView.setWebViewClient(new InsideWebViewClient());

    webView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN){
    if (isVideoFullyLoaded && !isVideoWatched)
    watchedVideo();
    }
    return false;
    }
    });

    }

    private class InsideWebViewClient extends WebViewClient {

    final HashMap<String, String> params = new HashMap<String, String>() {
    {
    put("Authorization", "Bearer " + UserService.getCurrentUser().getAccessToken());
    }
    };

    @Override
    // Force links to be opened inside WebView and not in Default Browser
    // Thanks http://stackoverflow.com/a/33681975/1815624
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
    view.loadUrl(url, params);
    return true;
    }
    }

    private void showFullscreenGuideToast() {
    Toast toastMessage = Toast.makeText(VideoPlayerActivity.this, getString(R.string.rotate_device), Toast.LENGTH_SHORT);
    toastMessage.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, (int) getResources().getDimension(R.dimen.video_webview_height) / 2);
    toastMessage.show();
    }

    }