Back to project page android-sdk.
The source code is released under:
Copyright (c) 2013 Adcash OU. All rights reserved under Creative Commons Attribution 3.0 Unported http://creativecommons.org/licenses/by/3.0/ Redistribution and use in source and binary forms, with or...
If you think the Android project 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.
/* * Copyright (c) 2010-2013, Adcash OU./* w ww.j a v a 2 s. com*/ * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of 'MoPub Inc.' nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.adcash.mobileads; import android.annotation.SuppressLint; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.net.Uri; import android.os.Build; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.webkit.WebSettings.ZoomDensity; import android.webkit.WebView; import android.webkit.WebViewClient; import com.adcash.mobileads.factories.HttpClientFactory; import com.adcash.mobileads.resource.MraidJavascript; import com.adcash.mobileads.util.Strings; 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 java.io.*; import java.net.URI; import java.util.*; import static com.adcash.mobileads.MraidCommandFactory.MraidJavascriptCommand; import static com.adcash.mobileads.ViewGestureDetector.UserClickListener; public class MraidView extends BaseWebView implements UserClickListener { private static final String LOGTAG = "MraidView"; private MraidBrowserController mBrowserController; private MraidDisplayController mDisplayController; private WebViewClient mWebViewClient; private boolean mHasFiredReadyEvent; private boolean mClicked; private final PlacementType mPlacementType; private ViewGestureDetector mViewGestureDetector; private AdConfiguration mAdConfiguration; static class MraidListenerInfo { private MraidListener mMraidListener; private OnCloseButtonStateChangeListener mOnCloseButtonListener; private OnOpenListener mOnOpenListener; } private MraidListenerInfo mListenerInfo; public enum ViewState { LOADING, DEFAULT, EXPANDED, HIDDEN } public enum ExpansionStyle { ENABLED, DISABLED } public enum NativeCloseButtonStyle { ALWAYS_VISIBLE, ALWAYS_HIDDEN, AD_CONTROLLED } public enum PlacementType { INLINE, INTERSTITIAL } public MraidView(Context context, AdConfiguration adConfiguration) { this(context, adConfiguration, ExpansionStyle.ENABLED, NativeCloseButtonStyle.AD_CONTROLLED, PlacementType.INLINE); } public MraidView(Context context, AdConfiguration adConfiguration, ExpansionStyle expStyle, NativeCloseButtonStyle buttonStyle, PlacementType placementType) { super(context); mPlacementType = placementType; mAdConfiguration = adConfiguration; mViewGestureDetector = new ViewGestureDetector(context, this, adConfiguration); mViewGestureDetector.setUserClickListener(this); initialize(expStyle, buttonStyle); } @Override public void onUserClick() { mClicked = true; } @Override public void onResetUserClick() { mClicked = false; } @Override public boolean wasClicked() { return mClicked; } @SuppressLint("NewApi") private void initialize(ExpansionStyle expStyle, NativeCloseButtonStyle buttonStyle) { setScrollContainer(false); // setBackgroundColor(Color.argb(1, 255, 255, 255)); setBackgroundColor(Color.TRANSPARENT); setVerticalScrollBarEnabled(false); setHorizontalScrollBarEnabled(false); setOnTouchListener(new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { mViewGestureDetector.sendTouchEvent(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_UP: if (!v.hasFocus()) { v.requestFocus(); } break; } return false; } }); getSettings().setJavaScriptEnabled(true); getSettings().setSupportZoom(true); getSettings().setBuiltInZoomControls(false); getSettings().setUseWideViewPort(true); getSettings().setLoadWithOverviewMode(true); mBrowserController = new MraidBrowserController(this); mDisplayController = new MraidDisplayController(this, expStyle, buttonStyle); mWebViewClient = new MraidWebViewClient(); setWebViewClient(mWebViewClient); mListenerInfo = new MraidListenerInfo(); } AdConfiguration getAdConfiguration() { return mAdConfiguration; } @Override public void destroy() { mDisplayController.destroy(); super.destroy(); } public void loadHtmlData(String data) { if (data == null) { return; } // If the string data lacks the HTML boilerplate, add it. if (!data.contains("<html>")) { data = "<html><head></head><body style='margin:0;padding:0;'>" + data + "</body></html>"; } // Inject the MRAID JavaScript bridge. data = data.replace("<head>", "<head><script>" + MraidJavascript.JAVASCRIPT_SOURCE + "</script>"); loadDataWithBaseURL(null, data, "text/html", "UTF-8", null); } @Override public void loadUrl(String url) { if (url == null) { return; } if (url.startsWith("javascript:")) { super.loadUrl(url); return; } HttpClient httpClient = HttpClientFactory.create(); String outString = ""; try { HttpGet httpGet = new HttpGet(url); HttpResponse response = httpClient.execute(httpGet); HttpEntity entity = response.getEntity(); if (entity != null) { outString = Strings.fromStream(entity.getContent()); } } catch (IllegalArgumentException e) { Log.d("Adcash", "Mraid loadUrl failed (IllegalArgumentException): "+url); notifyOnFailureListener(); return; } catch (ClientProtocolException e) { notifyOnFailureListener(); return; } catch (IOException e) { notifyOnFailureListener(); return; } loadHtmlData(outString); } private void notifyOnFailureListener() { if (mListenerInfo.mMraidListener != null) { mListenerInfo.mMraidListener.onFailure(this); } } // Controllers ///////////////////////////////////////////////////////////////////////////////// protected MraidBrowserController getBrowserController() { return mBrowserController; } protected MraidDisplayController getDisplayController() { return mDisplayController; } // Listeners /////////////////////////////////////////////////////////////////////////////////// public void setMraidListener(MraidListener mraidListener) { mListenerInfo.mMraidListener = mraidListener; } public MraidListener getMraidListener() { return mListenerInfo.mMraidListener; } 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(MraidJavascriptCommand mraidJavascriptCommand, String message) { String action = mraidJavascriptCommand.getCommand(); 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 = MraidCommandFactory.create(commandType, params, this); if (command == null) { fireNativeCommandCompleteEvent(commandType); return false; // } else if (command.isCommandDependentOnUserClick(mPlacementType) && !wasClicked()) { // return false; } else { command.execute(); fireNativeCommandCompleteEvent(commandType); return true; } } 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("adcash")) return true; if (scheme.equals("mraid")) { tryCommand(URI.create(url)); // java.net.URI, not android.net.Uri return true; } if ((!scheme.equals("http") && !scheme.equals("https")) || wasClicked()) { 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); if (!wasClicked() && scheme.equals("market")) { getDisplayController().close(); } return true; } catch (ActivityNotFoundException e) { return false; } } // view.loadUrl(url); return false; } @Override public void onPageFinished(WebView view, String url) { if (!mHasFiredReadyEvent) { mDisplayController.initializeJavaScriptState(); fireChangeEventForProperty(MraidPlacementTypeProperty.createWithType(mPlacementType)); fireReadyEvent(); if (getMraidListener() != null) { getMraidListener().onReady(MraidView.this); } mHasFiredReadyEvent = true; } } @Override public void onLoadResource(WebView view, String url) { Log.d(LOGTAG, "Loaded resource: " + url); } } public interface MraidListener { public void onReady(MraidView view); public void onFailure(MraidView view); public void onExpand(MraidView view); public void onClose(MraidView view, ViewState newViewState); } public static class BaseMraidListener implements MraidListener { @Override public void onReady(MraidView view) { } @Override public void onFailure(MraidView view) { } @Override public void onExpand(MraidView view) { } @Override public void onClose(MraidView view, ViewState newViewState) { } } public interface OnCloseButtonStateChangeListener { public void onCloseButtonStateChange(MraidView view, boolean enabled); } public interface OnOpenListener { public void onOpen(MraidView view); } @Deprecated // for testing WebViewClient getMraidWebViewClient() { return mWebViewClient; } @Deprecated // for testing void setMraidDisplayController(MraidDisplayController mraidDisplayController) { mDisplayController = mraidDisplayController; } }