3

I'm developing an app that will need to use a camera using the file input from WebView.

So this is the code that I write and it is working with the google camera.

In my webchromeclient

webView.setWebChromeClient(new WebChromeClient()  
    {  

           //The undocumented magic method override  
           //Eclipse will swear at you if you try to put @Override here  
        // For Android 3.0+
        @SuppressWarnings("unused")
        public void openFileChooser(ValueCallback<Uri> uploadMsg) {  

            mUploadMessage = uploadMsg;  
            File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyApp");
            // Create the storage directory if it does not exist
            if (! imageStorageDir.exists()){
                imageStorageDir.mkdirs();                  
            }
            File file = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");  
            imageUri = Uri.fromFile(file); 

            final List<Intent> cameraIntents = new ArrayList<Intent>();
            final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            final PackageManager packageManager = getPackageManager();
            final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
            for(ResolveInfo res : listCam) {
                final String packageName = res.activityInfo.packageName;
                final Intent i = new Intent(captureIntent);
                i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
                i.setPackage(packageName);
                i.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                cameraIntents.add(i);

            }


            mUploadMessage = uploadMsg; 
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);  
            i.addCategory(Intent.CATEGORY_OPENABLE);  
            i.setType("image/*"); 
            Intent chooserIntent = Intent.createChooser(i,"Image Chooser");
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
            MainActivity.this.startActivityForResult(chooserIntent,  FILECHOOSER_RESULTCODE);

       }

        //For Android 4.1
        @SuppressWarnings("unused")
        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType){
            mUploadMessage = uploadMsg;  
            File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyApp");
            // Create the storage directory if it does not exist
            if (! imageStorageDir.exists()){
                imageStorageDir.mkdirs();                  
            }
            File file = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");  
            imageUri = Uri.fromFile(file); 

            final List<Intent> cameraIntents = new ArrayList<Intent>();
            final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            final PackageManager packageManager = getPackageManager();
            final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
            for(ResolveInfo res : listCam) {
                final String packageName = res.activityInfo.packageName;
                final Intent i = new Intent(captureIntent);
                i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
                i.setPackage(packageName);
                i.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                cameraIntents.add(i);

            }


            mUploadMessage = uploadMsg; 
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);  
            i.addCategory(Intent.CATEGORY_OPENABLE);  
            i.setType("image/*"); 
            Intent chooserIntent = Intent.createChooser(i,"Image Chooser");
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
            MainActivity.this.startActivityForResult(chooserIntent,  FILECHOOSER_RESULTCODE);

        }

        //For Android 3.0+
       @SuppressWarnings("unused")
        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
           mUploadMessage = uploadMsg;  
           File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyApp");
           // Create the storage directory if it does not exist
           if (! imageStorageDir.exists()){
               imageStorageDir.mkdirs();                  
           }
           File file = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");  
           imageUri = Uri.fromFile(file); 

           final List<Intent> cameraIntents = new ArrayList<Intent>();
           final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
           final PackageManager packageManager = getPackageManager();
           final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
           for(ResolveInfo res : listCam) {
               final String packageName = res.activityInfo.packageName;
               final Intent i = new Intent(captureIntent);
               i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
               i.setPackage(packageName);
               i.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
               cameraIntents.add(i);

           }


           mUploadMessage = uploadMsg; 
           Intent i = new Intent(Intent.ACTION_GET_CONTENT);  
           i.addCategory(Intent.CATEGORY_OPENABLE);  
           i.setType("image/*"); 
           Intent chooserIntent = Intent.createChooser(i,"Image Chooser");
           chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
           MainActivity.this.startActivityForResult(chooserIntent,  FILECHOOSER_RESULTCODE);

       }

       //For Android 5.0+
       public boolean onShowFileChooser(
               WebView webView, ValueCallback<Uri[]> filePathCallback,
               WebChromeClient.FileChooserParams fileChooserParams) {

           // Double check that we don't have any existing callbacks
           if(mFilePathCallback != null) {
               mFilePathCallback.onReceiveValue(null);
           }
           mFilePathCallback = filePathCallback;

           // Set up the take picture intent
           Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
           if (takePictureIntent.resolveActivity(MainActivity.this.getPackageManager()) != null) {
               // Create the File where the photo should go
               File photoFile = null;
               try {
                   photoFile = createImageFile();
                   takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
               } catch (IOException ex) {
                   // Error occurred while creating the File
                   Log.e(tag, "Unable to create Image File", ex);
               }

               // Continue only if the File was successfully created
               if (photoFile != null) {
                   mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
                   takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                           Uri.fromFile(photoFile));
               } else {
                   takePictureIntent = null;
               }
           }

           // Set up the intent to get an existing image
           Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
           contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
           contentSelectionIntent.setType("image/*");

           // Set up the intents for the Intent chooser
           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, MainActivity.FILECHOOSER_RESULTCODE);

           return true;
       }
    }); 

