<resources>
<string name="webview_file_chooser_title">Choose a file</string>
<string name="webview_image_chooser_title">Choose an image</string>
<string name="webview_video_chooser_title">Choose a video</string>
</resources>
import android.net.Uri;
import android.webkit.ValueCallback;
@Override
public boolean onShowFileChooser(
WebView webView,
ValueCallback<Uri[]> filePathCallback,
FileChooserParams fileChooserParams) {
// info as of 2021-03-08:
// don't use fileChooserParams.getTitle() as it is (always? on Mi 9T Pro Android 10 at least) null
// don't use fileChooserParams.isCaptureEnabled() as it is (always? on Mi 9T Pro Android 10 at least) false, even when the file upload allows images or any file
final Context context = webView.getContext();
final boolean allowMultipleFiles = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
&& fileChooserParams.getMode() == FileChooserParams.MODE_OPEN_MULTIPLE;
final String[] acceptTypes = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP
? fileChooserParams.getAcceptTypes() : new String[0];
new FileChooserLauncher(context, allowMultipleFiles, filePathCallback, acceptTypes)
.start();
return true;
}
package io.flutter.plugins.webviewflutter;
import androidx.core.content.FileProvider;
public class GenericFileProvider extends FileProvider {
public static final String PROVIDER_NAME = "io.flutter.plugins.webviewflutter.GenericFileProvider";
}
11. input file 클릭시 카메라로 직접 사진을 찍어 파일을 올리게 하려면 원래 flutter project에서 android/app/src/main/AndroidManifest.xml 에 <uses-permission android:name="android.permission.CAMERA"/> 권한을 추가한다. (선택)
import java.util.Collections;
import java.util.Properties;
import java.util.Set;
import org.springframework.beans.factory.config.YamlProcessor.DocumentMatcher;
import org.springframework.beans.factory.config.YamlProcessor.MatchStatus;
import org.springframework.util.StringUtils;
/**
* Matches a document containing a given key and where the value of that key is an array
* containing one of the given values, or where one of the values matches one of the given
* values (interpreted as regexes).
*
* @author Dave Syer
* @deprecated as of 1.4.1 in favor of exact String-based matching
*/
@Deprecated
public class ArrayDocumentMatcher implements DocumentMatcher {
private final String key;
private final String[] patterns;
public ArrayDocumentMatcher(final String key, final String... patterns) {
this.key = key;
this.patterns = patterns;
}
@Override
public MatchStatus matches(Properties properties) {
if (!properties.containsKey(this.key)) {
return MatchStatus.ABSTAIN;
}
Set<String> values = StringUtils
.commaDelimitedListToSet(properties.getProperty(this.key));
if (values.isEmpty()) {
values = Collections.singleton("");
}
for (String pattern : this.patterns) {
for (String value : values) {
if (value.matches(pattern)) {
return MatchStatus.FOUND;
}
}
}
return MatchStatus.NOT_FOUND;
}
}
4. SpringProfileDocumentMatcher.java를 추가한다.
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Properties;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.YamlProcessor.DocumentMatcher;
import org.springframework.beans.factory.config.YamlProcessor.MatchStatus;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
public class SpringProfileDocumentMatcher implements DocumentMatcher, EnvironmentAware, ApplicationContextAware {
private ApplicationContext ctx;
private static final String[] DEFAULT_PROFILES = new String[] {"local"};
private String[] activeProfiles = new String[0];
public SpringProfileDocumentMatcher() {}
@Override
public void setEnvironment(Environment environment) {
if (environment != null) {
addActiveProfiles(environment.getActiveProfiles());
}
}
public void addActiveProfiles(String... profiles) {
LinkedHashSet<String> set = new LinkedHashSet<String>(Arrays.asList(this.activeProfiles));
Collections.addAll(set, profiles);
this.activeProfiles = set.toArray(new String[set.size()]);
}
@Bean(name = "yamlProperties")
public YamlPropertiesFactoryBean yamlPropertiesFactoryBean() throws IOException {
YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();
yamlPropertiesFactoryBean.setResources(ctx.getResources("classpath:application.yml"));
return yamlPropertiesFactoryBean;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.ctx = applicationContext;
}
@Override
public MatchStatus matches(Properties properties) {
String[] profiles = this.activeProfiles;
if (profiles.length == 0) {
try {
String activeProfile = yamlPropertiesFactoryBean().getObject().getProperty("spring.profiles.active");
if (activeProfile != null && activeProfile != "") {
profiles = new String[] { activeProfile };
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (profiles.length == 0) {
profiles = DEFAULT_PROFILES;
}
}
return new ArrayDocumentMatcher("spring.profiles", profiles).matches(properties);
}
}