Android Open Source - plus1-android-sdk Mraid View






From Project

Back to project page plus1-android-sdk.

License

The source code is released under:

Copyright (c) 2012, WapStart All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Red...

If you think the Android project plus1-android-sdk 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

package ru.wapstart.plus1.sdk;
//from ww w .j  a va2 s .  c o m
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;

import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.util.Log;
import android.view.View;
import android.view.MotionEvent;
import android.view.LayoutInflater;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.VideoView;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;

public class MraidView extends BaseAdView {
  private static final String LOGTAG = "MraidView";

  private View mCustomView;

  private MraidBrowserController mBrowserController;
  private MraidDisplayController mDisplayController;

  private WebViewClient mWebViewClient;
  private WebChromeClient mWebChromeClient;

  private boolean mHasFiredReadyEvent;
  private String mMraidPath;
  private final PlacementType mPlacementType;

  static class MraidListenerInfo {
    private OnExpandListener mOnExpandListener;
    private OnCloseListener mOnCloseListener;
    private OnReadyListener mOnReadyListener;
    private OnFailureListener mOnFailureListener;
    private OnCloseButtonStateChangeListener mOnCloseButtonListener;
    private OnOpenListener mOnOpenListener;
  }
  private MraidListenerInfo mListenerInfo;

  /**
   * NOTE: WebView workaround
   * @see http://code.google.com/p/android/issues/detail?id=7189
   */
  private OnTouchListener mTouchListener = new OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
      switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_UP:
          if (!v.hasFocus())
            v.requestFocus();
          break;
      }

      return false;
    }
  };

  public static final int PLACEHOLDER_VIEW_ID = 100;
  public static final int MODAL_CONTAINER_LAYOUT_ID = 101;
  public static final int AD_CONTAINER_LAYOUT_ID = 102;

  public enum ViewState {
    LOADING,
    DEFAULT,
    EXPANDED,
    HIDDEN
  }

  enum ExpansionStyle {
    ENABLED,
    DISABLED
  }

  enum NativeCloseButtonStyle {
    ALWAYS_VISIBLE,
    ALWAYS_HIDDEN,
    AD_CONTROLLED
  }

  enum PlacementType {
    INLINE,
    INTERSTITIAL
  }

  public MraidView(Context context) {
    this(context, ExpansionStyle.ENABLED, NativeCloseButtonStyle.AD_CONTROLLED,
        PlacementType.INLINE);
  }

  MraidView(Context context, ExpansionStyle expStyle, NativeCloseButtonStyle buttonStyle,
      PlacementType placementType) {
    super(context);
    mPlacementType = placementType;
    initialize(expStyle, buttonStyle);
  }

  private void initialize(ExpansionStyle expStyle, NativeCloseButtonStyle buttonStyle) {
    setScrollContainer(false);
    setBackgroundColor(Color.TRANSPARENT);

    setVerticalScrollBarEnabled(false);
    setHorizontalScrollBarEnabled(false);

    getSettings().setJavaScriptEnabled(true);

    mBrowserController = new MraidBrowserController(this);
    mDisplayController = new MraidDisplayController(this, expStyle, buttonStyle);

    mWebViewClient = new MraidWebViewClient();
    setWebViewClient(mWebViewClient);

    mWebChromeClient = new MraidWebChromeClient();
    setWebChromeClient(mWebChromeClient);

    mListenerInfo = new MraidListenerInfo();
  }

  @Override
  public void destroy() {
    if (mDisplayController != null) {
      mDisplayController.destroy();
      mBrowserController = null;
      mDisplayController = null;
    }

    super.destroy();
  }

  public void loadHtmlData(String data) {
    data = completeHtml(data);

    // Inject the MRAID JavaScript bridge.
    if (mMraidPath == null)
      mMraidPath = "file://" + copyRawResourceToFilesDir(R.raw.mraid, "mraid.js");

    data = data.replace("<head>", "<head><script src='" + mMraidPath + "'></script>");

    loadDataWithBaseURL(null, data, "text/html", "UTF-8", null);
  }

  @Override
  public void loadUrl(String url) {
    if (url.startsWith("file:")) {
      super.loadUrl(url);
      return;
    }

    HttpClient httpClient = new DefaultHttpClient();
    HttpGet httpGet = new HttpGet(url);
    StringBuffer out = new StringBuffer();

    try {
      HttpResponse response = httpClient.execute(httpGet);
      HttpEntity entity = response.getEntity();

      if (entity != null) {
        InputStream is = entity.getContent();
        byte[] b = new byte[4096];
        for (int n; (n = is.read(b)) != -1;) {
          out.append(new String(b, 0, n));
        }
      }
    } catch (ClientProtocolException e) {
      notifyOnFailureListener();
      return;
    } catch (IOException e) {
      notifyOnFailureListener();
      return;
    }

    loadHtmlData(out.toString());
  }

  @Override
  public void pauseAdView() {
    setOnTouchListener(null);

    if (mDisplayController != null)
      mDisplayController.stopTasks();

    super.pauseAdView();
  }

  @Override
  public void resumeAdView() {
    if (mDisplayController != null)
      mDisplayController.startTasks();

    setOnTouchListener(mTouchListener);

    super.resumeAdView();
  }

  @Override
  public boolean canGoBack() {
    return
      mCustomView != null
      || getDisplayController().isExpanded()
      || super.canGoBack();
  }

  @Override
  public void goBack() {
    if (mCustomView != null)
      mWebChromeClient.onHideCustomView();
    else if (getDisplayController().isExpanded())
      getDisplayController().close();
    else
      super.goBack();
  }

  private void notifyOnFailureListener() {
    if (mListenerInfo.mOnFailureListener != null) {
      mListenerInfo.mOnFailureListener.onFailure(this);
    }
  }

  // Controllers /////////////////////////////////////////////////////////////////////////////////

  protected MraidBrowserController getBrowserController() {
    return mBrowserController;
  }

  protected MraidDisplayController getDisplayController() {
    return mDisplayController;
  }

  // Listeners ///////////////////////////////////////////////////////////////////////////////////

  public void setOnExpandListener(OnExpandListener listener) {
    mListenerInfo.mOnExpandListener = listener;
  }

  public OnExpandListener getOnExpandListener() {
    return mListenerInfo.mOnExpandListener;
  }

  public void setOnCloseListener(OnCloseListener listener) {
    mListenerInfo.mOnCloseListener = listener;
  }

  public OnCloseListener getOnCloseListener() {
    return mListenerInfo.mOnCloseListener;
  }

  public void setOnReadyListener(OnReadyListener listener) {
    mListenerInfo.mOnReadyListener = listener;
  }

  public OnReadyListener getOnReadyListener() {
    return mListenerInfo.mOnReadyListener;
  }

  public void setOnFailureListener(OnFailureListener listener) {
    mListenerInfo.mOnFailureListener = listener;
  }

  public OnFailureListener getOnFailureListener() {
    return mListenerInfo.mOnFailureListener;
  }

  public void setOnCloseButtonStateChange(OnCloseButtonStateChangeListener listener) {
    mListenerInfo.mOnCloseButtonListener = listener;
  }

  public OnCloseButtonStateChangeListener getOnCloseButtonStateChangeListener() {
    return mListenerInfo.mOnCloseButtonListener;
  }

  public void setOnOpenListener(OnOpenListener listener) {
    mListenerInfo.mOnOpenListener = listener;
  }

  public OnOpenListener getOnOpenListener() {
    return mListenerInfo.mOnOpenListener;
  }

  // JavaScript injection ////////////////////////////////////////////////////////////////////////

  protected void injectJavaScript(String js) {
    if (js != null) super.loadUrl("javascript:" + js);
  }

  protected void fireChangeEventForProperty(MraidProperty property) {
    String json = "{" + property.toString() + "}";
    injectJavaScript("window.mraidbridge.fireChangeEvent(" + json + ");");
    Log.d(LOGTAG, "Fire change: " + json);
  }

  protected void fireChangeEventForProperties(ArrayList<MraidProperty> properties) {
    String props = properties.toString();
    if (props.length() < 2) return;

    String json = "{" + props.substring(1, props.length() - 1) + "}";
    injectJavaScript("window.mraidbridge.fireChangeEvent(" + json + ");");
    Log.d(LOGTAG, "Fire changes: " + json);
  }

  protected void fireErrorEvent(String action, String message) {
    injectJavaScript("window.mraidbridge.fireErrorEvent('" + action + "', '" + message + "');");
  }

  protected void fireReadyEvent() {
    injectJavaScript("window.mraidbridge.fireReadyEvent();");
  }

  protected void fireNativeCommandCompleteEvent(String command) {
    injectJavaScript("window.mraidbridge.nativeCallComplete('" + command + "');");
  }

  private boolean tryCommand(URI uri) {
    String commandType = uri.getHost();
    List<NameValuePair> list = URLEncodedUtils.parse(uri, "UTF-8");
    Map<String, String> params = new HashMap<String, String>();
    for (NameValuePair pair : list) {
      params.put(pair.getName(), pair.getValue());
    }

    MraidCommand command = MraidCommandRegistry.createCommand(commandType, params, this);
    if (command == null) {
      fireNativeCommandCompleteEvent(commandType);
      return false;
    } else {
      command.execute();
      fireNativeCommandCompleteEvent(commandType);
      return true;
    }
  }

  /**
   * Copies a file from res/raw to <destinationFilename> in the application file directory.
   */
  private String copyRawResourceToFilesDir(int resourceId, String destinationFilename) {
    InputStream is = getContext().getResources().openRawResource(resourceId);

    String destinationPath = getContext().getFilesDir().getAbsolutePath() + File.separator +
        destinationFilename;
    File destinationFile = new File(destinationPath);
    FileOutputStream fos;
    try {
      fos = new FileOutputStream(destinationFile);
    } catch (FileNotFoundException e) {
      return "";
    }

    byte[] b = new byte[8192];
    try {
      for (int n; (n = is.read(b)) != -1;) {
        fos.write(b, 0, n);
      }
    } catch (IOException e) {
      return "";
    } finally {
      try { is.close(); fos.close(); } catch (IOException e) { }
    }

    return destinationPath;
  }

  private class MraidWebViewClient extends WebViewClient {
    @Override
    public void onReceivedError(WebView view, int errorCode, String description,
        String failingUrl) {
      Log.d(LOGTAG, "Error: " + description);
      super.onReceivedError(view, errorCode, description, failingUrl);
    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
      Uri uri = Uri.parse(url);
      String scheme = uri.getScheme();

      if (scheme.equals("mraid")) {
        Log.d(LOGTAG, "MRAID command: " + url);
        tryCommand(URI.create(url)); // java.net.URI, not android.net.Uri
        return true;
      }

      Intent i = new Intent();
      i.setAction(Intent.ACTION_VIEW);
      i.setData(Uri.parse(url));
      i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

      try {
        getContext().startActivity(i);
        return true;
      } catch (ActivityNotFoundException e) {
        return false;
      }
    }

    @Override
    public void onPageFinished(WebView view, String url) {
      if (!mHasFiredReadyEvent && mDisplayController != null) {
        mDisplayController.initializeJavaScriptState();
        fireChangeEventForProperty(
          MraidPlacementTypeProperty.createWithType(mPlacementType)
        );
        fireReadyEvent();
        if (getOnReadyListener() != null) getOnReadyListener().onReady(MraidView.this);
        mHasFiredReadyEvent = true;
      }
    }

    @Override
    public void onLoadResource(WebView view, String url) {
      Log.d(LOGTAG, "Loaded resource: " + url);
    }
  }

  private class MraidWebChromeClient extends WebChromeClient {
    private WebChromeClient.CustomViewCallback mCustomViewCallback;

    private Bitmap mDefaultVideoPoster;
    private View mVideoProgressView;

    @Override
    public void onShowCustomView(View view, CustomViewCallback callback) {
      /*((Activity)getContext()).getWindow().addFlags(
        WindowManager.LayoutParams.FLAG_FULLSCREEN
      );*/

      if (mCustomView != null) {
        callback.onCustomViewHidden();
      } else {
        mCustomView = view;
        mCustomViewCallback = callback;

        VideoView customVideoView =
          (
            mCustomView instanceof FrameLayout
            && ((FrameLayout)mCustomView).getFocusedChild() instanceof VideoView
          )
            ? (VideoView) ((FrameLayout)mCustomView).getFocusedChild()
            : null;

        getDisplayController().showCustomView(mCustomView);

        if (customVideoView != null) {
          customVideoView.setOnCompletionListener(new OnCompletionListener() {
            public void onCompletion(MediaPlayer mp) {
              mp.stop();
              Log.d(LOGTAG, "onCompletion() fired");
              onHideCustomView();
            }
          });
          customVideoView.setOnErrorListener(new OnErrorListener() {
            public boolean onError(MediaPlayer mp, int what, int extra) {
              Log.e(LOGTAG, "Error in custom video, type " + what);
              return true;
            }
          });
          //customVideoView.start();
        }
      }
    }

    @Override
    public void onHideCustomView() {
      if (mCustomView != null) {
        getDisplayController().hideCustomView(mCustomView);
        mCustomViewCallback.onCustomViewHidden();
        mCustomView = null;
      }

      /*((Activity)getContext()).getWindow().clearFlags(
        WindowManager.LayoutParams.FLAG_FULLSCREEN
      );*/
    }

    @Override
    public Bitmap getDefaultVideoPoster() {
      if (mDefaultVideoPoster == null) {
        mDefaultVideoPoster = BitmapFactory.decodeResource(
          getResources(), R.drawable.default_video_poster);
      }

      return mDefaultVideoPoster;
    }

    @Override
    public View getVideoLoadingProgressView() {
      if (mVideoProgressView == null) {
        LayoutInflater inflater = LayoutInflater.from(getContext());
        mVideoProgressView =
          inflater.inflate(R.layout.video_loading_progress, null);
      }

      return mVideoProgressView;
    }

    @Override
    public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
      Log.d(LOGTAG, message);
      return false;
    }
  }

  public interface OnExpandListener {
    public void onExpand(MraidView view);
  }

  public interface OnCloseListener {
    public void onClose(MraidView view, ViewState newViewState);
  }

  public interface OnReadyListener {
    public void onReady(MraidView view);
  }

  public interface OnFailureListener {
    public void onFailure(MraidView view);
  }

  public interface OnCloseButtonStateChangeListener {
    public void onCloseButtonStateChange(MraidView view, boolean enabled);
  }

  public interface OnOpenListener {
    public void onOpen(MraidView view);
  }
}




