问题
I am working on a project where user can upload a document to my server. This file can be selected either from local storage or a cloud storage ,say google drive. When i click on the file from file chooser all i am receiving is an account info and doc info as a uri, When i tried to fetch doc from this URI it is showing FileNotFound . I have gone through Drive API also but It is a bit confusing to me. Following are the points i came accross while trying Google Drive API: 1. How to select file from local storage. 2. How do I get FileId form the selected file.
I tried with the following code snippet:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("**/");
startActivityForResult(intent, 1000);
and In onActivityResult
@Override
public void onActivityResult(int requestCode, int resultCode,
Intent resultData) {
// The ACTION_OPEN_DOCUMENT intent was sent with the request code
// READ_REQUEST_CODE. If the request code seen here doesn't match, it's the
// response to some other intent, and the code below shouldn't run at all.
if (requestCode == 1000 && resultCode == Activity.RESULT_OK) {
// The document selected by the user won't be returned in the intent.
// Instead, a URI to that document will be contained in the return intent
// provided to this method as a parameter.
// Pull that URI using resultData.getData().
Uri uri = null;
if (resultData != null) {
uri = resultData.getData();
Log.i("URI", "Uri: " + uri.toString());
try {
readTextFromUri(uri);
getMimeType(this,uri);
} catch (IOException e) {
e.printStackTrace();
}
// showImage(uri);
}
}
}
private String readTextFromUri(Uri uri) throws IOException {
// FileInputStream fileInputStream=new FileInputStream(uri.)
InputStream inputStream = getContentResolver().openInputStream(uri);
BufferedReader reader = new BufferedReader(new InputStreamReader(
inputStream));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
// fileInputStream.close();
// parcelFileDescriptor.close();
return stringBuilder.toString();
}
Conclusion:
Can anyone please send me a link how to upload a document(I should even check the extension of the document) from both local storage and Google drive in a File chooser.
回答1:
package com.example.ayyappaboddupalli.gdrive;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.drive.DriveClient;
import com.google.android.gms.drive.DriveContents;
import com.google.android.gms.drive.DriveFile;
import com.google.android.gms.drive.DriveId;
import com.google.android.gms.drive.DriveResourceClient;
import com.google.android.gms.drive.OpenFileActivityOptions;
import com.google.android.gms.drive.query.Filters;
import com.google.android.gms.drive.query.SearchableField;
import com.google.android.gms.tasks.Continuation;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.TaskCompletionSource;
import com.google.api.services.drive.model.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashSet;
import java.util.Set;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Google drive";
private static final String SIGN_IN = "Sign In";
private static final String DOWNLOAD_FILE = "Download file";
private static final int REQUEST_CODE_SIGN_IN = 0;
private static final int REQUEST_CODE_OPEN_ITEM = 1;
private static final int REQUEST_WRITE_STORAGE = 112;
private GoogleSignInAccount signInAccount;
private Set<Scope> requiredScopes;
private DriveClient mDriveClient;
private DriveResourceClient mDriveResourceClient;
private OpenFileActivityOptions openOptions;
private TaskCompletionSource<DriveId> mOpenItemTaskSource;
private java.io.File storageDir;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView( R.layout.activity_main);
initialize();
requestPermission();
signInAccount = GoogleSignIn.getLastSignedInAccount(this);
if (signInAccount != null && signInAccount.getGrantedScopes().containsAll(requiredScopes)) {
initializeDriveClient(signInAccount);
} else {
// onDriveClientReady();
signIn();
}
Button button=(Button)findViewById(R.id.Submit);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onDriveClientReady();
}
});
}
private void showMessage(String message) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_CODE_SIGN_IN:
if (resultCode == RESULT_OK) {
Task<GoogleSignInAccount> getAccountTask = GoogleSignIn.getSignedInAccountFromIntent(data);
if (getAccountTask.isSuccessful()) {
initializeDriveClient(getAccountTask.getResult());
showMessage("Sign in successfully.");
// binding.btnSubmit.setText(DOWNLOAD_FILE);
} else {
showMessage("Sign in failed.");
}
} else {
showMessage("Sign in failed.");
}
break;
case REQUEST_CODE_OPEN_ITEM:
if (resultCode == RESULT_OK) {
DriveId driveId = data.getParcelableExtra(OpenFileActivityOptions.EXTRA_RESPONSE_DRIVE_ID);
mOpenItemTaskSource.setResult(driveId);
} else {
mOpenItemTaskSource.setException(new RuntimeException("Unable to open file"));
}
break;
}
}
private void initialize() {
requiredScopes = new HashSet<>(2);
requiredScopes.add(Drive.SCOPE_FILE);
requiredScopes.add(Drive.SCOPE_APPFOLDER);
openOptions = new OpenFileActivityOptions.Builder()
.setSelectionFilter(Filters.eq(SearchableField.MIME_TYPE, "application/pdf"))
.setActivityTitle("Select file")
.build();
}
private void initializeDriveClient(GoogleSignInAccount signInAccount) {
mDriveClient = Drive.getDriveClient(getApplicationContext(), signInAccount);
mDriveResourceClient = Drive.getDriveResourceClient(getApplicationContext(), signInAccount);
}
private void signIn() {
GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestScopes(Drive.SCOPE_FILE)
.requestScopes(Drive.SCOPE_APPFOLDER)
.build();
GoogleSignInClient googleSignInClient = GoogleSignIn.getClient(this, signInOptions);
startActivityForResult(googleSignInClient.getSignInIntent(), REQUEST_CODE_SIGN_IN);
}
private void onDriveClientReady() {
mOpenItemTaskSource = new TaskCompletionSource<>();
mDriveClient.newOpenFileActivityIntentSender(openOptions)
.continueWith(new Continuation<IntentSender, Void>() {
@Override
public Void then(@NonNull Task<IntentSender> task) throws Exception {
startIntentSenderForResult(
task.getResult(), REQUEST_CODE_OPEN_ITEM, null, 0, 0, 0);
return null;
}
});
Task<DriveId> tasks = mOpenItemTaskSource.getTask();
tasks.addOnSuccessListener(this,
new OnSuccessListener<DriveId>() {
@Override
public void onSuccess(DriveId driveId) {
retrieveContents(driveId.asDriveFile());
}
})
.addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
showMessage("File not selected.");
}
});
}
private void retrieveContents(final DriveFile file) {
// [START open_file]
final Task<DriveContents> openFileTask = mDriveResourceClient.openFile(file, DriveFile.MODE_READ_ONLY);
// [END open_file]
// [START read_contents]
openFileTask.continueWithTask(new Continuation<DriveContents, Task<Void>>() {
@Override
public Task<Void> then(@NonNull Task<DriveContents> task) throws Exception {
DriveContents contents = task.getResult();
Log.v(TAG, "File name : " + contents.toString());
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
InputStream input = contents.getInputStream();
try {
java.io.File file = new java.io.File(getExternalFilesDir(null), "umesh.pdf");
Log.v(TAG, storageDir + "");
OutputStream output = new FileOutputStream(file);
try {
try {
byte[] buffer = new byte[4 * 1024]; // or other buffer size
int read;
while ((read = input.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
} finally {
output.close();
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
showMessage("Download file successfully.");
return mDriveResourceClient.discardContents(contents);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
showMessage("Unable to download file.");
}
});
// [END read_contents]
}
private void requestPermission() {
String dirPath = getFilesDir().getAbsolutePath() + java.io.File.separator + "PDF";
storageDir = new java.io.File(dirPath);
if (!storageDir.exists())
storageDir.mkdirs();}}
//in gradle
implementation 'com.google.android.gms:play-services:11.8.0'
compile 'com.google.android.gms:play-services-auth:11.8.0'
compile 'com.google.api-client:google-api-client:1.23.0'
compile 'com.google.oauth-client:google-oauth-client-jetty:1.23.0'
compile 'com.google.apis:google-api-services-drive:v3-rev110-1.23.0'
来源:https://stackoverflow.com/questions/50208956/unable-to-fetch-file-from-google-drive