Created
October 31, 2017 17:52
-
-
Save mksantoki/097bb1fa73af1f404acc02bb594cd743 to your computer and use it in GitHub Desktop.
FileChooser in Android webview
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
reference link ->https://www.opengeeks.me/2015/08/filechooser-and-android-webview/ | |
https://github.com/OpenGeeksMe/Android-File-Chooser | |
*/ | |
import android.app.Activity; | |
import android.app.ProgressDialog; | |
import android.content.Intent; | |
import android.graphics.Bitmap; | |
import android.net.Uri; | |
import android.os.Build; | |
import android.os.Bundle; | |
import android.os.Environment; | |
import android.os.Parcelable; | |
import android.provider.MediaStore; | |
import android.support.v7.app.ActionBarActivity; | |
import android.util.Log; | |
import android.view.KeyEvent; | |
import android.view.View; | |
import android.webkit.ValueCallback; | |
import android.webkit.WebChromeClient; | |
import android.webkit.WebSettings; | |
import android.webkit.WebView; | |
import android.webkit.WebViewClient; | |
import android.widget.Toast; | |
import java.io.File; | |
import java.io.IOException; | |
import java.text.SimpleDateFormat; | |
import java.util.Date; | |
public class MainActivity extends ActionBarActivity { | |
private static final int INPUT_FILE_REQUEST_CODE = 1; | |
private static final int FILECHOOSER_RESULTCODE = 1; | |
private static final String TAG = MainActivity.class.getSimpleName(); | |
private WebView webView; | |
private WebSettings webSettings; | |
private ValueCallback<Uri> mUploadMessage; | |
private Uri mCapturedImageURI = null; | |
private ValueCallback<Uri[]> mFilePathCallback; | |
private String mCameraPhotoPath; | |
@Override | |
public void onActivityResult(int requestCode, int resultCode, Intent data) { | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |
if (requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) { | |
super.onActivityResult(requestCode, resultCode, data); | |
return; | |
} | |
Uri[] results = null; | |
// Check that the response is a good one | |
if (resultCode == Activity.RESULT_OK) { | |
if (data == null) { | |
// If there is not data, then we may have taken a photo | |
if (mCameraPhotoPath != null) { | |
results = new Uri[]{Uri.parse(mCameraPhotoPath)}; | |
} | |
} else { | |
String dataString = data.getDataString(); | |
if (dataString != null) { | |
results = new Uri[]{Uri.parse(dataString)}; | |
} | |
} | |
} | |
mFilePathCallback.onReceiveValue(results); | |
mFilePathCallback = null; | |
} else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { | |
if (requestCode != FILECHOOSER_RESULTCODE || mUploadMessage == null) { | |
super.onActivityResult(requestCode, resultCode, data); | |
return; | |
} | |
if (requestCode == FILECHOOSER_RESULTCODE) { | |
if (null == this.mUploadMessage) { | |
return; | |
} | |
Uri result = null; | |
try { | |
if (resultCode != RESULT_OK) { | |
result = null; | |
} else { | |
// retrieve from the private variable if the intent is null | |
result = data == null ? mCapturedImageURI : data.getData(); | |
} | |
} catch (Exception e) { | |
Toast.makeText(getApplicationContext(), "activity :" + e, | |
Toast.LENGTH_LONG).show(); | |
} | |
mUploadMessage.onReceiveValue(result); | |
mUploadMessage = null; | |
} | |
} | |
return; | |
} | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
webView = (WebView) findViewById(R.id.webview); | |
webSettings = webView.getSettings(); | |
webSettings.setJavaScriptEnabled(true); | |
webSettings.setLoadWithOverviewMode(true); | |
webSettings.setAllowFileAccess(true); | |
webView.setWebViewClient(new Client()); | |
webView.setWebChromeClient(new ChromeClient()); | |
if (Build.VERSION.SDK_INT >= 19) { | |
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null); | |
} | |
else if(Build.VERSION.SDK_INT >=11 && Build.VERSION.SDK_INT < 19) { | |
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); | |
} | |
webView.loadUrl("http://example.com"); //change with your website | |
} | |
private File createImageFile() throws IOException { | |
// Create an image file name | |
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); | |
String imageFileName = "JPEG_" + timeStamp + "_"; | |
File storageDir = Environment.getExternalStoragePublicDirectory( | |
Environment.DIRECTORY_PICTURES); | |
File imageFile = File.createTempFile( | |
imageFileName, /* prefix */ | |
".jpg", /* suffix */ | |
storageDir /* directory */ | |
); | |
return imageFile; | |
} | |
public class ChromeClient extends WebChromeClient { | |
// For Android 5.0 | |
public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) { | |
// Double check that we don't have any existing callbacks | |
if (mFilePathCallback != null) { | |
mFilePathCallback.onReceiveValue(null); | |
} | |
mFilePathCallback = filePath; | |
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); | |
if (takePictureIntent.resolveActivity(getPackageManager()) != null) { | |
// Create the File where the photo should go | |
File photoFile = null; | |
try { | |
photoFile = createImageFile(); | |
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath); | |
} catch (IOException ex) { | |
// Error occurred while creating the File | |
Log.e(TAG, "Unable to create Image File", ex); | |
} | |
// Continue only if the File was successfully created | |
if (photoFile != null) { | |
mCameraPhotoPath = "file:" + photoFile.getAbsolutePath(); | |
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, | |
Uri.fromFile(photoFile)); | |
} else { | |
takePictureIntent = null; | |
} | |
} | |
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT); | |
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE); | |
contentSelectionIntent.setType("image/*"); | |
Intent[] intentArray; | |
if (takePictureIntent != null) { | |
intentArray = new Intent[]{takePictureIntent}; | |
} else { | |
intentArray = new Intent[0]; | |
} | |
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER); | |
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent); | |
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser"); | |
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray); | |
startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE); | |
return true; | |
} | |
// openFileChooser for Android 3.0+ | |
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) { | |
mUploadMessage = uploadMsg; | |
// Create AndroidExampleFolder at sdcard | |
// Create AndroidExampleFolder at sdcard | |
File imageStorageDir = new File( | |
Environment.getExternalStoragePublicDirectory( | |
Environment.DIRECTORY_PICTURES) | |
, "AndroidExampleFolder"); | |
if (!imageStorageDir.exists()) { | |
// Create AndroidExampleFolder at sdcard | |
imageStorageDir.mkdirs(); | |
} | |
// Create camera captured image file path and name | |
File file = new File( | |
imageStorageDir + File.separator + "IMG_" | |
+ String.valueOf(System.currentTimeMillis()) | |
+ ".jpg"); | |
mCapturedImageURI = Uri.fromFile(file); | |
// Camera capture image intent | |
final Intent captureIntent = new Intent( | |
android.provider.MediaStore.ACTION_IMAGE_CAPTURE); | |
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI); | |
Intent i = new Intent(Intent.ACTION_GET_CONTENT); | |
i.addCategory(Intent.CATEGORY_OPENABLE); | |
i.setType("image/*"); | |
// Create file chooser intent | |
Intent chooserIntent = Intent.createChooser(i, "Image Chooser"); | |
// Set camera intent to file chooser | |
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS | |
, new Parcelable[] { captureIntent }); | |
// On select image call onActivityResult method of activity | |
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE); | |
} | |
// openFileChooser for Android < 3.0 | |
public void openFileChooser(ValueCallback<Uri> uploadMsg) { | |
openFileChooser(uploadMsg, ""); | |
} | |
//openFileChooser for other Android versions | |
public void openFileChooser(ValueCallback<Uri> uploadMsg, | |
String acceptType, | |
String capture) { | |
openFileChooser(uploadMsg, acceptType); | |
} | |
} | |
public boolean onKeyDown(int keyCode, KeyEvent event) { | |
// Check if the key event was the Back button and if there's history | |
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) { | |
webView.goBack(); | |
return true; | |
} | |
// If it wasn't the Back key or there's no web page history, bubble up to the default | |
// system behavior (probably exit the activity) | |
return super.onKeyDown(keyCode, event); | |
} | |
public class Client extends WebViewClient { | |
ProgressDialog progressDialog; | |
public boolean shouldOverrideUrlLoading(WebView view, String url) { | |
// If url contains mailto link then open Mail Intent | |
if (url.contains("mailto:")) { | |
// Could be cleverer and use a regex | |
//Open links in new browser | |
view.getContext().startActivity( | |
new Intent(Intent.ACTION_VIEW, Uri.parse(url))); | |
// Here we can open new activity | |
return true; | |
}else { | |
// Stay within this webview and load url | |
view.loadUrl(url); | |
return true; | |
} | |
} | |
//Show loader on url load | |
public void onPageStarted(WebView view, String url, Bitmap favicon) { | |
// Then show progress Dialog | |
// in standard case YourActivity.this | |
if (progressDialog == null) { | |
progressDialog = new ProgressDialog(MainActivity.this); | |
progressDialog.setMessage("Loading..."); | |
progressDialog.show(); | |
} | |
} | |
// Called when all page resources loaded | |
public void onPageFinished(WebView view, String url) { | |
try { | |
// Close progressDialog | |
if (progressDialog.isShowing()) { | |
progressDialog.dismiss(); | |
progressDialog = null; | |
} | |
} catch (Exception exception) { | |
exception.printStackTrace(); | |
} | |
} | |
} | |
} |
Thank you very much. Can confirm it still works!
This piece of code made an app crash upon startup:
if (Build.VERSION.SDK_INT >= 19) { webView.setLayerType(View.LAYER_TYPE_HARDWARE, null); } else if(Build.VERSION.SDK_INT >=11 && Build.VERSION.SDK_INT < 19) { webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); }
So I removed it, and it works.
Hey thats working great, thank you.
That's a lot of code for just having an input[type="file"]
work no?
The photo is uploaded ready to go. The camera opens and takes a photo, but the photo is not uploaded to the website
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
thank you.