画像のアップロードをしたい!
受付中
回答 1
投稿
- 評価
- クリップ 1
- VIEW 455
実現したいこと
WebViewでファイルのアップロードの実装中です。アルバムから画像を選択するというところまでたどり着きましたが、選択した画像の読み込みが出来ません。そこで、onActivityResultを追加しました。現状ここまでは、正常に稼働します!
現状:onCreate → onShowFilleChooser → onAvtivityResult
しかし、選択された画像がアプリに読み込めていません。読み込みをできるようにして、アプリ内で画像のアップロードをできるようにしたいです。
自分で取り組んだこと・考察
現状を考え、選択した画像をアプリに取得させるという部分が抜けているのかと想定しました。
様々なサイトをみる中で下記三点の考えに至っています。
・createImageFileが抜けている?
https://www.zidsworld.com/android-development/make-android-webview-support-file-upload/
https://kotaeta.com/57573104
・getResultUriが抜けている?
https://jq-jo.github.io/blog/2016/10/19/android-camera-gallery/
・特段上記二つは必要ないかもしれない?
https://www.petitmonte.com/java/android_webview_camera.html
しかし、この時点から一人では考察が伸びずにおります。
お分かりの方、是非お助け願います。
コード
public class MainActivity extends AppCompatActivity {
private final static int FCR = 1;
private static final int INPUT_FILE_REQUEST_CODE = 1;
WebView webView;
private String mCM;
private ValueCallback<Uri> mUM;
private ValueCallback<Uri[]> mUMA;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webview);
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)) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, 1);
}
assert webView != null;
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccess(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setUseWideViewPort(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 < 19) {
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
webView.setWebViewClient(new Callback());
webView.loadUrl("https://google.com");
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("*/*");
MainActivity.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("*/*");
MainActivity.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("*/*");
MainActivity.this.startActivityForResult(Intent.createChooser(i, "File Chooser"), MainActivity.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);
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("*/*");
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;
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == INPUT_FILE_REQUEST_CODE) {
ValueCallback mFilePathCallback = null;
if (mFilePathCallback == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
Uri[] results = null;
// Check that the response is a good one
if (resultCode == RESULT_OK) {
String dataString = data.getDataString();
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
//return;
}
}
public class Callback extends WebViewClient {
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Toast.makeText(getApplicationContext(), "Failed loading app!", Toast.LENGTH_SHORT).show();
}
}
}
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
0
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == INPUT_FILE_REQUEST_CODE) {
ValueCallback mFilePathCallback = null;
if (mFilePathCallback == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
mFilePathCallback が null のまま if (mFilePathCallback == null) に入るのですから, super.onActivityResult を実行して return するだけで, それ以降の処理には絶対進みません.
mFilePathCallback に何かを設定しなければいけないのではないでしょうか.
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.19%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2019/10/16 21:24
実現したいことに記載した通り、読み込みをできるようにして、アプリ内で画像のアップロードをできるようにしたいのですが、記載のコードを見る限りどのようにすれば取得が叶いますでしょうか?
2019/10/16 22:33
mFilePathCallback は何をするオブジェクトで, どこで設定されてここに至るのかは, tomtom1 さんが知らなくては意味がありません.
どちらかからコピペされたコードなのでしたら, そのコードでこのオブジェクトがどう扱われているのかをお調べになって, ご理解の上でご自身のプログラムに組み込まれなければならないのではないでしょうか.
ざっと見た所, ValueCallback 型のオブジェクトは WebChromeClient の各メソッド(openFileChooser, onShowFileChooser) のパラメータとして表れています.
openFileChooser のパラメータは MainActivity のクラス変数 mUM, onShowFileChooser のパラメータは同 mUMA に保存しているようですので, これらの変数を利用するようにしては如何でしょうか.