Then this is my activityresult:

private Uri imageUri;
 @Override  
 protected void onActivityResult(int requestCode, int resultCode,  
                                    Intent intent) { 
    if (Build.VERSION.SDK_INT >= 21){
        if(requestCode != FILECHOOSER_RESULTCODE || mFilePathCallback == null) {
            super.onActivityResult(requestCode, resultCode, intent);
            return;
        }

        Uri[] results = null;

        // Check that the response is a good one
        if(resultCode == Activity.RESULT_OK) {
            if(intent == null) {
                // If there is not data, then we may have taken a photo
                if(mCameraPhotoPath != null) {
                    results = new Uri[]{Uri.parse(mCameraPhotoPath)};
                }
            } else {
                String dataString = intent.getDataString();
                if (dataString != null) {
                    results = new Uri[]{Uri.parse(dataString)};
                }
            }
        }

        mFilePathCallback.onReceiveValue(results);
        mFilePathCallback = null;
        return;
    }else{
          if(requestCode==FILECHOOSER_RESULTCODE)
          {  
              if (null == this.mUploadMessage) {
                    return;
                }

                Uri result;
                if (resultCode != RESULT_OK) {
                    result = null;
                } else {
                    result = intent == null ? this.imageUri : intent.getData(); // retrieve from the private variable if the intent is null
                }

                this.mUploadMessage.onReceiveValue(result);
                this.mUploadMessage = null;
          } 
    }
 } 

It is working with image upload or taking photo using the google camera.

My Question is how to exclude some camera intent when making the input action?

For example I want to remove camera 360 or retrica in the list, how to do it? http://i.imgur.com/n3Ni3wq.jpg

Alex K
  • 8,269
  • 9
  • 39
  • 57
bangketa
  • 33
  • 5

3 Answers3

1

Edit this part:

for(ResolveInfo res : listCam) {
           final String packageName = res.activityInfo.packageName;
           final Intent i = new Intent(captureIntent);
           i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
           i.setPackage(packageName);
           i.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
           cameraIntents.add(i);

       }

To This one:

for(ResolveInfo res : listCam) {
               final String packageName = res.activityInfo.packageName;
               final Intent i = new Intent(captureIntent);
               if(packageName.equals("ihate.this.package")||packageName.equals("begone.unwanted.package")){
                Log.i("camera", res.activityInfo.packageName+" blocked!");
               }else{
                i.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
                captureIntent.setPackage(packageName);
                i.setPackage(packageName);
                i.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                   cameraIntents.add(i);
               }

           }

If you want to know the package name just Log the res.activityInfo.packageName

You can do the same approach for android 5.0

wehpogi
  • 121
  • 4
0

You can restrict available apps by setPackage.

Bracadabra
  • 3,609
  • 3
  • 26
  • 46
  • setPackage is for limiting only for allowed application. All I need is to exclude some packages. There are so many built in camera app for different oems, so I cannot predict them all. Thats why, I think I need to exclude some unwanted camera app. – bangketa Jan 30 '15 at 01:24
0

No, what you are trying to do is not supported. You can either use setPackage to restrict it to one particular app, or leave the package null, and allow any capable app to handle the intent.

GreyBeardedGeek
  • 29,460
  • 2
  • 47
  • 67