I am trying to upload images via a WebView in Android. The problem is the missing content type. Seems like it`s a known issue in Android 4.4.4. What can be done in this situation? I found this answer on similar question, but I can't figure out how to implement this solution. I have access to server side.
Thanks.
In the answer you found, they call
startActivityForResult( Intent.createChooser( i, "File Chooser" ), MainActivity.FILECHOOSER_RESULTCODE)
What means, you should get the results of this in this method
protected void onActivityResult( int requestCode, int resultCode, Intent data )
{
if(requestCode == MainActivity.FILECHOOSER_RESULTCODE)
{
if(resultCode == RESULT_OK)
// TODO: Check Results of data-intent
}
}
in this method you can handle the results from the file chooser and do a upload by yourself (e.g. with URLConnection or ApacheHttpClient).
UPDATE 2016-10-19
Here is a Example where the ValueCallback is stored and the result of the ChooserIntent is passed back to the callback.
I didn`t try this example, but I think it should trigger a own upload methode from the webview.
private ValueCallback<Uri> mUploadMessage;
private Uri mCapturedImageURI = null;
protected void onActivityResult( int requestCode, int resultCode, Intent data )
{
if(requestCode == MainActivity.FILECHOOSER_RESULTCODE)
{
if(resultCode == RESULT_OK) {
result = intent == null ? mCapturedImageURI : intent.getData();
mUploadMessage.onReceiveValue(result);
}
}
}
onReceiveValue(result);
Source: http://androidexample.com/Open_File_Chooser_With_Camera_Option_In_Webview_File_Option/index.php?view=article_discription&aid=128
Check this thread for more examples https://stackoverflow.com/a/7857102/2377961
Related
I am trying to fetch a file this way:
final Intent chooseFileIntent = new Intent(Intent.ACTION_GET_CONTENT);
String[] mimetypes = {"application/pdf"};
chooseFileIntent.setType("*/*");
chooseFileIntent.addCategory(Intent.CATEGORY_OPENABLE);
if (chooseFileIntent.resolveActivity(activity
.getApplicationContext().getPackageManager()) != null) {
chooseFileIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
activity.startActivityForResult(chooseFileIntent, Uploader.PDF);
}
Then in onActivityResult :
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
According to many threads I'm supposed to fetch the file name from the intent with data.getData().getPath(), the file name I'm expecting is my_file.pdf, but instead I'm getting this :
/document/acc=1;doc=28
So what to do? Thanks for your help.
I am trying to fetch a file
Not with that code. That code is asking the user to pick a piece of content. This may or may not be a file.
According to many threads I'm supposed to fetch the file name from the intent with data.getData().getPath()
That was never correct, though it tended to work on older versions of Android.
So what to do?
Well, that depends.
If you wish to only accept files, integrate a file chooser library instead of using ACTION_GET_CONTENT. (UPDATE 2019-04-06: since Android Q is banning most filesystem access, this solution is no longer practical)
If you are willing to allow the user to pick a piece of content using ACTION_GET_CONTENT, please understand that it does not have to be a file and it does not have to have something that resembles a filename. The closest that you will get:
If getScheme() of the Uri returns file, your original algorithm will work
If getScheme() of the Uri returns content, use DocumentFile.fromSingleUri() to create a DocumentFile, then call getName() on that DocumentFile — this should return a "display name" which should be recognizable to the user
To get the real name and to avoid getting a name that looks like "image: 4431" or even just a number, you can write code as recommended by CommonsWare.
The following is an example of a code that selects a single pdf file, prints its name and path to the log, and then sends the file by email using its uri.
private static final int FILEPICKER_RESULT_CODE = 1;
private static final int SEND_EMAIL_RESULT_CODE = 2;
private Uri fileUri;
private void chooseFile() {
Intent fileChooser = new Intent(Intent.ACTION_GET_CONTENT);
fileChooser.setType("application/pdf");
startActivityForResult(Intent.createChooser(fileChooser, "Choose one pdf file"), FILEPICKER_RESULT_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILEPICKER_RESULT_CODE) {
if (resultCode == RESULT_OK) {
fileUri = data != null ? data.getData() : null;
if (fileUri != null) {
DocumentFile d = DocumentFile.fromSingleUri(this, fileUri);
if (d != null) {
Log.d("TAG", "file name: " + d.getName());
Log.d("TAG", "file path: " + d.getUri().getPath());
sendEmail(fileUri);
}
}
}
}
}
private void sendEmail(Uri path) {
String email = "example#gmail.com";
Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("application/octet-stream");
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "PDF file");
String[] to = { email };
intent.putExtra(Intent.EXTRA_EMAIL, to);
intent.putExtra(Intent.EXTRA_TEXT, "This is the pdf file...");
intent.putExtra(Intent.EXTRA_STREAM, path);
startActivityForResult(Intent.createChooser(intent, "Send mail..."), SEND_EMAIL_RESULT_CODE);
}
hope it helps.
I can't get the normal taken picture by my phone in java. Everything is working while I choose picture from the gallery which is screenshot but when It's normal taken picture it's not returning anything. I will give you some parts of the code where u can see how I'm getting picture.
#Override
public void onActivityResult(int reqCode, int resultCode, final Intent data) {
super.onActivityResult(reqCode, resultCode, data);
if (reqCode == PICK_IMAGE && resultCode == Activity.RESULT_OK) {
final Uri imageUri = data.getData();
final String path = getPath(getActivity(), imageUri);
if (path != null) {
try {
File f1 = new File(path);
final AsyncHttpClient client = new AsyncHttpClient(true, 80, 443);
client.addHeader("accept", "application/json");
final RequestParams params = new RequestParams();
params.put("id", id);
params.put("token", token);
params.put("avatar", f1);
And also this
add_avatar.setOnClickListener(new View.OnClickListener() {
#TargetApi(Build.VERSION_CODES.M)
#Override
public void onClick(View view) {
// filePickUtils.requestImageGallery(STORAGE_PERMISSION_IMAGE, true, true);
if (getActivity().checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (shouldShowRequestPermissionRationale(
android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
// Explain to the user why we need to read the contacts
}
requestPermissions(new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
1);
// MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
// app-defined int constant that should be quite unique
return;
}
if (getActivity().checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (shouldShowRequestPermissionRationale(
android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Explain to the user why we need to read the contacts
}
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
1);
// MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
// app-defined int constant that should be quite unique
return;
}
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
photoPickerIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
photoPickerIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, PICK_IMAGE);
}
});
What would you suggest?
Thanks for your help
Given that you only need to read the image, and upload the data to your backend server, I'd suggest if you use Intent.ACTION_GET_CONTENT instead of Intent.ACTION_PICK.
Why
Your problem might related to what Intent.ACTION_PICK needs to have. The documentation stated:
Input: getData() is URI containing a directory of data (vnd.android.cursor.dir/*) from which to pick an item.
So it means, if you want to use Intent.ACTION_PICK, you need to provide the directory of the data.
Meanwhile if you use Intent.ACTION_GET_CONTENT, you can just set the MIME type of the file that you want to search (just as what you are doing now), and use Context.startActivity(intent).
Additional note from the documentation that you might want to read:
Input: getType() is the desired MIME type to retrieve. Note that no URI is supplied in the intent, as there are no constraints on where the returned data originally comes from. You may also include the CATEGORY_OPENABLE if you can only accept data that can be opened as a stream. You may use EXTRA_LOCAL_ONLY to limit content selection to local data. You may use EXTRA_ALLOW_MULTIPLE to allow the user to select multiple items.
Output: The URI of the item that was picked. This must be a content: URI so that any receiver can access it.
Add a comment here, if you need further information.
Sample Code:
In your activity
private searchImageFile() {
Intent intent = new Intent(Intent.GET_CONTENT);
// Filter to only show results that can be "opened"
intent.addCategory(Intent.CATEGORY_OPENABLE);
// Filter to show only images, using the image MIME data type.
// it would be "*/*".
intent.setType("image/*");
startActivityForResult(intent, READ_REQUEST_CODE);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
final Uri imageUri = resultData.getData();
//Do something with your Uri.
}
}
I am a beginner at Android programming and I had a doubt to be clarified.
I tried out a tutorial on VideoView in Android and observed that,
When the specified URI string is "http://www.androidbegin.com/tutorial/AndroidCommercial.3gp", the program works.
I tried replacing the URI string with the location of a video present in the phone's internal storage (/storage/emulated/0/Movies/test.mp4) and the program produced the error java.io.IOException: setDataSource failed.
My question is what does the error signify and why does it occur ? since both the URI string's do specify the video to be played.
(Note: I followed this tutorial)
Try this code to get a video from gallery:
// in onCreate method
Intent getVid= new Intent();
getVid.setType("video/*");
getVid.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(getVid, "Select a video" ),
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
} if (requestCode == 1 && resultCode == RESULT_OK){
String videoUrl = data.getData().toString();
Intent i = new Intent(MainActivity.this , videoViewActivity.class);
i.putExtra("vid" , videoUrl);
startActivity(i);
}
in videoViewActivity type this code in onCreate method after initializing videoView :
String path = getIntent().getStringExtra("vid");
videoView.setVideoPath(path);
videoView.start();
It's probably because of your Uri. When you use Uri.parse("/blabla") it's not validating that path, is it really exist or not. And in your case you need to give something like "file:///storage/emulated/0/Movies/test.mp4". Or your app don't have file permission, you need to add a permission check first.
I'm making an Android app that is web base social media sites all in one and I am having trouble with Twitter and Google plus won't allow me to upload a photo, it will let me choose one but will not let me upload it.
Facebook is fine that will let me choose a photo and upload it without errors.
Here is the code I'm using, maybe something I'm doing is wrong.
#SuppressWarnings("unused")
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
hello.mUploadMessage = uploadMsg;
getActivity().startActivityForResult( Intent.createChooser( i, "File Chooser" ), 1 ); }
MainActivity
ValueCallback<Uri> mUploadMessage;
private final static int FILECHOOSER_RESULTCODE=1;
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if(requestCode==FILECHOOSER_RESULTCODE)
{
if (null == mUploadMessage) return;
Uri result = intent == null || resultCode != RESULT_OK ? null
: intent.getData();
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
I'm using Eclipse and testing it on Android 4.4.4 and 4.3, can anyone give me an idea? hope it something basic and an easy fix.
I would like to take multiple photos via Intent. I know how to make intent for taking just one image, but what if I would like to take e.g. 10 photos?
static final int REQUEST_IMAGE_CAPTURE = 1;
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
Trivial solution is to make another intent after result but I think there must be better solution, isn't there?
You have to do something by using some trick, one of the question asked on the stackoverflow will help you, see this link
second check this link
these two links will surely help you.
the second link recomend this code
Intent intent = new Intent(
MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
this.startActivity(intent);
In my case I had to use MediaStore.ACTION_IMAGE_CAPTURE in order to disable selecting image from the phone gallery.
In order to achieve "similar" behaviour with taking several pictures I was starting next camera intent directly from onActivityResult while processing recently taken photo in background.
Code looks like this:
...
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode != REQUEST_IMAGE_CAPTURE) {
return
}
if (resultCode == Activity.RESULT_CANCELED) {
Timber.d("Taking image was cancelled")
return
}
if (resultCode == Activity.RESULT_OK) {
lastTakenPhotoData?.let {
handlePhotoTaken(it)
startCameraIntent()
}
}
}
...
private fun handlePhotoTaken(...) {
disposable.add(
Single.fromCallable { compressPhotoTaken(data) }
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread()).subscribe { _ ->
//update UI with processed photo
}
)
}
...
private fun compressTakenPhoto(...) {
//rotate, compress, save taken photo to the local file if needed
//this part was taking quite a lot of time, so it is better to do it in background
}