Java Source Code List

ru.wapstart.plus1.bart.BartActivity.java
ru.wapstart.plus1.sdk.AdView.java
ru.wapstart.plus1.sdk.ApplicationBrowser.java
ru.wapstart.plus1.sdk.Base64.java
ru.wapstart.plus1.sdk.BaseAdView.java
ru.wapstart.plus1.sdk.BaseRequestLoader.java
ru.wapstart.plus1.sdk.Constants.java
ru.wapstart.plus1.sdk.HtmlBannerDownloader.java
ru.wapstart.plus1.sdk.InitRequestLoader.java
ru.wapstart.plus1.sdk.JsonHelper.java
ru.wapstart.plus1.sdk.MraidAbstractController.java
ru.wapstart.plus1.sdk.MraidBrowserController.java
ru.wapstart.plus1.sdk.MraidCommandRegistry.java
ru.wapstart.plus1.sdk.MraidCommand.java
ru.wapstart.plus1.sdk.MraidDisplayController.java
ru.wapstart.plus1.sdk.MraidProperty.java
ru.wapstart.plus1.sdk.MraidView.java
ru.wapstart.plus1.sdk.Plus1AdAnimator.java
ru.wapstart.plus1.sdk.Plus1BannerAsker.java
ru.wapstart.plus1.sdk.Plus1BannerDownloadListener.java
ru.wapstart.plus1.sdk.Plus1BannerView.java
ru.wapstart.plus1.sdk.Plus1Helper.java
ru.wapstart.plus1.sdk.Plus1Request.java