Skip to content

Instantly share code, notes, and snippets.

@yuya
Last active August 29, 2015 14:08
Show Gist options
  • Save yuya/699a0adba932e33cc60e to your computer and use it in GitHub Desktop.
Save yuya/699a0adba932e33cc60e to your computer and use it in GitHub Desktop.
Android WebView で GeoLocation 許可
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="im.yuya.unitywebview"
android:installLocation="preferExternal"
android:theme="@android:style/Theme.NoTitleBar"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application android:icon="@drawable/app_icon"
android:label="@string/app_name"
android:debuggable="true"
android:hardwareAccelerated="true">
<activity android:name="com.unity3d.player.UnityPlayerNativeActivity"
android:label="@string/app_name"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
<meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />
</activity>
</application>
</manifest>
/*
* Copyright (C) 2011 Keijiro Takahashi
* Copyright (C) 2012 GREE, Inc.
* Copyright (C) 2014 Yuya Hashimoto
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
package im.yuya.unitywebviewplugin;
import com.unity3d.player.UnityPlayer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.net.Uri;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.JsResult;
import android.webkit.GeolocationPermissions.Callback;
public class WebViewPlugin {
private WebView webView;
private String gameObjectName;
private String customScheme;
private Pattern customSchemeRe;
private static FrameLayout layout = null;
private class WebViewClientNetworkHook extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (Uri.parse(url).getScheme().toString().equals(customScheme)) {
ShiftQueue();
}
return false;
}
public void onPageFinished(WebView view, String url) {
UnityPlayer.UnitySendMessage(gameObjectName, "DetectNetworkStatus", "pass");
}
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
if (!Uri.parse(failingUrl).getScheme().toString().equals(customScheme)) {
UnityPlayer.UnitySendMessage(gameObjectName, "DetectNetworkStatus", "fail");
}
}
}
private class WebChromeClientAlertHook extends WebChromeClient {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
if (customSchemeRe == null) {
return false;
}
Matcher matcher = customSchemeRe.matcher(message);
if (matcher.lookingAt() || message.equals("undefined")) {
if (matcher.lookingAt()) {
UnityPlayer.UnitySendMessage(gameObjectName, "HandleMessage", matcher.replaceFirst(""));
}
try {
return true;
}
finally {
result.confirm();
}
}
else {
return false;
}
}
}
public WebViewPlugin() {}
@SuppressLint("SetJavaScriptEnabled")
public void Init(final String name, final String userAgent) {
final Activity activity = UnityPlayer.currentActivity;
gameObjectName = name;
customScheme = "webviewbridge";
customSchemeRe = Pattern.compile("^" + customScheme + ":\\/\\/");
activity.runOnUiThread(new Runnable() {
@SuppressWarnings("deprecation")
public void run() {
webView = new WebView(activity);
WebSettings webSettings = webView.getSettings();
if (userAgent != null) {
String defaultUAStr = webSettings.getUserAgentString();
String customUAStr = defaultUAStr + " " + userAgent;
webSettings.setUserAgentString(customUAStr);
}
webView.setVisibility(View.GONE);
webView.setFocusable(true);
webView.setFocusableInTouchMode(true);
webView.setVerticalScrollbarOverlay(true);
webView.setWebViewClient(new WebViewClientNetworkHook());
webView.setWebChromeClient(new WebChromeClientAlertHook());
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {
callback.invoke(origin, true, false);
}
});
webSettings.setSupportZoom(false);
webSettings.setJavaScriptEnabled(true);
if (layout == null) {
layout = new FrameLayout(activity);
activity.addContentView(layout, new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)
);
layout.setFocusable(true);
layout.setFocusableInTouchMode(true);
}
layout.addView(webView, new FrameLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT,
Gravity.NO_GRAVITY)
);
}
});
}
public void Destroy() {
Activity activity = UnityPlayer.currentActivity;
activity.runOnUiThread(new Runnable() {
public void run() {
if (webView != null) {
layout.removeView(webView);
webView.setWebViewClient(null);
webView.setWebChromeClient(null);
webView.destroy();
webView = null;
}
}
});
}
public void LoadURL(final String url) {
final Activity activity = UnityPlayer.currentActivity;
activity.runOnUiThread(new Runnable() {
public void run() {
if (webView != null) {
webView.loadUrl(url);
}
}
});
}
public void EvaluteJs(final String str) {
final Activity activity = UnityPlayer.currentActivity;
activity.runOnUiThread(new Runnable() {
public void run() {
if (webView != null) {
webView.loadUrl("javascript:" + str);
}
}
});
}
public void SetVisibility(final boolean visibility) {
Activity activity = UnityPlayer.currentActivity;
activity.runOnUiThread(new Runnable() {
public void run() {
if (webView != null) {
if (visibility) {
webView.setVisibility(View.VISIBLE);
layout.requestFocus();
webView.requestFocus();
}
else {
webView.setVisibility(View.GONE);
}
}
}
});
}
public void SetMargins(int left, int top, int right, int bottom) {
@SuppressWarnings("deprecation")
final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, Gravity.NO_GRAVITY);
Activity activity = UnityPlayer.currentActivity;
params.setMargins(left, top, right, bottom);
activity.runOnUiThread(new Runnable() {
public void run() {
if (webView != null) {
webView.setLayoutParams(params);
}
}
});
}
private void ShiftQueue() {
String message = "javascript: (typeof WebViewMediator !== 'undefined') ? alert(WebViewMediator.ShiftQueue()) : void(0)";
if (webView != null) {
webView.loadUrl(message);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment