Hello I am making a webview app for my website. That site have a file chooser, upto lollipop, uploading working, no problem, in manifest I have given read external storage permission, but I know new marshmallow need request permission show. So how to implement that (ask user to allow read external storage for file upload) in this activity, suppose this is my main activity for upload page webview. Main2Activity is that activity page which deals with upload page webview
Main2Activity.java code:
package com.mywebsite.mywebsite;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
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 Main2Activity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener{
WebView webView;
private static final String TAG = Main2Activity.class.getSimpleName();
private String mCM;
private ValueCallback<Uri> mUM;
private ValueCallback<Uri[]> mUMA;
private final static int FCR=1;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent){
super.onActivityResult(requestCode, resultCode, intent);
if(Build.VERSION.SDK_INT >= 21){
Uri[] results = null;
//Check if response is positive
if(resultCode== Activity.RESULT_OK){
if(requestCode == FCR){
if(null == mUMA){
return;
}
if(intent == null){
//Capture Photo if no image available
if(mCM != null){
results = new Uri[]{Uri.parse(mCM)};
}
}else{
String dataString = intent.getDataString();
if(dataString != null){
results = new Uri[]{Uri.parse(dataString)};
}
}
}
}
mUMA.onReceiveValue(results);
mUMA = null;
}else{
if(requestCode == FCR){
if(null == mUM) return;
Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData();
mUM.onReceiveValue(result);
mUM = null;
}
}
}
@SuppressLint({"SetJavaScriptEnabled", "WrongViewCast"})
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
//new code start
Toolbar toolbar2 = (Toolbar) findViewById(R.id.toolbar2);
setSupportActionBar(toolbar2);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout2);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar2, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view2);
navigationView.setNavigationItemSelectedListener(this);
//new code end
webView = (WebView) findViewById(R.id.main2);
assert webView != null;
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccess(true);
if(Build.VERSION.SDK_INT >= 21){
webSettings.setMixedContentMode(0);
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}else 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.setWebViewClient(new Callback());
webView.setWebViewClient(new CustomWebViewClient());
webView.loadUrl("http://path to upload page");
webView.setWebChromeClient(new WebChromeClient(){
//For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg){
mUM = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
Main2Activity.this.startActivityForResult(Intent.createChooser(i,"File Chooser"), FCR);
}
// For Android 3.0+, above method not supported in some android 3+ versions, in such case we use this
public void openFileChooser(ValueCallback uploadMsg, String acceptType){
mUM = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
Main2Activity.this.startActivityForResult(
Intent.createChooser(i, "File Browser"),
FCR);
}
//For Android 4.1+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
mUM = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
Main2Activity.this.startActivityForResult(Intent.createChooser(i, "File Chooser"), Main2Activity.FCR);
}
//For Android 5.0+
public boolean onShowFileChooser(
WebView webView, ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams){
if(mUMA != null){
mUMA.onReceiveValue(null);
}
mUMA = filePathCallback;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if(takePictureIntent.resolveActivity(Main2Activity.this.getPackageManager()) != null){
File photoFile = null;
try{
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCM);
}catch(IOException ex){
Log.e(TAG, "Image file creation failed", ex);
}
if(photoFile != null){
mCM = "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, FCR);
return true;
}
});
}
//new code start
@Override
public boolean onCreateOptionsMenu(Menu menu2) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main2, menu2);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings2) {
Intent i = new Intent(Main2Activity.this, MainActivity.class);
startActivity(i);
}
return super.onOptionsItemSelected(item);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_local) {
// Handle the camera action
webView.loadUrl("http://example.com/index.php?/category/1&mobile=true");
} else if (id == R.id.nav_spices2) {
webView.loadUrl("http://example.com/index.php?/category/84&mobile=true");
} else if (id == R.id.nav_vherbarium2) {
webView.loadUrl("http://example.com/index.php?/category/36&mobile=true");
} else if (id == R.id.nav_usersupload2) {
webView.loadUrl("http://example.com/index.php?/category/user&mobile=true");
} else if (id == R.id.nav_recent2) {
webView.loadUrl("http://example.com/index.php?/recent_pics&mobile=true");
} else if (id == R.id.nav_login2) {
webView.loadUrl("http://example.com/identification.php?mobile=true");
} else if (id == R.id.nav_register2) {
webView.loadUrl("http://example.com/register.php?mobile=true");
} else if (id == R.id.nav_search2) {
webView.loadUrl("http://example.com/search.php?mobile=true");
} else if (id == R.id.nav_contact2) {
webView.loadUrl("http://example.com/index.php?/contact/&mobile=true");
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout2);
drawer.closeDrawer(GravityCompat.START);
return true;
}
public class CustomWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
if(url.contains("something")) return true;
return false; //Default is to not override unless our condition is met.
}
public void onPageFinished(WebView webView, String url) {
String webUrl = webView.getUrl();
System.out.println(webUrl);
if(url.startsWith("http://example/oAuth/auth.php?provider=Facebook&openid_identifier=&init_auth=1#_=_")){
String redirectUrl = "http:/// link to upload page.php";
webView.loadUrl(redirectUrl);
return;
}
super.onPageFinished(webView, url);
}
}
//new code end
public class Callback extends WebViewClient {
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl){
Toast.makeText(getApplicationContext(), "Failed loading app! Check internet connection", Toast.LENGTH_SHORT).show();
}
}
// Create an image file
private File createImageFile() throws IOException{
@SuppressLint("SimpleDateFormat") String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "img_"+timeStamp+"_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
return File.createTempFile(imageFileName,".jpg",storageDir);
}
@Override
public boolean onKeyDown(int keyCode, @NonNull KeyEvent event){
if(event.getAction() == KeyEvent.ACTION_DOWN){
switch(keyCode){
case KeyEvent.KEYCODE_BACK:
if(webView.canGoBack()){
webView.goBack();
}else{
finish();
}
return true;
}
}
return super.onKeyDown(keyCode, event);
}
@Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
}
}
Check permissions like so (source):
Also implement the permission callback:
For easier permission handling across all Android versions, check out this awesome third party library called PermissionsDispatcher by Hotchemi.