0

background information

I have been writing a backup photos service, which needs to get all photo absolute paths from Android external storage (like photos stored in 'DCIM' directory and its subdirectores) and upload them to remote server. The problem is how to get all validate photo absolute paths from Android device. Since there is a vast majority of Android devices, it`s tough to ensure the get-photo-absolute-path algorithm to successfully reach all validate photos Gallery directory and traverse all photos paths inside of it.

Now my app only supports uploading photos from primary external storage (not the secondary external storage, like removable SD card). That`s to say.

  1. if the device only has one emulated external storage (on-board flash), camera upload service can scan photo paths on it correctly.
  2. if the device only has a removable storage (like SD card), camera upload service can scan photo paths correctly as well.

the algorithm above scans photo paths from primary external storage which works correctly. But when it comes to

  1. if the device both has a emulated external storage and a removable storage, camera upload service only scans photo paths on the emulated external storage (primary storage), but a majority of users save their photos to the 16G or bigger size removable SD card (secondary storage) which will be ignored by my app, that`s the problem. see the complete issue here.

Code implementation

To get absolute photo path from internal storage, I hard coded an "external directory list",

String[] paths = {
            "/DCIM",
            "/DCIM/Camera",
            "/DCIM/100MEDIA",
            // Many Samsung phones mount the external sd card to /sdcard/external_sd
            "/external_sd/DCIM",
            "/external_sd/DCIM/Camera",
            "/external_sd/DCIM/100MEDIA"
        };

and combined the absolute path like

String fullPath = Environment.getExternalStorageDirectory().getAbsolutePath() + path;

I know that`s not the best practice, that`s why ask for help. BTW, see the complete external directory list

Question

To get absolute photo paths from Android storage

  1. check if external storage mounted, then scan photos from internal storage by default. This can fit a majority of getting photo path requirements, see the complete implementation here
  2. let user choose a specific directory to upload photos from SD card (if mounted one)

So I wonder if the proposal above is right or not?
Any comments or reference will be greatly appreciated.


EDIT Different manufacturers set their SD card mounted point differently, there is no regular rules for that, it almost impossible (or say, bad practice) to scan and upload photos by the app in the background automatically. To get photos path from SD card, the practical way I think is to only scan root directories, then shows such directories in a file browser window to let user choose a specific gallery directory and persist the path locally instead of scanning by the app itself. Because it`s error prone to scan photos directives automatically on SD card.

Logan Guo
  • 865
  • 4
  • 17
  • 35

2 Answers2

0

You can try this way

for popup

private void selectImage() 
{
    final CharSequence[] items = { "Camera", "Gallery","Cancel" };
    AlertDialog.Builder builder = new AlertDialog.Builder(Detail_mul.this);
    builder.setTitle("Add Photo!");
    builder.setItems(items, new DialogInterface.OnClickListener() 
    {
        @Override
        public void onClick(DialogInterface dialog, int item) 
        {
            if (items[item].equals("Camera"))
            {
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                File f = new File(android.os.Environment.getExternalStorageDirectory(), "temp.jpg");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
                startActivityForResult(intent, REQUEST_CAMERA);
            } else if (items[item].equals("Gallery")) {
                Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                intent.setType("image/*");
                startActivityForResult(Intent.createChooser(intent, "Select File"),SELECT_FILE);
            } else if (items[item].equals("Cancel")) {
                dialog.dismiss();
            }
        }
    });
    builder.show();
}

for getting the result

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Bitmap bm = null;
    if (resultCode == RESULT_OK) {
        if (requestCode == REQUEST_CAMERA) {
            File f = new File(Environment.getExternalStorageDirectory().toString());
            for (File temp : f.listFiles()) {
                if (temp.getName().equals("temp.jpg")) {
                    f = temp;
                    break;
                }
            }
            try {
                
                BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
                bm = BitmapFactory.decodeFile(f.getAbsolutePath(),btmapOptions);
                bm = Bitmap.createScaledBitmap(bm, 300, 200, true);
                
                String path = android.os.Environment.getExternalStorageDirectory()+ File.separator+ "Phoenix" + File.separator + "default";
                
                PreferenceManager.getDefaultSharedPreferences(getBaseContext()).edit().putString("endum_image_"+count, f.toString()).commit();
                
                OutputStream fOut = null;
                File file = new File(path, String.valueOf(System.currentTimeMillis()) + ".jpg");
                try {
                    fOut = new FileOutputStream(file);
                    bm.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
                    fOut.flush();
                    fOut.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (requestCode == SELECT_FILE) 
        {
            Uri selectedImageUri = data.getData();
            
            //getRealPathFromURI(selectedImageUri);
            
            String tempPath = getPath(selectedImageUri, Detail_mul.this);
            PreferenceManager.getDefaultSharedPreferences(getBaseContext()).edit().putString("endum_image_"+count, tempPath).commit();
            
            BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
            bm = BitmapFactory.decodeFile(tempPath,btmapOptions);
            bm = Bitmap.createScaledBitmap(bm, 300, 200, true);
            
            bm = BitmapFactory.decodeFile(tempPath, btmapOptions);
            
        }
    }   }
Community
  • 1
  • 1
Maveňツ
  • 1
  • 12
  • 50
  • 89
  • thanks for your comment, but I need to get all validate photo paths in background service, I don\`t plan to supply user a window to choose some specific photos, instead I want to scan the whole external storage and get all validate photo paths. My requirement here is to **backup** all local photos to remote server. – Logan Guo Nov 07 '14 at 02:06
0

I think you are uploading images for your photo service.You can access the gallery to select a particular picture because every picture in your phone is there in your Gallery whether on SDcard or Primary memory.

Code for accessing gallery you can see this code.I think this would help

Community
  • 1
  • 1
thestrongenough
  • 225
  • 2
  • 14
  • not really, I need all photo paths in Gallery rather than only one, also please notice that I need to get these photo paths from background, which doesn\`t popup a window. Everything to be done in background service. – Logan Guo Nov 07 '14 at 02:00