Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/184.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
android应用程序的跨客户端google oauth2.0,带有用于脱机访问的后端服务器_Android_Oauth 2.0_Google Oauth_Access Token - Fatal编程技术网

android应用程序的跨客户端google oauth2.0,带有用于脱机访问的后端服务器

android应用程序的跨客户端google oauth2.0,带有用于脱机访问的后端服务器,android,oauth-2.0,google-oauth,access-token,Android,Oauth 2.0,Google Oauth,Access Token,我正在开发一个android应用程序,它可以从用户的youtube帐户获取数据,并且还需要在脱机模式下这样做。为此,我应该实现google的oauth2.0跨客户端身份验证()机制。 我能够获取IdToken,但对于一次exchange token(),它返回null。 请帮我解决这个问题。 先谢谢你。。。 这是我的密码 package com.example.sampleapp; import java.util.Arrays; import java.util.List; import

我正在开发一个android应用程序,它可以从用户的youtube帐户获取数据,并且还需要在脱机模式下这样做。为此,我应该实现google的oauth2.0跨客户端身份验证()机制。 我能够获取IdToken,但对于一次exchange token(),它返回null。 请帮我解决这个问题。 先谢谢你。。。 这是我的密码

package com.example.sampleapp;

import java.util.Arrays;
import java.util.List;

import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.android.gms.common.AccountPicker;
import android.support.v7.app.ActionBarActivity;
import android.text.TextUtils;
import android.accounts.AccountManager;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

final private String CLIENT_ID = "12345----.apps.googleusercontent.com";
static final int REQUEST_CODE_PICK_ACCOUNT = 1000;
private String mEmail;
//private static final String SCOPE =
  //      "oauth2:https://www.googleapis.com/auth/userinfo.profile";

final private List<String> SCOPES = Arrays.asList(new String[]{
          "https://www.googleapis.com/auth/plus.login",
          "https://www.googleapis.com/auth/youtube"});

 private EditText mExchangeCodeEditText;
  private EditText mIdTokenEditText;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

     mExchangeCodeEditText = (EditText) findViewById(R.id.editTextExchangeCode);
        mIdTokenEditText = (EditText) findViewById(R.id.editTextIdToken);

Button b1=(Button) findViewById(R.id.button1);
b1.setOnClickListener(new View.OnClickListener(){

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub

//      static final int REQUEST_CODE_PICK_ACCOUNT = 1000;

        String[] accountTypes = new String[]{"com.google"};
        Intent intent = AccountPicker.newChooseAccountIntent(null, null,
                accountTypes, false, null, null, null, null);
        startActivityForResult(intent, REQUEST_CODE_PICK_ACCOUNT);          
    }
});



}

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

