· 6 years ago · Nov 25, 2019, 05:04 AM
1package mgks.os.fileup;
2
3/*
4 * Os-FileUp is an Open Source Android Project hosted on GitHub (https://github.com/mgks/Os-FileUp).
5 * Developed by Ghazi Khan (https://github.com/mgks) under MIT Open Source License.
6 * This program is free to use for private and commercial purposes.
7 * Please mention project source or developer credit in your Application's License(s) Wiki.
8 * Giving right credit to developers encourages them to create better projects :)
9 */
10
11import android.Manifest;
12import android.annotation.SuppressLint;
13import android.app.Activity;
14import android.content.ClipData;
15import android.content.Intent;
16import android.content.pm.PackageManager;
17import android.content.res.Configuration;
18import android.net.Uri;
19import android.os.Build;
20import android.os.Bundle;
21import android.os.Environment;
22import android.provider.MediaStore;
23import android.util.Log;
24import android.view.KeyEvent;
25import android.view.View;
26import android.webkit.GeolocationPermissions;
27import android.webkit.ValueCallback;
28import android.webkit.WebChromeClient;
29import android.webkit.WebSettings;
30import android.webkit.WebView;
31import android.webkit.WebViewClient;
32import android.widget.Toast;
33
34import androidx.annotation.NonNull;
35import androidx.appcompat.app.AppCompatActivity;
36import androidx.core.app.ActivityCompat;
37import androidx.core.content.ContextCompat;
38
39import java.io.File;
40import java.io.IOException;
41import java.text.SimpleDateFormat;
42import java.util.Date;
43
44public class MainActivity extends AppCompatActivity{
45
46 /*-- CUSTOMIZE --*/
47 /*-- you can customize these options for your convenience --*/
48/*
49 private static String webview_url = "file:///android_res/raw/index.html"; // web address or local file location you want to open in webview
50*/
51 private static String webview_url = "https://dvlp.bpjs-kesehatan.go.id/promise_mobile/"; // web address or local file location you want to open in webview
52 private static String file_type = "image/*"; // file types to be allowed for upload
53 private boolean multiple_files = true; // allowing multiple file upload
54
55 /*-- MAIN VARIABLES --*/
56 WebView webView;
57
58 private static final String TAG = MainActivity.class.getSimpleName();
59
60 private String cam_file_data = null; // for storing camera file information
61 private ValueCallback<Uri> file_data; // data/header received after file selection
62 private ValueCallback<Uri[]> file_path; // received file(s) temp. location
63
64 private final static int file_req_code = 1;
65
66 @Override
67 protected void onActivityResult(int requestCode, int resultCode, Intent intent){
68 super.onActivityResult(requestCode, resultCode, intent);
69 if(Build.VERSION.SDK_INT >= 21){
70 Uri[] results = null;
71
72 /*-- if file request cancelled; exited camera. we need to send null value to make future attempts workable --*/
73 if (resultCode == Activity.RESULT_CANCELED) {
74 if (requestCode == file_req_code) {
75 file_path.onReceiveValue(null);
76 return;
77 }
78 }
79
80 /*-- continue if response is positive --*/
81 if(resultCode== Activity.RESULT_OK){
82 if(requestCode == file_req_code){
83 if(null == file_path){
84 return;
85 }
86
87 ClipData clipData;
88 String stringData;
89 try {
90 clipData = intent.getClipData();
91 stringData = intent.getDataString();
92 }catch (Exception e){
93 clipData = null;
94 stringData = null;
95 }
96
97 if (clipData == null && stringData == null && cam_file_data != null) {
98 results = new Uri[]{Uri.parse(cam_file_data)};
99 }else{
100 if (clipData != null) { // checking if multiple files selected or not
101 final int numSelectedFiles = clipData.getItemCount();
102 results = new Uri[numSelectedFiles];
103 for (int i = 0; i < clipData.getItemCount(); i++) {
104 results[i] = clipData.getItemAt(i).getUri();
105 }
106 } else {
107 results = new Uri[]{Uri.parse(stringData)};
108 }
109 }
110 }
111 }
112 file_path.onReceiveValue(results);
113 file_path = null;
114 }else{
115 if(requestCode == file_req_code){
116 if(null == file_data) return;
117 Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData();
118 file_data.onReceiveValue(result);
119 file_data = null;
120 }
121 }
122 }
123
124 @SuppressLint({"SetJavaScriptEnabled", "WrongViewCast"})
125 @Override
126 protected void onCreate(Bundle savedInstanceState){
127 super.onCreate(savedInstanceState);
128 setContentView(R.layout.activity_main);
129
130 webView = (WebView) findViewById(R.id.os_view);
131 assert webView != null;
132 WebSettings webSettings = webView.getSettings();
133 webSettings.setJavaScriptEnabled(true);
134 webSettings.setAllowFileAccess(true);
135
136 if(Build.VERSION.SDK_INT >= 21){
137 webSettings.setMixedContentMode(0);
138 webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
139 }else if(Build.VERSION.SDK_INT >= 19){
140 webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
141 }else {
142 webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
143 }
144 webView.setWebViewClient(new Callback());
145 webView.loadUrl(webview_url);
146 ActivityCompat.requestPermissions(this, new String[]{
147 Manifest.permission.ACCESS_FINE_LOCATION,
148 Manifest.permission.ACCESS_COARSE_LOCATION,
149 Manifest.permission.CAMERA,
150 Manifest.permission.INTERNET,
151 Manifest.permission.READ_EXTERNAL_STORAGE,
152 Manifest.permission.WRITE_EXTERNAL_STORAGE,
153 }, 0);
154
155 webView.setWebChromeClient(new WebChromeClient() {
156 @Override
157 public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
158 callback.invoke(origin, true, false);
159 }
160
161 /*-- handling input[type="file"] requests for android API 21+ --*/
162 public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
163
164 if(file_permission() && Build.VERSION.SDK_INT >= 21) {
165 file_path = filePathCallback;
166 Intent takePictureIntent = null;
167 Intent takeVideoIntent = null;
168
169 boolean includeVideo = false;
170 boolean includePhoto = false;
171
172 /*-- checking the accept parameter to determine which intent(s) to include --*/
173 paramCheck:
174 for (String acceptTypes : fileChooserParams.getAcceptTypes()) {
175 String[] splitTypes = acceptTypes.split(", ?+"); // although it's an array, it still seems to be the whole value; split it out into chunks so that we can detect multiple values
176 for (String acceptType : splitTypes) {
177 switch (acceptType) {
178 case "*/*":
179 includePhoto = true;
180 includeVideo = true;
181 break paramCheck;
182 case "image/*":
183 includePhoto = true;
184 break;
185 case "video/*":
186 includeVideo = true;
187 break;
188 }
189 }
190 }
191
192 if (fileChooserParams.getAcceptTypes().length == 0) { //no `accept` parameter was specified, allow both photo and video
193 includePhoto = true;
194 includeVideo = true;
195 }
196
197 if (includePhoto) {
198 takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
199 if (takePictureIntent.resolveActivity(MainActivity.this.getPackageManager()) != null) {
200 File photoFile = null;
201 try {
202 photoFile = create_image();
203 takePictureIntent.putExtra("PhotoPath", cam_file_data);
204 } catch (IOException ex) {
205 Log.e(TAG, "Image file creation failed", ex);
206 }
207 if (photoFile != null) {
208 cam_file_data = "file:" + photoFile.getAbsolutePath();
209 takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
210 } else {
211 cam_file_data = null;
212 takePictureIntent = null;
213 }
214 }
215 }
216
217 if (includeVideo) {
218 takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
219 if (takeVideoIntent.resolveActivity(MainActivity.this.getPackageManager()) != null) {
220 File videoFile = null;
221 try {
222 videoFile = create_video();
223 } catch (IOException ex) {
224 Log.e(TAG, "Video file creation failed", ex);
225 }
226 if (videoFile != null) {
227 cam_file_data = "file:" + videoFile.getAbsolutePath();
228 takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(videoFile));
229 } else {
230 cam_file_data = null;
231 takeVideoIntent = null;
232 }
233 }
234 }
235
236 Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
237 contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
238 contentSelectionIntent.setType(file_type);
239 if (multiple_files) {
240 contentSelectionIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
241 }
242
243 Intent[] intentArray;
244 if (takePictureIntent != null && takeVideoIntent != null) {
245 intentArray = new Intent[]{takePictureIntent, takeVideoIntent};
246 } else if (takePictureIntent != null) {
247 intentArray = new Intent[]{takePictureIntent};
248 } else if (takeVideoIntent != null) {
249 intentArray = new Intent[]{takeVideoIntent};
250 } else {
251 intentArray = new Intent[0];
252 }
253
254 Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
255 chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
256 chooserIntent.putExtra(Intent.EXTRA_TITLE, "File chooser");
257 chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
258 startActivityForResult(chooserIntent, file_req_code);
259 return true;
260 } else {
261 return false;
262 }
263 }
264 }
265 );
266 }
267
268 /*-- callback reporting if error occurs --*/
269 public class Callback extends WebViewClient{
270 public void onReceivedError(WebView view, int errorCode, String description, String failingUrl){
271 Toast.makeText(getApplicationContext(), "Failed loading app!", Toast.LENGTH_SHORT).show();
272 }
273 }
274
275 /*-- checking and asking for required file permissions --*/
276 public boolean file_permission(){
277 if(Build.VERSION.SDK_INT >=23 && (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)) {
278 ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, 1);
279 return false;
280 }else{
281 return true;
282 }
283 }
284
285 /*-- creating new image file here --*/
286 private File create_image() throws IOException{
287 @SuppressLint("SimpleDateFormat") String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
288 String imageFileName = "img_"+timeStamp+"_";
289 File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
290 return File.createTempFile(imageFileName,".jpg",storageDir);
291 }
292
293 /*-- creating new video file here --*/
294 private File create_video() throws IOException {
295 @SuppressLint("SimpleDateFormat")
296 String file_name = new SimpleDateFormat("yyyy_mm_ss").format(new Date());
297 String new_name = "file_"+file_name+"_";
298 File sd_directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
299 return File.createTempFile(new_name, ".3gp", sd_directory);
300 }
301
302 /*-- back/down key handling --*/
303 @Override
304 public boolean onKeyDown(int keyCode, @NonNull KeyEvent event){
305 if(event.getAction() == KeyEvent.ACTION_DOWN){
306 if (keyCode == KeyEvent.KEYCODE_BACK) {
307 if (webView.canGoBack()) {
308 webView.goBack();
309 } else {
310 finish();
311 }
312 return true;
313 }
314 }
315 return super.onKeyDown(keyCode, event);
316 }
317
318 @Override
319 public void onConfigurationChanged(Configuration newConfig){
320 super.onConfigurationChanged(newConfig);
321 }
322}