应用程序崩溃选择Gmail帐户oAuth2后?

时间:2016-08-16 07:03:45

标签: java android oauth google-oauth google-oauth2

所以我终于实现了用户选择在我尝试做oAuth2时使用哪个gmail帐户的能力....我有几个oAuth2问题,但遗憾的是没有得到答案..无论如何我点击了标志后在按钮中,系统会提示我选择哪个gmail帐户。但是,在我选择它并点击“确定”后,应用程序崩溃了。但是,我不确定为什么。

这是我的MainActivity.java

<activity />

这是给出的错误。

public class MainActivity extends AppCompatActivity{

    Context mContext = MainActivity.this;
    private AccountManager mAccountManager;
    private AuthPreferences authPreferences;
    String[] avail_accounts;
    ListView list;
    ArrayAdapter<String> adapter;
    EditText emailText;
    TextView responseView;
    ProgressBar progressBar;
    SharedPreferences pref;
    static final String API_KEY = "USE_YOUR_OWN_API_KEY";
    static final String API_URL = "https://api.fullcontact.com/v2/person.json?";
    static final String ClientId= "45471411055-m902j8c6jo4v6mndd2jiuqkanjsvcv6j.apps.googleusercontent.com";
    static final String ClientSecret = "it5cGajZGSHQw5-e2kn2zL_R";
    static final String SCOPE = "https://www.googleapis.com/auth/userinfo.email";
    static final String AuthUrl = "https://accounts.google.com/o/oauth2/token";
    private static final int AUTHORIZATION_CODE = 1993;
    private static final int ACCOUNT_CODE = 1601;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        responseView = (TextView) findViewById(R.id.responseView);
        emailText = (EditText) findViewById(R.id.emailText);
        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        final Context context = this;
        mAccountManager = AccountManager.get(this);
        authPreferences = new AuthPreferences(this);


        SignInButton signInButton = (SignInButton) findViewById(R.id.sign_in_button);
        signInButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(authPreferences.getUser() != null && authPreferences.getToken() !=null)
                {
                    doCoolAuthenticatedStuff();
                }else
                {
                    chooseAccount();
                }
            }
        });
        Button queryButton = (Button) findViewById(R.id.queryButton);

        queryButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new RetrieveFeedTask().execute();

                if(isNetworkAvailable()==true)
                {
                    Intent intent = new Intent(context, NavDrawerActivity.class);
                    startActivity(intent);
                }else {
                    Toast.makeText(MainActivity.this, "No Network Service, please check your WiFi or Mobile Data Connection", Toast.LENGTH_SHORT).show();
                }
            }
        });

        SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);
        boolean dontShowDialog = sharedPref.getBoolean("DONT_SHOW_DIALOG", false);
        if (!dontShowDialog) {
            WifivsDataDialog myDiag = new WifivsDataDialog();
            myDiag.show(getFragmentManager(), "WiFi");
            myDiag.setCancelable(false);
        }
    }

    private void doCoolAuthenticatedStuff()
    {
        Log.e("AuthApp", authPreferences.getToken());
    }

    private void chooseAccount()
    {
        Intent intent = AccountManager.newChooseAccountIntent(null, null,new String[] { "com.google"}, false, null, null, null, null);
        startActivityForResult(intent, ACCOUNT_CODE);
    }

    private void requestToken()
    {
        Account userAccount = null;
        String user = authPreferences.getUser();
        for (Account account : mAccountManager.getAccountsByType("com.google")) {
            if (account.name.equals(user)) {
                userAccount = account;

                break;
            }
        }

        mAccountManager.getAuthToken(userAccount, "oauth2:" + SCOPE, null, this,
                new OnTokenAcquired(), null);
    }

    private void invalidateToken()
    {
        AccountManager mAccountManager = AccountManager.get(this);
        mAccountManager.invalidateAuthToken("com.google", authPreferences.getToken());
        authPreferences.setToken(null);

    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_OK) {
            if (requestCode == AUTHORIZATION_CODE) {
                requestToken();
            } else if (requestCode == ACCOUNT_CODE) {
                String accountName = data
                        .getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
                authPreferences.setUser(accountName);

                // invalidate old tokens which might be cached. we want a fresh
                // one, which is guaranteed to work
                invalidateToken();

                requestToken();
            }
        }
    }

    private class OnTokenAcquired implements AccountManagerCallback<Bundle>
    {
        @Override
        public void run(AccountManagerFuture<Bundle> result)
        {
            try {
                Bundle bundle = result.getResult();
                Intent launch = (Intent) bundle.get(AccountManager.KEY_INTENT);
                if(launch != null)
                {
                    startActivityForResult(launch, AUTHORIZATION_CODE);
                } else {
                    String token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
                    authPreferences.setToken(token);
                    doCoolAuthenticatedStuff();
                }
            } catch (Exception e){
                Log.e("ERROR", e.getMessage(), e);
            }
        }
    }

    public boolean isNetworkAvailable()
    {
        ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = cm.getActiveNetworkInfo();
        if(networkInfo != null && networkInfo.isConnected())
        {
            Log.e("Network Testing", "Available");
            return true;
        }
        Log.e("Network Testing", "Not Available");
        return false;
    }

    class RetrieveFeedTask extends AsyncTask<Void, Void, String> {

        private Exception exception;

        protected void onPreExecute() {
            progressBar.setVisibility(View.VISIBLE);
            responseView.setText("");
        }

        protected String doInBackground(Void... urls) {
            String email = emailText.getText().toString();
            // Do some validation here

            try {
                URL url = new URL(API_URL + "email=" + email + "&apiKey=" + API_KEY);

                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                try {
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                    StringBuilder stringBuilder = new StringBuilder();
                    String line;
                    while ((line = bufferedReader.readLine()) != null) {
                        stringBuilder.append(line).append("\n");
                    }
                    bufferedReader.close();
                    return stringBuilder.toString();
                }
                finally{
                    urlConnection.disconnect();
                }
            }
            catch(Exception e) {
                Log.e("ERROR", e.getMessage(), e);
                return null;
            }
        }

        protected void onPostExecute(String response) {
            if(response == null) {
                response = "THERE WAS AN ERROR";
            }
            progressBar.setVisibility(View.GONE);
            Log.i("INFO", response);
            responseView.setText(response);
            //
            // TODO: check this.exception
            // TODO: do something with the feed

//            try {
//                JSONObject object = (JSONObject) new JSONTokener(response).nextValue();
//                String requestID = object.getString("requestId");
//                int likelihood = object.getInt("likelihood");
//                JSONArray photos = object.getJSONArray("photos");
//                .
//                .
//                .
//                .
//            } catch (JSONException e) {
//                e.printStackTrace();
//            }
        }
    }


}

