14

I am launching an intent to get photos from gallery and when I am using nexus google photo app in my gallery everything works fine.

But if the image is not on the phone (on the Google Photos online service) it will download it for me. After selecting the image I am sending the image to another activity for cropping but in case of download the image sent to the crop activity is null since the download is not finished yet.

How can I know when the download is finished to send the image to the cropping activity?

Here is my code:

private void pickFromGallery()
{
    Intent galleryIntent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(galleryIntent, RESULT_LOAD_IMG);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    try {
        // When an Image is picked
        if (requestCode == RESULT_LOAD_IMG && resultCode == Activity.RESULT_OK
                && null != data) {
            // Get the Image from data

            Uri selectedImage = data.getData();
            String[] filePathColumn = {MediaStore.Images.Media.DATA};

            // Get the cursor
            Cursor cursor = getApplicationContext().getContentResolver().query(selectedImage,
                    filePathColumn, null, null, null);
            // Move to first row
            assert cursor != null;
            cursor.moveToFirst();

            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            imgDecodableString = cursor.getString(columnIndex);
            cursor.close();
            startCrop(imgDecodableString);
        }
    } catch (Exception e) {
        Toast.makeText(this, "Something went wrong", Toast.LENGTH_LONG)
                .show();
    }
    }

any help would be appreciated.

Vince
  • 1,570
  • 3
  • 27
  • 48
Mostafa Addam
  • 6,956
  • 4
  • 20
  • 38

3 Answers3

19

I think you can't crop images when you download selected image from google photos. you can only crop your local storage images

But for checking whether selected image is downloadable or from local storage you can do like this in your onActivityResult() method.

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == RESULT_LOAD_IMG && resultCode == Activity.RESULT_OK
                && null != data) {

                Uri selectedImageUri = data.getData();
                String tempPath = getPath(selectedImageUri, getActivity());
                String url = data.getData().toString();
                if (url.startsWith("content://com.google.android.apps.photos.content")){
                    try {
                        InputStream is = getActivity().getContentResolver().openInputStream(selectedImageUri);
                        if (is != null) {
                            Bitmap pictureBitmap = BitmapFactory.decodeStream(is);
                            //You can use this bitmap according to your purpose or Set bitmap to imageview
                        }
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }else {
                     startCrop(tempPath);

             }
         }

}

Here is getPath() method which is used in onActivityResult().

public String getPath(Uri uri, Activity activity) {
    Cursor cursor = null;
    try {
        String[] projection = {MediaStore.MediaColumns.DATA};
        cursor = activity.getContentResolver().query(uri, projection, null, null, null);
        if (cursor.moveToFirst()) {
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
            return cursor.getString(column_index);
        }
    } catch (Exception e) {
    } finally {
        cursor.close();
    }
    return "";
}

I hope it helps you.

Rajesh Jadav
  • 12,801
  • 5
  • 53
  • 78
2

you can not download images from google drive below are the steps to download images or files from drive.

To download images or file from google drive you need a library

  • google-api-services-drive-v2-rev9-1.8.0-beta.jar()

SETTING UP THE CONSOLE

  • next go to Google Consol

  • Make a new project. Under Services, you'll need to turn on two things: DRIVE API and DRIVE SDK! They are separate, one does not automatically turn the other on, and YOU MUST TURN BOTH ON! (Figuring this out wasted at least 20 hours of my time alone.)

  • Still on the console, go to API Access. Create a client, make it an Android app. Give it your bundle ID. I don't think the fingerprints thing is actually important, as I'm pretty sure I used the wrong one, but try to get that right anyways (Google provides instructions for it.)

  • It'll generate a Client ID. You're going to need that. Hold onto it.

THE ANDROID CODE - Set Up and Uploading

  • First, get an auth token:

    AccountManager am = AccountManager.get(activity); am.getAuthToken(am.getAccounts())[0], "oauth2:" + DriveScopes.DRIVE, new Bundle(), true, new OnTokenAcquired(), null);

Next, OnTokenAcquired() needs to be set up something like this:

