diff options
author | Ben Murdoch <benm@google.com> | 2011-02-18 11:25:38 +0000 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-02-18 14:17:29 +0000 |
commit | e4c0cae39f1ca34891de0f892aee4797c892caec (patch) | |
tree | aa10c1a97a2d74f3c7cd87629c0d803b2410370d /src/com | |
parent | bf6b54db8f42a42c218f17ec358563e66e8e95ba (diff) | |
download | packages_apps_Browser-e4c0cae39f1ca34891de0f892aee4797c892caec.zip packages_apps_Browser-e4c0cae39f1ca34891de0f892aee4797c892caec.tar.gz packages_apps_Browser-e4c0cae39f1ca34891de0f892aee4797c892caec.tar.bz2 |
Fix crash when activity for file upload is not present.
Ensure that there is an activity to handle the intents
that the file upload control fires. If not, fallback to
the default upload control. This CL also refactors the
code to be (hopefully :)) easier to follow.
Bug:3447924
Change-Id: Ie5f7b448ec1c6abc7da7df29b94cc120d3b2c60e
Diffstat (limited to 'src/com')
-rw-r--r-- | src/com/android/browser/UploadHandler.java | 179 |
1 files changed, 106 insertions, 73 deletions
diff --git a/src/com/android/browser/UploadHandler.java b/src/com/android/browser/UploadHandler.java index d9b387f..ee578fa 100644 --- a/src/com/android/browser/UploadHandler.java +++ b/src/com/android/browser/UploadHandler.java @@ -17,11 +17,13 @@ package com.android.browser; import android.app.Activity; +import android.content.ActivityNotFoundException; import android.content.Intent; import android.net.Uri; import android.os.Environment; import android.provider.MediaStore; import android.webkit.ValueCallback; +import android.widget.Toast; import java.io.File; import java.util.Vector; @@ -82,14 +84,10 @@ public class UploadHandler { final String mediaSourceValueCamcorder = "camcorder"; final String mediaSourceValueMicrophone = "microphone"; - // media source can be 'filesystem' or 'camera' or 'camcorder' or 'microphone'. + // According to the spec, media source can be 'filesystem' or 'camera' or 'camcorder' + // or 'microphone'. String mediaSource = ""; - // We add the camera intent if there was no accept type (or '*/*' or 'image/*'). - boolean addCameraIntent = true; - // We add the camcorder intent if there was no accept type (or '*/*' or 'video/*'). - boolean addCamcorderIntent = true; - if (mUploadMessage != null) { // Already a file picker operation in progress. return; @@ -111,104 +109,139 @@ public class UploadHandler { } } - // This intent will display the standard OPENABLE file picker. - Intent i = new Intent(Intent.ACTION_GET_CONTENT); - i.addCategory(Intent.CATEGORY_OPENABLE); - - // Create an intent to add to the standard file picker that will - // capture an image from the camera. We'll combine this intent with - // the standard OPENABLE picker unless the web developer specifically - // requested the camera or gallery be opened by passing a parameter - // in the accept type. - Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - File externalDataDir = Environment.getExternalStoragePublicDirectory( - Environment.DIRECTORY_DCIM); - File cameraDataDir = new File(externalDataDir.getAbsolutePath() + - File.separator + "browser-photos"); - cameraDataDir.mkdirs(); - mCameraFilePath = cameraDataDir.getAbsolutePath() + File.separator + - System.currentTimeMillis() + ".jpg"; - cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(mCameraFilePath))); - - Intent camcorderIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); - - Intent soundRecIntent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION); + //Ensure it is not still set from a previous upload. + mCameraFilePath = null; if (mimeType.equals(imageMimeType)) { - i.setType(imageMimeType); - addCamcorderIntent = false; if (mediaSource.equals(mediaSourceValueCamera)) { - // Specified 'image/*' and requested the camera, so go ahead and launch the camera - // directly. - startActivity(cameraIntent); + // Specified 'image/*' and requested the camera, so go ahead and launch the + // camera directly. + startActivity(createCameraIntent()); return; } else if (mediaSource.equals(mediaSourceValueFileSystem)) { - // Specified filesytem as the source, so don't want to consider the camera. - addCameraIntent = false; + // Specified 'image/*' and requested the filesystem, so go ahead and launch an + // OPENABLE intent. + startActivity(createOpenableIntent(imageMimeType)); + return; + } else { + // Specified just 'image/*', so launch an intent for both the Camera and image/* + // OPENABLE. + Intent chooser = createChooserIntent(createCameraIntent()); + chooser.putExtra(Intent.EXTRA_INTENT, createOpenableIntent(imageMimeType)); + startActivity(chooser); + return; } } else if (mimeType.equals(videoMimeType)) { - i.setType(videoMimeType); - addCameraIntent = false; - // The camcorder saves it's own file and returns it to us in the intent, so - // we don't need to generate one here. - mCameraFilePath = null; - if (mediaSource.equals(mediaSourceValueCamcorder)) { // Specified 'video/*' and requested the camcorder, so go ahead and launch the // camcorder directly. - startActivity(camcorderIntent); + startActivity(createCamcorderIntent()); return; } else if (mediaSource.equals(mediaSourceValueFileSystem)) { - // Specified filesystem as the source, so don't want to consider the camcorder. - addCamcorderIntent = false; + // Specified 'video/*' and requested the filesystem, so go ahead and launch an + // an OPENABLE intent. + startActivity(createOpenableIntent(videoMimeType)); + return; + } else { + // Specified just 'video/*', so go ahead and launch an intent for both camcorder and + // video/* OPENABLE. + Intent chooser = createChooserIntent(createCamcorderIntent()); + chooser.putExtra(Intent.EXTRA_INTENT, createOpenableIntent(videoMimeType)); + startActivity(chooser); + return; } } else if (mimeType.equals(audioMimeType)) { - i.setType(audioMimeType); - addCameraIntent = false; - addCamcorderIntent = false; if (mediaSource.equals(mediaSourceValueMicrophone)) { // Specified 'audio/*' and requested microphone, so go ahead and launch the sound // recorder. - startActivity(soundRecIntent); + startActivity(createSoundRecorderIntent()); + return; + } else if (mediaSource.equals(mediaSourceValueFileSystem)) { + // Specified 'audio/*' and requested filesystem, so go ahead and launch an + // OPENABLE intent. + startActivity(createOpenableIntent(audioMimeType)); + return; + } else { + // Specified just 'audio/*', so go ahead and launch an intent for both the sound + // recorder and audio/* OPENABLE. + Intent chooser = createChooserIntent(createSoundRecorderIntent()); + chooser.putExtra(Intent.EXTRA_INTENT, createOpenableIntent(audioMimeType)); + startActivity(chooser); return; } - // On a default system, there is no single option to open an audio "gallery". Both the - // sound recorder and music browser respond to the OPENABLE/audio/* intent unlike the - // image/* and video/* OPENABLE intents where the image / video gallery are the only - // respondants (and so the user is not prompted by default). - } else { - i.setType("*/*"); } - // Combine the chooser and the extra choices (like camera or camcorder) - Intent chooser = new Intent(Intent.ACTION_CHOOSER); - chooser.putExtra(Intent.EXTRA_INTENT, i); - - Vector<Intent> extraInitialIntents = new Vector<Intent>(0); + // No special handling based on the accept type was necessary, so trigger the default + // file upload chooser. + startActivity(createDefaultOpenableIntent()); + } - if (addCameraIntent) { - extraInitialIntents.add(cameraIntent); + private void startActivity(Intent intent) { + try { + mController.getActivity().startActivityForResult(intent, Controller.FILE_SELECTED); + } catch (ActivityNotFoundException e) { + // No installed app was able to handle the intent that + // we sent, so fallback to the default file upload control. + try { + mController.getActivity().startActivityForResult(createDefaultOpenableIntent(), + Controller.FILE_SELECTED); + } catch (ActivityNotFoundException e2) { + // Nothing can return us a file, so file upload is effectively disabled. + Toast.makeText(mController.getActivity(), R.string.uploads_disabled, + Toast.LENGTH_LONG).show(); + } } + } - if (addCamcorderIntent) { - extraInitialIntents.add(camcorderIntent); - } + private Intent createDefaultOpenableIntent() { + // Create and return a chooser with the default OPENABLE + // actions including the camera, camcorder and sound + // recorder where available. + Intent i = new Intent(Intent.ACTION_GET_CONTENT); + i.addCategory(Intent.CATEGORY_OPENABLE); + i.setType("*/*"); - if (extraInitialIntents.size() > 0) { - Intent[] extraIntents = new Intent[extraInitialIntents.size()]; - chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, - extraInitialIntents.toArray(extraIntents)); - } + Intent chooser = createChooserIntent(createCameraIntent(), createCamcorderIntent(), + createSoundRecorderIntent()); + chooser.putExtra(Intent.EXTRA_INTENT, i); + return chooser; + } + private Intent createChooserIntent(Intent... intents) { + Intent chooser = new Intent(Intent.ACTION_CHOOSER); + chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents); chooser.putExtra(Intent.EXTRA_TITLE, mController.getActivity().getResources() .getString(R.string.choose_upload)); - startActivity(chooser); + return chooser; } - private void startActivity(Intent intent) { - mController.getActivity().startActivityForResult(intent, - Controller.FILE_SELECTED); + private Intent createOpenableIntent(String type) { + Intent i = new Intent(Intent.ACTION_GET_CONTENT); + i.addCategory(Intent.CATEGORY_OPENABLE); + i.setType(type); + return i; + } + + private Intent createCameraIntent() { + Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + File externalDataDir = Environment.getExternalStoragePublicDirectory( + Environment.DIRECTORY_DCIM); + File cameraDataDir = new File(externalDataDir.getAbsolutePath() + + File.separator + "browser-photos"); + cameraDataDir.mkdirs(); + mCameraFilePath = cameraDataDir.getAbsolutePath() + File.separator + + System.currentTimeMillis() + ".jpg"; + cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(mCameraFilePath))); + return cameraIntent; + } + + private Intent createCamcorderIntent() { + return new Intent(MediaStore.ACTION_VIDEO_CAPTURE); + } + + private Intent createSoundRecorderIntent() { + return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION); } } |