小编典典

Google Drive SDK错误

java

这是我的代码来访问谷歌驱动器,从很大程度上采取 ArtOfWarfare在这个帖子:

public class MainActivity extends Activity {
    class OnTokenAcquired implements AccountManagerCallback<Bundle> {
        boolean alreadyTriedAgain;
        public OnTokenAcquired() {
            // TODO Auto-generated constructor stub
        }
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (requestCode == 3025) {
                switch (resultCode) {
                case RESULT_OK:
                    AccountManager am = AccountManager.get(getApplicationContext());
                    am.getAuthToken(am.getAccounts()[0],
                            "ouath2:" + DriveScopes.DRIVE,
                            new Bundle(),
                            true,
                            new OnTokenAcquired(),
                            null);
                    break;
                case RESULT_CANCELED:
                    // This probably means the user refused to log in. Explain to them why they need to log in.
                    break;
                default:
                    // This isn't expected... maybe just log whatever code was returned.
                    break;
                }
            } else {
                // Your application has other intents that it fires off besides the one for Drive's log in if it ever reaches this spot. Handle it here however you'd like.
            }
        }
        @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("my number here");
                        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");
                File newFile = new File("this");
                final FileContent mediaContent = new FileContent("text/plain", newFile);
                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(getApplicationContext());
                                am.invalidateAuthToken(am.getAccounts()[0].type, null); // Requires the permissions MANAGE_ACCOUNTS & USE_CREDENTIALS in the Manifest
                                am.getAuthToken(am.getAccounts()[0],
                                        "ouath2:" + DriveScopes.DRIVE,
                                        new Bundle(),
                                        true,
                                        new OnTokenAcquired(),
                                        null);
                            } 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...
            }
        }

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

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

                InputStream inputStream = response.getEntity().getContent();
                jFolder.mkdirs();
                java.io.File jFile = new java.io.File(jFolder.getAbsolutePath() + "/" + gFile.getName()); // 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;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getApplicationContext();
        AccountManager am = AccountManager.get(this);
        am.getAuthToken(am.getAccounts()[0],
                "ouath2:" + DriveScopes.DRIVE,
                new Bundle(),
                true,
                new OnTokenAcquired(),
                null);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

}

启动应用程序时出现以下错误(Android系统也会立即停止):

11-26 22:31:03.093: E/AndroidRuntime(4288): FATAL EXCEPTION: main
11-26 22:31:03.093: E/AndroidRuntime(4288): java.lang.RuntimeException: Unable to start activity ComponentInfo{android/android.accounts.GrantCredentialsPermissionActivity}: java.lang.NullPointerException
11-26 22:31:03.093: E/AndroidRuntime(4288):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2225)
11-26 22:31:03.093: E/AndroidRuntime(4288):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2260)
11-26 22:31:03.093: E/AndroidRuntime(4288):     at android.app.ActivityThread.access$600(ActivityThread.java:139)
11-26 22:31:03.093: E/AndroidRuntime(4288):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1277)
11-26 22:31:03.093: E/AndroidRuntime(4288):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-26 22:31:03.093: E/AndroidRuntime(4288):     at android.os.Looper.loop(Looper.java:156)
11-26 22:31:03.093: E/AndroidRuntime(4288):     at android.app.ActivityThread.main(ActivityThread.java:5045)
11-26 22:31:03.093: E/AndroidRuntime(4288):     at java.lang.reflect.Method.invokeNative(Native Method)
11-26 22:31:03.093: E/AndroidRuntime(4288):     at java.lang.reflect.Method.invoke(Method.java:511)
11-26 22:31:03.093: E/AndroidRuntime(4288):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
11-26 22:31:03.093: E/AndroidRuntime(4288):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
11-26 22:31:03.093: E/AndroidRuntime(4288):     at dalvik.system.NativeStart.main(Native Method)
11-26 22:31:03.093: E/AndroidRuntime(4288): Caused by: java.lang.NullPointerException
11-26 22:31:03.093: E/AndroidRuntime(4288):     at android.accounts.GrantCredentialsPermissionActivity.onCreate(GrantCredentialsPermissionActivity.java:84)
11-26 22:31:03.093: E/AndroidRuntime(4288):     at android.app.Activity.performCreate(Activity.java:4543)
11-26 22:31:03.093: E/AndroidRuntime(4288):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1071)
11-26 22:31:03.093: E/AndroidRuntime(4288):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2181)
11-26 22:31:03.093: E/AndroidRuntime(4288):     ... 11 more

此外,我的手机显示了一个奇怪的通知:"Permission Requested for account Weather"。有人知道是什么原因造成的吗?


阅读 310

收藏
2020-11-26

共1个答案

小编典典

尝试替换此:

am.getAccounts()[0],

有了这个:

am.getAccountsByType("com.google")[0],

我在另一个主题中的代码经过了简化,假设它找到的第一个帐户是Google帐户(因此也有Google
Drive)。我们在应用中实际使用的代码经过检查以确保它是一个Google帐户(然后进行进一步检查以确保它是一个公司帐户,这就是为什么我将代码简化为共享的原因。)

2020-11-26