连接Google Drive时触发IllegalArgumentException异常的排查求助
Looking at your stack trace, the critical error is java.lang.IllegalArgumentException: the name must not be empty: null — this pops up when GoogleAuthUtil tries to fetch an auth token but can't validate the account you're using. Let's break down all the issues in your code and fix them:
1. Camera flow is broken (and asynchronous logic is wrong)
Your handleCamera() method only creates a camera Intent but never launches the camera! Even worse, you call save2Drive() immediately in onCreate() — the photo hasn't been taken yet (or even started), which would cause file-related errors later.
Fix the camera launch:
public void handleCamera(){ String mediaStorageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath(); String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); fileUri = Uri.fromFile(new java.io.File(mediaStorageDir + java.io.File.separator + "IMG_" + timeStamp + ".jpg")); Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // Actually start the camera and wait for results startActivityForResult(cameraIntent, CAPTURE_IMAGE); }
Then add an onActivityResult method to trigger upload only after the photo is taken:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == CAPTURE_IMAGE && resultCode == RESULT_OK) { // Photo was taken successfully — now upload it save2Drive(); } else { showToast("Photo capture failed or was canceled"); } }
2. Hardcoded account is causing auth failure
The "name must not be empty" error means the system doesn't recognize the hardcoded blogmsr28@gmail.com account. Here's why and how to fix it:
- Ensure the account exists on your device: Your Android device must have
blogmsr28@gmail.comadded as a Google account in Settings > Accounts. If it's not there, the system can't authenticate it. - Stop hardcoding accounts (recommended): Hardcoding is inflexible and error-prone. Use the account picker to let users select their own account:
// Replace your onCreate account setup with this credential = GoogleAccountCredential.usingOAuth2(this, Arrays.asList(new String[]{DriveScopes.DRIVE})); // Launch account picker Intent accountPickerIntent = credential.newChooseAccountIntent(); startActivityForResult(accountPickerIntent, REQUEST_ACCOUNT_PICKER); // Define REQUEST_ACCOUNT_PICKER as 1001
Update onActivityResult to handle the account selection:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch(requestCode) { case REQUEST_ACCOUNT_PICKER: if (resultCode == RESULT_OK && data != null) { String selectedAccount = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME); if (selectedAccount != null) { credential.setSelectedAccountName(selectedAccount); service = getDriveService(credential); // Now start the camera handleCamera(); } } break; case CAPTURE_IMAGE: // Handle photo result as before break; } }
3. Fix Google Play Services resource warning
The The Google Play services resources were not found message means your project isn't properly set up with Google Play Services. Fix this:
- Add these dependencies to your module-level
build.gradle:
implementation 'com.google.android.gms:play-services-auth:20.7.0' implementation 'com.google.apis:google-api-services-drive:v3-rev20240422-2.0.0' implementation 'com.google.api-client:google-api-client-android:2.0.0'
- Add these to your
AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- For older Android versions --> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
4. Handle authorization exceptions properly
Your save2Drive() method catches UserRecoverableAuthIOException but does nothing — this exception requires launching an intent to let users grant permissions. Fix it:
catch (UserRecoverableAuthIOException e) { // Launch the authorization intent startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION); // Define REQUEST_AUTHORIZATION as 1002 }
Original Code (for reference)
public class first extends Activity { static final int CAPTURE_IMAGE = 3; private static Uri fileUri = null; private static Drive service = null; private GoogleAccountCredential credential = null; String accountName = "blogmsr28@gmail.com"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.firstscreen); credential = GoogleAccountCredential.usingOAuth2(this, Arrays.asList(new String[]{DriveScopes.DRIVE})); credential.setSelectedAccountName(accountName); service = getDriveService(credential); showToast(" Inside oncreate"); handleCamera(); save2Drive(); } public void handleCamera(){ String mediaStorageDir = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES).getPath(); String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); fileUri = Uri.fromFile(new java.io.File(mediaStorageDir + java.io.File.separator + "IMG_" + timeStamp + ".jpg")); Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); } public void save2Drive() { Thread t = new Thread(new Runnable() { @Override public void run() { try { java.io.File fileContent = new java.io.File(fileUri.getPath()); FileContent mediaContent = new FileContent("image/jpeg", fileContent); File body = new File(); body.setTitle(fileContent.getName()); body.setMimeType("image/jpeg"); File file = service.files().insert(body, mediaContent).setOcr(true).execute(); if (file != null) { showToast("Photo uploaded: " + file.getTitle()); } } catch (UserRecoverableAuthIOException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }); t.start(); } private Drive getDriveService(GoogleAccountCredential credential) { return new Drive.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), credential) .build(); } public void showToast(final String toast) { runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), toast, Toast.LENGTH_LONG).show(); } }); } }
Original Stack Trace
05-10 14:48:53.074: E/GooglePlayServicesUtil(17592): The Google Play services resources were not found. Check your project configuration to ensure that the resources are included. 05-10 14:48:53.148: E/AndroidRuntime(17592): FATAL EXCEPTION: Thread-11750 05-10 14:48:53.148: E/AndroidRuntime(17592): Process: com.example.drivequickstart, PID: 17592 05-10 14:48:53.148: E/AndroidRuntime(17592): java.lang.IllegalArgumentException: the name must not be empty: null 05-10 14:48:53.148: E/AndroidRuntime(17592): at android.os.Parcel.readException(Parcel.java:1624) 05-10 14:48:53.148: E/AndroidRuntime(17592): at android.os.Parcel.readException(Parcel.java:1573) 05-10 14:48:53.148: E/AndroidRuntime(17592): at com.google.android.gms.internal.o$a$a.a(Unknown Source) 05-10 14:48:53.148: E/AndroidRuntime(17592): at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source) 05-10 14:48:53.148: E/AndroidRuntime(17592): at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source) 05-10 14:48:53.148: E/AndroidRuntime(17592): at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:255) 05-10 14:48:53.148: E/AndroidRuntime(17592): at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:279) 05-10 14:48:53.148: E/AndroidRuntime(17592): at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:858) 05-10 14:48:53.148: E/AndroidRuntime(17592): at com.google.api.client.googleapis.media.MediaHttpUploader.executeCurrentRequest(MediaHttpUploader.java:559) 05-10 14:48:53.148: E/AndroidRuntime(17592): at com.google.api.client.googleapis.media.MediaHttpUploader.executeCurrentRequestWithBackOffAndGZip(MediaHttpUploader.java:581) 05-10 14:48:53.148: E/AndroidRuntime(17592): at com.google.api.client.googleapis.media.MediaHttpUploader.executeUploadInitiation(MediaHttpUploader.java:533) 05-10 14:48:53.148: E/AndroidRuntime(17592): at com.google.api.client.googleapis.media.MediaHttpUploader.resumableUpload(MediaHttpUploader.java:393) 05-10 14:48:53.148: E/AndroidRuntime(17592): at com.google.api.client.googleapis.media.MediaHttpUploader.upload(MediaHttpUploader.java:345)
内容的提问来源于stack exchange,提问作者Rohit S