如果有人有任何想法,那将非常感激。此外,我还需要使用选定的Gmail帐户执行oAuth2。

这是我的AndroidManifest.xml

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.example.jamessingleton.chffrapi, PID: 2025
                  java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1601, result=-1, data=Intent {  VirtualScreenParam=Params{mDisplayId=-1, null, mFlags=0x00000000)}(has extras) }} to activity {com.example.jamessingleton.chffrapi/com.example.jamessingleton.chffrapi.MainActivity}: java.lang.IllegalArgumentException: account is null
                      at android.app.ActivityThread.deliverResults(ActivityThread.java:4920)
                      at android.app.ActivityThread.handleSendResult(ActivityThread.java:4963)
                      at android.app.ActivityThread.access$1600(ActivityThread.java:221)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1848)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:158)
                      at android.app.ActivityThread.main(ActivityThread.java:7224)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
                   Caused by: java.lang.IllegalArgumentException: account is null
                      at android.accounts.AccountManager.getAuthToken(AccountManager.java:1267)
                      at com.example.jamessingleton.chffrapi.MainActivity.requestToken(MainActivity.java:152)
                      at com.example.jamessingleton.chffrapi.MainActivity.onActivityResult(MainActivity.java:181)
                      at android.app.Activity.dispatchActivityResult(Activity.java:7137)
                      at android.app.ActivityThread.deliverResults(ActivityThread.java:4916)
                      at android.app.ActivityThread.handleSendResult(ActivityThread.java:4963) 
                      at android.app.ActivityThread.access$1600(ActivityThread.java:221) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1848) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:158) 
                      at android.app.ActivityThread.main(ActivityThread.java:7224) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

这是我的AuthPreferences.java

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.jamessingleton.chffrapi">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCOUNT_MANAGER" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.USE_CREDENTIALS" />
    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <meta-data android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version"/>

        <meta-data android:name="com.google.android.geo.API_KEY" android:value=""/>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".NavDrawerActivity"
            android:label="@string/title_activity_nav_drawer"
            android:theme="@style/AppTheme.NoActionBar"></activity>
    </application>

</manifest>

1 个答案:

答案 0 :(得分:0)

适用于Java的Drive API客户端库调用GoogleAuthUtil.getToken(),这需要GET_ACCOUNTS权限。您需要在清单文件中拥有该权限。