private class OnTokenAcquired implements AccountManagerCallback<Bundle> {
    @Override
    public void run(AccountManagerFuture<Bundle> result) {
        try {
            final String token = result.getResult().getString(AccountManager.KEY_AUTHTOKEN);
            HttpTransport httpTransport = new NetHttpTransport();
            JacksonFactory jsonFactory = new JacksonFactory();
            Drive.Builder b = new Drive.Builder(httpTransport, jsonFactory, null);
            b.setJsonHttpRequestInitializer(new JsonHttpRequestInitializer() {
                @Override
                public void initialize(JSonHttpRequest request) throws IOException {
                    DriveRequest driveRequest = (DriveRequest) request;
                    driveRequest.setPrettyPrint(true);
                    driveRequest.setKey(CLIENT ID YOU GOT WHEN SETTING UP THE CONSOLE BEFORE YOU STARTED CODING)
                    driveRequest.setOauthToken(token);
                }
            });

            final Drive drive = b.build();

            final com.google.api.services.drive.model.File body = new com.google.api.services.drive.model.File();
            body.setTitle("My Test File");
    body.setDescription("A Test File");
    body.setMimeType("text/plain");

            final FileContent mediaContent = new FileContent("text/plain", an ordinary java.io.File you'd like to upload. Make it using a FileWriter or something, that's really outside the scope of this answer.)
            new Thread(new Runnable() {
                public void run() {
                    try {
                        com.google.api.services.drive.model.File file = drive.files().insert(body, mediaContent).execute();
                        alreadyTriedAgain = false; // Global boolean to make sure you don't repeatedly try too many times when the server is down or your code is faulty... they'll block requests until the next day if you make 10 bad requests, I found.
                    } catch (IOException e) {
                        if (!alreadyTriedAgain) {
                            alreadyTriedAgain = true;
                            AccountManager am = AccountManager.get(activity);
                            am.invalidateAuthToken(am.getAccounts()[0].type, null); // Requires the permissions MANAGE_ACCOUNTS & USE_CREDENTIALS in the Manifest
                            am.getAuthToken (same as before...)
                        } else {
                            // Give up. Crash or log an error or whatever you want.
                        }
                    }
                }
            }).start();
            Intent launch = (Intent)result.getResult().get(AccountManager.KEY_INTENT);
            if (launch != null) {
                startActivityForResult(launch, 3025);
                return; // Not sure why... I wrote it here for some reason. Might not actually be necessary.
            }
        } catch (OperationCanceledException e) {
            // Handle it...
        } catch (AuthenticatorException e) {
            // Handle it...
        } catch (IOException e) {
            // Handle it...
        }
    }
}

THE ANDROID CODE - Downloading

private java.io.File downloadGFileToJFolder(Drive drive, String token, File gFile, java.io.File jFolder) throws IOException {
    if (gFile.getDownloadUrl() != null && gFile.getDownloadUrl().length() > 0 ) {
        if (jFolder == null) {
            jFolder = Environment.getExternalStorageDirectory();
            jFolder.mkdirs();
        }
        try {

            HttpClient client = new DefaultHttpClient();
            HttpGet get = new HttpGet(gFile.getDownloadUrl());
            get.setHeader("Authorization", "Bearer " + token);
            HttpResponse response = client.execute(get);

            InputStream inputStream = response.getEntity().getContent();
            jFolder.mkdirs();
            java.io.File jFile = new java.io.File(jFolder.getAbsolutePath() + "/" + getGFileName(gFile)); // getGFileName() is my own method... it just grabs originalFilename if it exists or title if it doesn't.
            FileOutputStream fileStream = new FileOutputStream(jFile);
            byte buffer[] = new byte[1024];
            int length;
            while ((length=inputStream.read(buffer))>0) {
                fileStream.write(buffer, 0, length);
            }
            fileStream.close();
            inputStream.close();
            return jFile;
        } catch (IOException e) {        
            // Handle IOExceptions here...
            return null;
        }
    } else {
        // Handle the case where the file on Google Drive has no length here.
        return null;
    }
}
vishal jangid
  • 2,967
  • 16
  • 22
  • 2
    The question mention Google Photos, not Google Drive. Anyway - you can get file from Google Drive using DocumentsProvider. – Milos Fec Jan 08 '16 at 18:07
  • @MilosFec google drive is part of google and google always store photos on google drive. – vishal jangid Jan 11 '16 at 09:27
  • 1
    That is not relevant. When you have installed Google Photos you can get photos using Intent.ACTION_PICK. If you have installed Google Drive, you can get any file using Intent.ACTION_OPEN_DOCUMENT. – Milos Fec Jan 11 '16 at 13:01
0

You can use AsyncTask for downloading (or copying local image), then process it.

In your Activity create:

private class PictureAsyncTask extends AsyncTask<Void, Void, String> {
    private Uri mUri;

    public PictureAsyncTask(Uri uri) {
        mUri = uri;
    }

    @Override
    protected String doInBackground(Void... params) {
        InputStream inputStream = null;
        try {
            inputStream = getContentResolver().openInputStream(mUri);
            String path = null; // Path of downloaded image
            // Download image from inputStream
            return path;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null
    }

    @Override
    protected void onPostExecute(String path) {
        if (path == null) {
            // Process image
            // Maybe another AsyncTask or background thread?
        } else {
            // Download failed
        }
    }
}

Call it from onActivityResult:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case RESULT_LOAD_IMG:
            if (resultCode == RESULT_OK) {
                if (data != null) {
                    Uri uri = data.getData();
                    if (uri != null) {
                        new PictureAsyncTask(uri).execute();
                    } else {
                        // No data
                    }
                } else {
                    // No picture selected?
                }
            }
            break;
    }
}
Milos Fec
  • 828
  • 6
  • 11
  • i just wanna know when to handle the download while using google photo app as gallery – Mostafa Addam Jan 10 '16 at 16:55
  • You should always handle it in the background thread, even when it is local picture. I.e. instead of downloading you can create the Bitmap using BitmapFactory.decodeStream(inpustStream) and process the bitmap. It could take some time so it is not good to do it on the main thread. – Milos Fec Jan 11 '16 at 08:49