@Override   public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
        // Receiving a result from the AccountPicker
        if (resultCode == RESULT_OK) {
            mEmail = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
            // With the account name acquired, go get the auth token
      //      getUsername();
            Log.v("MY_UNAME",mEmail);
            new RetrieveJwtAsyncTask().execute();
            new RetrieveExchangeCodeAsyncTask().execute();
        } else if (resultCode == RESULT_CANCELED) {
            // The account picker dialog closed without selecting an account.
            // Notify users that they must pick an account to proceed.
            Toast.makeText(this, R.string.pick_account, Toast.LENGTH_SHORT).show();
        }
    }
    // Later, more code will go here to handle the result from some exceptions...
}


 public class RetrieveJwtAsyncTask
 extends AsyncTask<Void, Boolean, String> {

   @Override
  protected String doInBackground(Void... params) {
  String scope = "audience:server:client_id:" + CLIENT_ID;
  try {
   return GoogleAuthUtil.getToken(
       MainActivity.this, mEmail, scope);
  } catch (Exception e) {
   e.printStackTrace(); // TODO: handle the exception
  }
  return null;
 }

  @Override
  protected void onPostExecute(String idToken) {
  // exchange encrypted idToken with server-side to identify the user
   mIdTokenEditText.setText(idToken);
  Log.v("Second One","  "+ idToken);

  }
 }

 public class RetrieveExchangeCodeAsyncTask
 extends AsyncTask<Void, Boolean, String> {



 @Override
 protected String doInBackground(Void... params) {
 String scope = String.format("oauth2:server:client_id:%s:api_scope:%s",
     CLIENT_ID, TextUtils.join(" ", SCOPES));
 try {
   return GoogleAuthUtil.getToken(
       MainActivity.this, mEmail, scope);

 } catch (Exception e) {
   e.printStackTrace(); // TODO: handle the exception
  }
 return null;
 }

 @Override
 protected void onPostExecute(String code) {
 // exchange code with server-side to retrieve an additional
 // access token on the server-side.
 Log.v("first One","1"+ code);
 mExchangeCodeEditText.setText(code);
  }
 }

} 
package com.example.sampleapp;
导入java.util.array;
导入java.util.List;
导入com.google.android.gms.auth.GoogleAuthUtil;
导入com.google.android.gms.auth.UserRecoverableAuthException;
导入com.google.android.gms.common.AccountPicker;
导入android.support.v7.app.ActionBarActivity;
导入android.text.TextUtils;
导入android.accounts.AccountManager;
导入android.content.Intent;
导入android.os.AsyncTask;
导入android.os.Bundle;
导入android.util.Log;
导入android.view.Menu;
导入android.view.MenuItem;
导入android.view.view;
导入android.widget.Button;
导入android.widget.EditText;
导入android.widget.Toast;
公共类MainActivity扩展了ActionBarActivity{
最终私有字符串客户端\u ID=“12345---.apps.googleusercontent.com”;
静态最终整数请求\代码\选择\帐户=1000;
私有字符串mEmail;
//私有静态最终字符串作用域=
//“oauth2:https://www.googleapis.com/auth/userinfo.profile";
最终私有列表范围=Arrays.asList(新字符串[]){
"https://www.googleapis.com/auth/plus.login",
"https://www.googleapis.com/auth/youtube"});
私有EditText mExchangeCodeEditText;
私有EditText中间标记EditText;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mExchangeCodeEditText=(EditText)findViewById(R.id.editTextExchangeCode);
mIdTokenEditText=(EditText)findViewById(R.id.editTextIdToken);
按钮b1=(按钮)findViewById(R.id.button1);
b1.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
//TODO自动生成的方法存根
//静态最终整数请求\代码\选择\帐户=1000;
String[]accountTypes=新字符串[]{“com.google”};
Intent Intent=AccountPicker.newchooseAccountContent(null,null,
accountTypes,false,null,null,null,null);
startActivityForResult(意向、请求、代码、选择账户);
}
});
}
@凌驾
公共布尔onCreateOptions菜单(菜单){
//为菜单充气;这会将项目添加到操作栏(如果存在)。
getMenuInflater().充气(R.menu.main,menu);
返回true;
}
@覆盖公共布尔值OnOptions项Selected(MenuItem项){
//处理操作栏项目单击此处。操作栏将
//自动处理Home/Up按钮上的点击,只要
//在AndroidManifest.xml中指定父活动时。
int id=item.getItemId();
if(id==R.id.action\u设置){
返回true;
}
返回super.onOptionsItemSelected(项目);
}
@凌驾
受保护的void onActivityResult(int请求代码、int结果代码、意图数据){
if(requestCode==请求\代码\选择\帐户){
//从AccountPicker接收结果
if(resultCode==RESULT\u OK){
mEmail=data.getStringExtra(AccountManager.KEY\u ACCOUNT\u NAME);
//获取帐户名后,获取身份验证令牌
//getUsername();
Log.v(“MY_UNAME”,mEmail);
新建RetrieveJwtAsyncTask().execute();
新建RetrieveExchangeCodeAsyncTask().execute();
}else if(resultCode==RESULT\u取消){
//帐户选择器对话框关闭,但未选择帐户。
//通知用户必须选择一个帐户才能继续。
Toast.makeText(this,R.string.pick_account,Toast.LENGTH_SHORT).show();
}
}
//稍后,更多代码将转到此处处理某些异常的结果。。。
}
公共类RetrieveJwtAsyncTask
扩展异步任务{
@凌驾
受保护字符串doInBackground(无效…参数){
String scope=“受众:服务器:客户机id:+客户机id;
试一试{
返回GoogleAuthUtil.getToken(
MainActivity.this、mEmail、scope);
}捕获(例外e){
e、 printStackTrace();//TODO:处理异常
}
返回null;
}
@凌驾
受保护的void onPostExecute(字符串idToken){
//与服务器端交换加密的idToken以标识用户
mIdTokenEditText.setText(idToken);
Log.v(“第二个”,即“+idToken”);
}
}
公共类RetrieveExchangeCodeAsyncTask
扩展异步任务{
@凌驾
受保护字符串doInBackground(无效…参数){
String scope=String.format(“oauth2:server:client\u id:%s:api\u scope:%s”,
CLIENT_ID,TextUtils.join(“,SCOPES));
试一试{
返回GoogleAuthUtil.getToken(
MainActivity.this、mEmail、scope);
}捕获(例外e){
e、 printStackTrace();//TODO:处理异常
}
返回null;
}
@凌驾
受保护的void onPostExecute(字符串代码){
//与服务器端交换代码以检索其他
//服务器端的访问令牌。
Log.v(“第一个”,“1”+代码);
mExchangeCodeEditText.setText(代码);
}
}
} 

类RetrieveJwtAsyncTask运行正常,但类RetrieveExchangeCodeAsyncTask返回null,而不是在上述代码段中引用为“代码”的一次性访问代码。

我没有在开发人员控制台中正确注册我的应用程序。修复后,我的问题解决了,上面的代码正常工作。

您可以将其作为答案提交并接受。