我正在构建一个Android应用,并且已经实现了google&facebook auth。 (API级别:19)
问题是:这些身份验证方法在我的模拟电话上可以正常使用,但在实际情况下(例如,真实电话,例如个人电话)却无法使用。
我设法添加了一些带有详细信息的Log.i(),我发现Google登录按钮返回了: com.google.android.gms.common.api.apiException:10 (是的,我知道,stackoverflow上存在有关此错误代码的问题),但我没有使用firebase,只是使用了Google开发人员控制台(console.developers.google.com)。
因此,我将重现对两种auth方法执行的步骤:
Google身份验证:
1)我去了:console.developers.google.com/apis
2)然后单击“创建凭据”按钮
3)选择OAuth客户端ID选项
4)选择Android选项
5)从我的android应用程序中添加了程序包名称(就像:com.xyz.xyz)
6)作为签名证书指纹,我使用了SHA-1 android studio生成的代码(单击右侧按钮“ Gradle”,然后从项目目录中选择“ app”->“ Tasks” ->“ android”->“ signingReport”,复制SHA1生成的代码并使用它。)
7)创建然后在列表中添加的新服务/应用程序(无论它是什么),我复制了其客户端ID并将其粘贴到app / res / values / strings.xml中,如下所示:
<string name="server_client_id">random_numbers-random_numbers_and_letters.apps.googleusercontent.com</string>
Facebook身份验证
1)我去了:developers.facebook.com/apps,那里已经有一些应用程序,所以我只配置了其中一个来支持这个android应用程序
2)我单击设置->基本->添加平台(在页面底部)-> Android
3)然后,我几乎遵循了他们教程中的内容。
在这里我还会有一些问题: 对于我使用的Facebook身份验证,请在app / res / values / strings.xml内
<string name="facebook_app_id">some_generated_numbers</string>
<string name="fb_login_protocol_scheme">fbsome_other_generated_numbers</string>
问题1:fb_login_protocol_scheme字符串值是什么?
问题2:如果没有该应用程序,该应用程序仍然可以运行吗?
问题3:如果我丢失了它,在哪里/如何再次找到它?
这是活动中的xml(facebook和google按钮):
<FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity">
<com.google.android.gms.common.SignInButton android:id="@+id/googleLogin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onClick" android:layout_gravity="center_horizontal" android:layout_marginTop="50dp" />
<com.facebook.login.widget.LoginButton android:id="@+id/facebookLogin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onClick" android:layout_gravity="center_horizontal" android:layout_marginTop="10dp" />
</FrameLayout>
这是登录类中的代码:
package com.xyz.xyz;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.facebook.CallbackManager;
import com.facebook.FacebookCallback;
import com.facebook.FacebookException;
import com.facebook.Profile;
import com.facebook.ProfileTracker;
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.json.JSONException;
import org.json.JSONObject;
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.SignInButton;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.tasks.Task;
public class Login extends AppCompatActivity implements View.OnClickListener {
private Button Login ;
private LoginButton facebookLogin;
private static final String TAG = "AndroidClarified";
private SignInButton googleSignInButton;
private GoogleSignInClient googleSignInClient;
EditText Username , Password;
TextView RegisterLink , Error;
private String reqResponse;
public Parameters parameters;
private CallbackManager callbackManager;
private LoginManager loginManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
callbackManager = CallbackManager.Factory.create();
parameters = new Parameters();
Username = findViewById(R.id.Username);
Password = findViewById(R.id.Password);
Login = findViewById(R.id.Login);
RegisterLink = findViewById(R.id.RegisterLink);
Error = findViewById(R.id.sendTNTErrorMessage);
facebookLogin = findViewById(R.id.facebookLogin);
callbackManager = CallbackManager.Factory.create();
googleSignInButton = findViewById(R.id.googleLogin);
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestId()
.build();
googleSignInClient = GoogleSignIn.getClient(this, gso);
googleSignInButton.setOnClickListener(this);
facebookLogin.setOnClickListener(this);
Login.setOnClickListener(this);
RegisterLink.setOnClickListener(this);
}
@Override
public void onClick(View v){
switch (v.getId()){
case R.id.googleLogin:
Toast.makeText(getApplicationContext(),"LOGIN GOOGLE BUTTON TRIGGERED",Toast.LENGTH_SHORT).show();
signIn();
break;
case R.id.facebookLogin:
Toast.makeText(getApplicationContext(),"LOGIN FACEBOOK BUTTON TRIGGERED",Toast.LENGTH_SHORT).show();
facebookLogin.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
private ProfileTracker mProfileTracker;
@Override
public void onSuccess(LoginResult loginResult) {
if(Profile.getCurrentProfile() == null) {
mProfileTracker = new ProfileTracker() {
@Override
protected void onCurrentProfileChanged(Profile oldProfile, Profile currentProfile) {
OkHttpClient client = new OkHttpClient();
String jsonInputString = "{\"facebookID\":\"" + currentProfile.getId() + "\"}";
final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, jsonInputString);
Request request = new Request.Builder()
.url(parameters.API_URL + parameters.ACCOUNTS_API_MODULE)
.header("API_KEY",parameters.API_KEY)
.put(body)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_SHORT).show();
runOnUiThread(new Runnable() {
@Override
public void run() {
Error.setText("Connection error");
loginManager.getInstance().logOut();
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
reqResponse = response.body().string();
Log.i("GOOD REQUEST : " , reqResponse);
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
JSONObject json = new JSONObject(reqResponse);
Intent intent = new Intent(Login.this, MainActivity.class);
intent.putExtra("accountID",json.getString("accountID"));
intent.putExtra("accountAddress",json.getString("accountAddress"));
intent.putExtra("password",Password.getText().toString());
startActivity(intent);
LoginManager.getInstance().logOut();
} catch (JSONException e) {
e.printStackTrace();
Error.setText(reqResponse);
loginManager.getInstance().logOut();
}
}
});
}
});
mProfileTracker.stopTracking();
}
};
// no need to call startTracking() on mProfileTracker
// because it is called by its constructor, internally.
}
else {
Profile profile = Profile.getCurrentProfile();
}
}
@Override
public void onCancel() {
}
@Override
public void onError(FacebookException e) {
}
});
break;
}
}
private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
try {
GoogleSignInAccount account = completedTask.getResult(ApiException.class);
// Signed in successfully, show authenticated UI.
googleSignInClient.signOut();
} catch (ApiException e) {
final String error = e.toString();
// The ApiException status code indicates the detailed failure reason.
// Please refer to the GoogleSignInStatusCodes class reference for more information.
Log.w(TAG, "signInResult:failed code=" + e.getStatusCode());
runOnUiThread(new Runnable() {
@Override
public void run() {
googleSignInClient.signOut();
Error.setText("API : Connection error");
Error.setText(error);
}
});
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (callbackManager.onActivityResult(requestCode, resultCode, data)) {
return;
}
Log.i("request code : " , requestCode + " resultCode : " + resultCode + " intent : " + data.toString());
Intent result = getIntent();
Log.i("RESULT : " , result.toString());
Log.i(" " , Activity.RESULT_OK + "");
// Result returned from launching the Intent from GoogleSignInClient.getSignInIntent(...);
Toast.makeText(getApplicationContext(),"GONNA CHECK REQUEST CODE",Toast.LENGTH_SHORT).show();
if (requestCode == 101) {
Toast.makeText(getApplicationContext(),"REQUEST CODE IS 101",Toast.LENGTH_SHORT).show();
try {
// The Task returned from this call is always completed, no need to attach
// a listener.
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
GoogleSignInAccount account = task.getResult(ApiException.class);
Log.i("google account - id : ", account.getId());
OkHttpClient client = new OkHttpClient();
String jsonInputString = "{\"googleID\":\"" + account.getId() + "\"}";
Log.i("API REQUEST BODY : ", jsonInputString);
final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, jsonInputString);
Request request = new Request.Builder()
.url(parameters.API_URL + parameters.ACCOUNTS_API_MODULE)
.header("API_KEY", parameters.API_KEY)
.put(body)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_SHORT).show();
runOnUiThread(new Runnable() {
@Override
public void run() {
Error.setText("API : Connection error");
googleSignInClient.signOut();
Toast.makeText(getApplicationContext(),"API FAILURE",Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
reqResponse = response.body().string();
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
JSONObject json = new JSONObject(reqResponse);
Intent intent = new Intent(Login.this, MainActivity.class);
intent.putExtra("accountID", json.getString("accountID"));
intent.putExtra("accountAddress", json.getString("accountAddress"));
intent.putExtra("password", Password.getText().toString());
startActivity(intent);
googleSignInClient.signOut();
} catch (JSONException e) {
Error.setText(reqResponse);
e.printStackTrace();
googleSignInClient.signOut();
}
}
});
}
});
} catch (ApiException e) {
// The ApiException status code indicates the detailed failure reason.
Log.w(TAG, "signInResult:failed code=" + e.getStatusCode());
Toast.makeText(getApplicationContext(),e.toString(),Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void onStart() {
super.onStart();
GoogleSignInAccount alreadyloggedAccount = GoogleSignIn.getLastSignedInAccount(this);
if (alreadyloggedAccount != null)
Toast.makeText(this, "Already Logged In", Toast.LENGTH_SHORT).show();
// Check for existing Google Sign In account, if the user is already signed in
// the GoogleSignInAccount will be non-null.
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
googleSignInClient.signOut();
}
private void signIn() {
Intent signInIntent = googleSignInClient.getSignInIntent();
startActivityForResult(signInIntent, 101);
}
}
非常感谢您的帮助和时间。
P.S:这是依赖项:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//noinspection GradleCompatible
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:customtabs:28.0.0'
implementation 'com.facebook.android:facebook-android-sdk:[4,5)'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.google.android.gms:play-services-auth:15.0.1'
implementation 'com.android.support:design:28.0.0'
implementation 'com.squareup.okhttp3:okhttp:3.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}