This repository has been archived by the owner on Apr 24, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 376
/
MainFragment.java
231 lines (199 loc) · 7.97 KB
/
MainFragment.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/*
* Copyright (C) 2010 The Android Open Source Project
*
* 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 jsinterfacesample.android.chrome.google.com.jsinterface_example;
import android.annotation.TargetApi;
import android.app.Fragment;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.util.JsonReader;
import android.util.JsonToken;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.ValueCallback;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import java.io.IOException;
import java.io.StringReader;
/**
* Created by mattgaunt on 10/16/14.
*/
public class MainFragment extends Fragment {
public static final String EXTRA_FROM_NOTIFICATION = "EXTRA_FROM_NOTIFICATION";
private WebView mWebView;
public MainFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
// Get reference of WebView from layout/activity_main.xml
mWebView = (WebView) rootView.findViewById(R.id.fragment_main_webview);
// Add Javascript Interface, this will expose "window.NotificationBind"
// in Javascript
mWebView.addJavascriptInterface(
new NotificationBindObject(getActivity().getApplicationContext()),
"NotificationBind");
setUpWebViewDefaults(mWebView);
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore the previous URL and history stack
mWebView.restoreState(savedInstanceState);
}
// Prepare the WebView and get the appropriate URL
String url = prepareWebView(mWebView.getUrl());
// Load the local index.html file
if(mWebView.getUrl() == null) {
mWebView.loadUrl(url);
}
return rootView;
}
/**
* Convenience method to set some generic defaults for a
* given WebView
*
* @param webView
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setUpWebViewDefaults(WebView webView) {
WebSettings settings = webView.getSettings();
// Enable Javascript
settings.setJavaScriptEnabled(true);
// Use WideViewport and Zoom out if there is no viewport defined
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
// Enable pinch to zoom without the zoom buttons
settings.setBuiltInZoomControls(true);
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
// Hide the zoom controls for HONEYCOMB+
settings.setDisplayZoomControls(false);
}
// Enable remote debugging via chrome://inspect
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
}
/**
* This is method where specific logic for this application is going to live
* @return url to load
*/
private String prepareWebView(String currentUrl) {
String hash = "";
int bgColor;
if(currentUrl != null) {
String[] hashSplit = currentUrl.split("#");
if(hashSplit.length == 2) {
hash = hashSplit[1];
}
} else {
Intent intent = getActivity().getIntent();
if(intent != null && intent.getBooleanExtra(EXTRA_FROM_NOTIFICATION, false)) {
hash = "notification-launch";
}
}
if(hash.equals("notification-launch")) {
bgColor = Color.parseColor("#1abc9c");
} else if(hash.equals("notification-shown")) {
bgColor = Color.parseColor("#3498db");
} else if(hash.equals("secret")) {
bgColor = Color.parseColor("#34495e");
} else {
bgColor = Color.parseColor("#f1c40f");
}
preventBGColorFlicker(bgColor);
// We set the WebViewClient to ensure links are consumed by the WebView rather
// than passed to a browser if it can
mWebView.setWebViewClient(new WebViewClient());
return "file:///android_asset/www/index.html#"+hash;
}
/**
* This is a little bit of trickery to make the background color of the UI
* the same as the anticipated UI background color of the web-app.
*
* @param bgColor
*/
private void preventBGColorFlicker(int bgColor) {
((ViewGroup) getActivity().findViewById(R.id.activity_main_container)).setBackgroundColor(bgColor);
mWebView.setBackgroundColor(bgColor);
}
/**
* This method is designed to hide how Javascript is injected into
* the WebView.
*
* In KitKat the new evaluateJavascript method has the ability to
* give you access to any return values via the ValueCallback object.
*
* The String passed into onReceiveValue() is a JSON string, so if you
* execute a javascript method which return a javascript object, you can
* parse it as valid JSON. If the method returns a primitive value, it
* will be a valid JSON object, but you should use the setLenient method
* to true and then you can use peek() to test what kind of object it is,
*
* @param javascript
*/
public void loadJavascript(String javascript) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// In KitKat+ you should use the evaluateJavascript method
mWebView.evaluateJavascript(javascript, new ValueCallback<String>() {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onReceiveValue(String s) {
JsonReader reader = new JsonReader(new StringReader(s));
// Must set lenient to parse single values
reader.setLenient(true);
try {
if(reader.peek() != JsonToken.NULL) {
if(reader.peek() == JsonToken.STRING) {
String msg = reader.nextString();
if(msg != null) {
Toast.makeText(getActivity().getApplicationContext(),
msg, Toast.LENGTH_LONG).show();
}
}
}
} catch (IOException e) {
Log.e("TAG", "MainActivity: IOException", e);
} finally {
try {
reader.close();
} catch (IOException e) {
// NOOP
}
}
}
});
} else {
/**
* For pre-KitKat+ you should use loadUrl("javascript:<JS Code Here>");
* To then call back to Java you would need to use addJavascriptInterface()
* and have your JS call the interface
**/
mWebView.loadUrl("javascript:"+javascript);
}
}
public boolean goBack() {
if(!mWebView.canGoBack()) {
return false;
}
mWebView.goBack();
return true;
}
}