首页 文章 精选 留言 我的

精选列表

搜索[桌面应用程序],共10000篇文章
优秀的个人博客,低调大师

Android 应用程序集成FaceBook 登录及二次封装

1、首先在Facebook 开发者平台注册一个账号 https://developers.facebook.com/ 开发者后台 https://developers.facebook.com/apps 2、创建账号并且获得 APP ID 图一 图二 图三 图四 图五 3、获取app签名的Key Hashes 值(两种方式) 3.1方法1: 1 package com.pegasus.map.presentation.utils; 2 import android.content.Context; 3 import android.content.pm.PackageInfo; 4 import android.content.pm.PackageManager; 5 import android.content.pm.Signature; 6 import android.util.Base64; 7 import android.widget.Toast; 8 import java.security.MessageDigest; 9 import java.security.NoSuchAlgorithmException; 10 11 /** 12 * Created by ${zyj} on 2016/3/29. 13 */ 14 public class KeyHash { 15 16 /** 17 * 注意运行的时候,app需要正式的签名 18 * @param context 19 * @param packageName app的包名 20 */ 21 public static void getKeyHash( Context context , String packageName ){ 22 try { 23 PackageInfo info = null; 24 info = context.getPackageManager().getPackageInfo( packageName , PackageManager.GET_SIGNATURES ); 25 for ( Signature signature : info.signatures ) { 26 MessageDigest messageDigest = null; 27 messageDigest = MessageDigest.getInstance("SHA"); 28 messageDigest.update(signature.toByteArray()); 29 String hs = Base64.encodeToString(messageDigest.digest(), Base64.DEFAULT) ; 30 Toast.makeText(context, "" + hs , Toast.LENGTH_SHORT).show(); 31 } 32 } catch (PackageManager.NameNotFoundException e) { 33 e.printStackTrace(); 34 } catch (NoSuchAlgorithmException e) { 35 e.printStackTrace(); 36 } 37 } 38 } 3.2 命令行的方式获取 Key hash 值 3.2.1 :首选保证你的电脑上有 openSSl 的库文件 下载 http://gnuwin32.sourceforge.net/packages/openssl.htm 3.2.2 :解压下载的文件 3.2.3:cmd 命令行模式定位到 openssl 的 bin目录下 3.2.4:执行命令 keytool -exportcert -alias yiba -keystore C:\work\Key.jks | openssl sha1 -binary | openssl base64 注意: 1、这里的 yiba 代表app签名的别名,也就是alias 2、C:\work\Key.jks 代表签名的路径,需要换成你签名的路径 3.2.5 如果你的电脑上没有下载 openssl 那么你执行下面的代码会出现 4、设置应用的基本配置 图一 图二 图三 5、App开始集成 FacebookSDk 5.1 在项目的 build.gradle 添加 compile 'com.facebook.android:facebook-android-sdk:4.10.1' 查看最新的版本 :http://search.maven.org/#search%7Cga%7C1%7Ccom.facebook.android 5.2 在应用的 Application 里面初始化SDK //facebook登录初始化 FacebookSdk.sdkInitialize( getApplicationContext() ); 5.3 在value文件夹下 strings.xml 中 <!-- facebook 登录 key--> <string name="facebook_app_id">1001702146573854</string> 5.4 在 AndroidManifest.xml 中 <meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/> <activity android:name="com.facebook.FacebookActivity" android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:label="@string/app_name" ></activity> 5.5 在布局文件中定义登录按钮 <com.facebook.login.widget.LoginButton android:id="@+id/facebook_bt" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="facebook login" > </com.facebook.login.widget.LoginButton> 5.6 在代码中实现 1 package com.pegasus.map.presentation.ui.activity; 2 import android.content.Intent; 3 import android.os.Bundle; 4 import android.widget.Toast; 5 import com.facebook.CallbackManager; 6 import com.facebook.FacebookCallback; 7 import com.facebook.FacebookException; 8 import com.facebook.login.LoginResult; 9 import com.facebook.login.widget.LoginButton; 10 import com.pegasus.map.R; 11 import com.pegasus.map.presentation.ui.base.BaseActivity; 12 import butterknife.Bind; 13 import butterknife.ButterKnife; 14 15 16 /** 17 * Created by ${zyj} on 2016/3/24. 18 * 登录 19 */ 20 21 public class LoginLoginActivity extends BaseActivity { 22 23 @Bind(R.id.facebook_bt) 24 public LoginButton facebook_bt; 25 26 private CallbackManager callbackManager ; 27 28 @Override 29 protected void onCreate(Bundle savedInstanceState) { 30 super.onCreate(savedInstanceState); 31 setContentView(R.layout.activity_login); 32 33 ButterKnife.bind(this); 34 callbackManager = CallbackManager.Factory.create() ; 35 36 init(); 37 } 38 39 private void init() { 40 41 facebook_bt.registerCallback(callbackManager, new FacebookCallback<LoginResult>() { 42 @Override 43 public void onSuccess(LoginResult loginResult) { 44 Toast.makeText(LoginLoginActivity.this, "facebook登录成功了", Toast.LENGTH_SHORT).show(); 45 log("facebook登录成功了" + loginResult.getAccessToken()); //获取登录信息 getLoginInfo( loginResult.getAccessToken() ) ; 46 } 47 48 @Override 49 public void onCancel() { 50 Toast.makeText(LoginLoginActivity.this, "facebook登录取消了", Toast.LENGTH_SHORT).show(); 51 log("facebook登录取消了"); 52 } 53 54 @Override 55 public void onError(FacebookException error) { 56 Toast.makeText(LoginLoginActivity.this, "facebook登录失败了", Toast.LENGTH_SHORT).show(); 57 log("facebook登录失败了"); 58 } 59 }); 60 61 } 62 63 @Override 64 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 65 super.onActivityResult(requestCode, resultCode, data); 66 67 //facebook回调 68 callbackManager.onActivityResult( requestCode , resultCode ,data ) ; 69 } 70 } 1 /** 2 * 获取登录信息 3 * @param accessToken 4 */ 5 public void getLoginInfo( AccessToken accessToken ){ 6 GraphRequest request = GraphRequest.newMeRequest(accessToken, new GraphRequest.GraphJSONObjectCallback() { 7 @Override 8 public void onCompleted(JSONObject object, GraphResponse response) { 9 if (object != null) { 10 String id = object.optString( "id" ) ; //比如:1565455221565 11 String name = object.optString( "name" ) ; //比如:Zhang San 12 String gender = object.optString("gender") ; //性别:比如 male (男) female (女) 13 String emali = object.optString("email") ; //邮箱:比如:56236545@qq.com 14 15 //获取用户头像 16 JSONObject object_pic = object.optJSONObject( "picture" ) ; 17 JSONObject object_data = object_pic.optJSONObject( "data" ) ; 18 String photo = object_data.optString( "url" ) ; 19 20 //获取地域信息 21 String locale = object.optString( "locale" ) ; //zh_CN 代表中文简体 22 23 Toast.makeText( activity , "" + object.toString() , Toast.LENGTH_SHORT).show(); 24 } 25 } 26 }) ; 27 28 Bundle parameters = new Bundle(); 29 parameters.putString("fields", "id,name,link,gender,birthday,email,picture,locale,updated_time,timezone,age_range,first_name,last_name"); 30 request.setParameters(parameters); 31 request.executeAsync() ; 32 } 5.7 企业账号需要注意的事项,把发布按钮打开 6、对facebookSDk 进行二次封装 1 package com.pegasus.map.presentation.utils; 2 3 import android.app.Activity; 4 import android.content.DialogInterface; 5 import android.os.Bundle; 6 import android.support.v7.app.AlertDialog; 7 import android.widget.Toast; 8 9 import com.facebook.AccessToken; 10 import com.facebook.CallbackManager; 11 import com.facebook.FacebookCallback; 12 import com.facebook.FacebookException; 13 import com.facebook.GraphRequest; 14 import com.facebook.GraphResponse; 15 import com.facebook.Profile; 16 import com.facebook.login.LoginManager; 17 import com.facebook.login.LoginResult; 18 19 import org.json.JSONObject; 20 21 import java.util.Arrays; 22 import java.util.Collections; 23 import java.util.List; 24 25 /** 26 * Created by ${zyj} on 2016/3/30. 27 */ 28 public class FaceBookLogin { 29 30 private Activity activity ; 31 private CallbackManager callbackManager ; 32 private FacebookListener facebookListener ; 33 private List<String> permissions = Collections.<String>emptyList(); 34 private LoginManager loginManager; 35 36 public FaceBookLogin( Activity activity ){ 37 this.activity = activity ; 38 39 //初始化facebook登录服务 40 callbackManager = CallbackManager.Factory.create() ; 41 getLoginManager().registerCallback(callbackManager, new FacebookCallback<LoginResult>() { 42 @Override 43 public void onSuccess(LoginResult loginResult) { 44 // login success 45 AccessToken accessToken = loginResult.getAccessToken(); 46 getLoginInfo(accessToken); 47 } 48 49 @Override 50 public void onCancel() { 51 //取消登录 52 } 53 54 @Override 55 public void onError(FacebookException error) { 56 //登录出错 57 } 58 }); 59 60 permissions = Arrays 61 .asList("email", "user_likes", "user_status", "user_photos", "user_birthday", "public_profile", "user_friends") ; 62 } 63 64 /** 65 * 登录 66 */ 67 public void login(){ 68 getLoginManager().logInWithReadPermissions( 69 activity, permissions); 70 } 71 72 /** 73 * 退出 74 */ 75 public void logout(){ 76 String logout = activity.getResources().getString( 77 com.facebook.R.string.com_facebook_loginview_log_out_action); 78 String cancel = activity.getResources().getString( 79 com.facebook.R.string.com_facebook_loginview_cancel_action); 80 String message; 81 Profile profile = Profile.getCurrentProfile(); 82 if (profile != null && profile.getName() != null) { 83 message = String.format( 84 activity.getResources().getString( 85 com.facebook.R.string.com_facebook_loginview_logged_in_as), 86 profile.getName()); 87 } else { 88 message = activity.getResources().getString( 89 com.facebook.R.string.com_facebook_loginview_logged_in_using_facebook); 90 } 91 AlertDialog.Builder builder = new AlertDialog.Builder(activity); 92 builder.setMessage(message) 93 .setCancelable(true) 94 .setPositiveButton(logout, new DialogInterface.OnClickListener() { 95 public void onClick(DialogInterface dialog, int which) { 96 getLoginManager().logOut(); 97 } 98 }) 99 .setNegativeButton(cancel, null); 100 builder.create().show(); 101 } 102 103 /** 104 * 获取登录信息 105 * @param accessToken 106 */ 107 public void getLoginInfo( AccessToken accessToken ){ 108 GraphRequest request = GraphRequest.newMeRequest(accessToken, new GraphRequest.GraphJSONObjectCallback() { 109 @Override 110 public void onCompleted(JSONObject object, GraphResponse response) { 111 if (object != null) { 112 String id = object.optString("id"); //比如:1565455221565 113 String name = object.optString("name"); //比如:Zhang San 114 String gender = object.optString("gender"); //性别:比如 male (男) female (女) 115 String emali = object.optString("email"); //邮箱:比如:56236545@qq.com 116 117 //获取用户头像 118 JSONObject object_pic = object.optJSONObject("picture"); 119 JSONObject object_data = object_pic.optJSONObject("data"); 120 String photo = object_data.optString("url"); 121 122 //获取地域信息 123 String locale = object.optString("locale"); //zh_CN 代表中文简体 124 125 Toast.makeText(activity, "" + object.toString(), Toast.LENGTH_SHORT).show(); 126 } 127 } 128 }) ; 129 130 Bundle parameters = new Bundle(); 131 parameters.putString("fields", "id,name,link,gender,birthday,email,picture,locale,updated_time,timezone,age_range,first_name,last_name"); 132 request.setParameters(parameters); 133 request.executeAsync() ; 134 } 135 136 /** 137 * 获取loginMananger 138 * @return 139 */ 140 private LoginManager getLoginManager() { 141 if (loginManager == null) { 142 loginManager = LoginManager.getInstance(); 143 } 144 return loginManager; 145 } 146 147 public CallbackManager getCallbackManager(){ 148 return callbackManager ; 149 } 150 151 /** 152 * 设置登录简体器 153 * @param facebookListener 154 */ 155 public void setFacebookListener( FacebookListener facebookListener ){ 156 this.facebookListener =facebookListener ; 157 } 158 159 public interface FacebookListener { 160 void facebookLoginSuccess(); 161 void facebookLoginFail() ; 162 } 163 164 165 } 在 activity使用 1 //初始化Facebook登录服务 2 FaceBookLogin faceBookLogin = new FaceBookLogin( this ) ; 3 4 //登录 5 faceBookLogin.login(); 6 7 //退出 8 faceBookLogin.logout(); 1 @Override 2 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 3 super.onActivityResult(requestCode, resultCode, data); 4 5 //facebook回调 6 faceBookLogin.getCallbackManager().onActivityResult(requestCode, resultCode, data); 7 8 }

优秀的个人博客,低调大师

Android 应用程序集成Google 登录及二次封装

谷歌登录API: https://developers.google.com/identity/sign-in/android/ 1、注册并且登录google网站 https://accounts.google.com/ 2、进入google开发者平台创建应用 https://developers.google.com/mobile/add?platform=android&cntapi=signin&cntapp=Default%20Demo%20App&cntpkg=com.google.samples.quickstart.signin&cnturl=https:%2F%2Fdevelopers.google.com%2Fidentity%2Fsign-in%2Fandroid%2Fstart%3Fconfigured%3Dtrue&cntlbl=Continue%20with%20Try%20Sign-In 3、在开发者平台填写响应的信息,包括 应用名、包名、签名的SHA-1值 图1 图2 图3 4、在项目中添加谷歌服务 4.1、在SDK Manager 里面下载 google service 4.2、在project目录下的build.gradle下添加 classpath 'com.google.gms:google-services:2.1.0-alpha4' 查看最新版本号:https://jcenter.bintray.com/com/google/gms/google-services/ 4.3 在model目录下的build.gradle下添加 compile 'com.google.android.gms:play-services-auth:8.4.0' 5、代码实现 5.1、在布局文件中 1 <com.google.android.gms.common.SignInButton 2 android:id="@+id/google_signIn_bt" 3 android:layout_width="wrap_content" 4 android:layout_height="wrap_content" /> 5 6 <Button 7 android:id="@+id/google_loginOut_bt" 8 android:layout_width="match_parent" 9 android:layout_height="wrap_content" 10 android:text="google退出登录" 11 android:layout_gravity="center" 12 android:gravity="center" 13 > 14 </Button> 5.2、java代码 1 package com.pegasus.map.presentation.ui.activity; 2 3 import android.content.Intent; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.Button; 7 8 import com.google.android.gms.auth.api.Auth; 9 import com.google.android.gms.auth.api.signin.GoogleSignInAccount; 10 import com.google.android.gms.auth.api.signin.GoogleSignInOptions; 11 import com.google.android.gms.auth.api.signin.GoogleSignInResult; 12 import com.google.android.gms.common.ConnectionResult; 13 import com.google.android.gms.common.SignInButton; 14 import com.google.android.gms.common.api.GoogleApiClient; 15 import com.google.android.gms.common.api.ResultCallback; 16 import com.google.android.gms.common.api.Status; 17 import com.pegasus.map.R; 18 import com.pegasus.map.presentation.ui.base.BaseActivity; 19 20 import butterknife.Bind; 21 import butterknife.ButterKnife; 22 23 /** 24 * Created by ${zyj} on 2016/3/24. 25 * 登录 26 */ 27 28 public class LoginActivity1 extends BaseActivity implements GoogleApiClient.OnConnectionFailedListener , View.OnClickListener { 29 30 public int RequestCode = 10 ; 31 32 @Bind( R.id.google_signIn_bt ) 33 public SignInButton google_signIn_bt ; 34 35 @Bind( R.id.google_loginOut_bt ) 36 public Button google_loginOut_bt ; 37 38 public GoogleSignInOptions gso ; 39 public GoogleApiClient mGoogleApiClient ; 40 41 @Override 42 protected void onCreate(Bundle savedInstanceState) { 43 super.onCreate(savedInstanceState); 44 setContentView(R.layout.activity_login); 45 ButterKnife.bind(this); 46 init(); 47 } 48 49 50 private void init() { 51 //初始化谷歌登录服务 52 gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 53 .requestEmail() //获取邮箱 54 .requestId() //获取id 号 55 .requestIdToken("456212545785") //获取token 56 .build(); 57 58 // Build a GoogleApiClient with access to GoogleSignIn.API and the options above. 59 mGoogleApiClient = new GoogleApiClient.Builder( this ) 60 .enableAutoManage( this , this ) 61 .addApi(Auth.GOOGLE_SIGN_IN_API, gso) 62 .build(); 63 64 //登录 65 google_signIn_bt.setSize(SignInButton.SIZE_STANDARD); 66 google_signIn_bt.setScopes(gso.getScopeArray()); 67 google_signIn_bt.setOnClickListener(this) ; 68 69 //退出 70 google_loginOut_bt.setOnClickListener(this) ; 71 72 } 73 74 @Override 75 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 76 super.onActivityResult(requestCode, resultCode, data); 77 78 //谷歌登录成功回调 79 if ( requestCode == RequestCode ) { 80 GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); 81 handleSignInResult( result ) ; 82 } 83 } 84 85 @Override 86 public void onConnectionFailed(ConnectionResult connectionResult) { 87 88 } 89 90 @Override 91 public void onClick(View v) { 92 switch ( v.getId() ){ 93 case R.id.google_signIn_bt : //登录 94 signIn(); 95 break; 96 97 case R.id.google_loginOut_bt : 98 signOut(); 99 break; 100 } 101 } 102 103 /** 104 * 登录 105 */ 106 private void signIn() { 107 Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); 108 startActivityForResult(signInIntent, RequestCode ); 109 } 110 111 /** 112 * 退出 113 */ 114 private void signOut() { 115 Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback( 116 new ResultCallback<Status>() { 117 @Override 118 public void onResult(Status status) { 119 // ... 120 } 121 }); 122 } 123 124 private void handleSignInResult(GoogleSignInResult result) { 125 if (result.isSuccess()) { 126 // Signed in successfully, show authenticated UI. 127 GoogleSignInAccount acct = result.getSignInAccount(); 128 //获取用户名 129 String name = acct.getDisplayName() ; 130 String email = acct.getEmail() ; 131 String token = acct.getIdToken() ; 132 String id = acct.getId() ; 133 134 } else { 135 // Signed out, show unauthenticated UI. 136 } 137 } 138 139 } 6、Google SDK 二次封装 1 package com.pegasus.map.presentation.utils; 2 3 import android.content.Intent; 4 import android.support.v4.app.FragmentActivity; 5 import android.util.Log; 6 import android.widget.Toast; 7 8 import com.google.android.gms.auth.api.Auth; 9 import com.google.android.gms.auth.api.signin.GoogleSignInAccount; 10 import com.google.android.gms.auth.api.signin.GoogleSignInOptions; 11 import com.google.android.gms.auth.api.signin.GoogleSignInResult; 12 import com.google.android.gms.common.api.GoogleApiClient; 13 import com.google.android.gms.common.api.ResultCallback; 14 import com.google.android.gms.common.api.Status; 15 import com.pegasus.map.R; 16 17 /** 18 * Created by ${zyj} on 2016/3/30. 19 */ 20 public class GoogleLogin { 21 22 public int requestCode = 10 ; 23 private FragmentActivity activity ; 24 public GoogleSignInOptions gso ; 25 public GoogleApiClient mGoogleApiClient ; 26 public GoogleApiClient.OnConnectionFailedListener listener ; 27 private GoogleSignListener googleSignListener ; 28 29 public GoogleLogin(FragmentActivity activity , GoogleApiClient.OnConnectionFailedListener listener ){ 30 this.activity = activity ; 31 this.listener = listener ; 32 33 //初始化谷歌登录服务 34 gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 35 .requestEmail() 36 .requestId() 37 .requestIdToken( activity.getString(R.string.google_server_client_id)) 38 .requestProfile() 39 .build(); 40 41 // Build a GoogleApiClient with access to GoogleSignIn.API and the options above. 42 mGoogleApiClient = new GoogleApiClient.Builder( activity ) 43 .enableAutoManage( activity , listener ) 44 .addApi(Auth.GOOGLE_SIGN_IN_API, gso) 45 .build(); 46 } 47 48 49 /** 50 * 登录 51 */ 52 public void signIn() { 53 Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient); 54 activity.startActivityForResult(signInIntent, requestCode); 55 } 56 57 /** 58 * 退出登录 59 */ 60 public void signOut() { 61 Auth.GoogleSignInApi.signOut(mGoogleApiClient).setResultCallback( 62 new ResultCallback<Status>() { 63 @Override 64 public void onResult(Status status) { 65 if ( status.isSuccess() ){ 66 if ( googleSignListener != null ){ 67 googleSignListener.googleLogoutSuccess(); 68 } 69 }else { 70 if ( googleSignListener!= null ){ 71 googleSignListener.googleLogoutFail(); 72 } 73 } 74 } 75 }); 76 } 77 78 public String handleSignInResult(GoogleSignInResult result) { 79 String res = "" ; 80 if (result.isSuccess()) { 81 //登录成功 82 GoogleSignInAccount acct = result.getSignInAccount(); 83 res = "登录成功" 84 + "用户名为:" + acct.getDisplayName() 85 + " 邮箱为:" + acct.getEmail() 86 + " token为:" + acct.getIdToken() 87 + " 头像地址为:" + acct.getPhotoUrl() 88 + " Id为:" + acct.getId() 89 + " GrantedScopes为:" + acct.getGrantedScopes() ; 90 Log.e("res", "res:"+res); 91 Toast.makeText( activity, res, Toast.LENGTH_SHORT).show(); 92 if ( googleSignListener != null ){ 93 googleSignListener.googleLoginSuccess(); 94 } 95 } else { 96 // Signed out, show unauthenticated UI. 97 res = "-1" ; //-1代表用户退出登录了 , 可以自定义 98 Toast.makeText( activity , "退出登录", Toast.LENGTH_SHORT).show(); 99 if ( googleSignListener != null ){ 100 googleSignListener.googleLoginFail(); 101 } 102 } 103 return res ; 104 } 105 106 107 public void setGoogleSignListener( GoogleSignListener googleSignListener ){ 108 this.googleSignListener = googleSignListener ; 109 } 110 111 public interface GoogleSignListener { 112 void googleLoginSuccess(); 113 void googleLoginFail() ; 114 void googleLogoutSuccess(); 115 void googleLogoutFail() ; 116 } 117 118 } 注意:当你把 GoogleLogin 类复制到你项目中的时候,activity.getString(R.string.google_server_client_id) 这一句会报错,可以先不用管,在6.5 部分会做说明 6.1 在activity里使用封装类 activity 实现 GoogleApiClient.OnConnectionFailedListener , GoogleLogin.GoogleSignListener 两个接口 6.2 //初始化谷歌登录服务 GoogleLogin googleLogin = new GoogleLogin( this , this ) ; googleLogin.setGoogleSignListener(this); 6.3 1 @Override 2 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 3 super.onActivityResult(requestCode, resultCode, data); 4 5 //谷歌登录成功回调 6 if (requestCode == googleLogin.requestCode ) { 7 GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data); 8 googleLogin.handleSignInResult( result ) ; 9 } 10 } 6.4 1 //登录 2 googleLogin.signIn(); 3 4 //退出 5 googleLogin.signOut(); 6.5 获取google_server_client_id , 并在strings 里面配置 https://console.developers.google.com/projectselector/apis/credentials 在上面的网站里选择 点击选择项目,然后选择你创建的app,进入下面一个界面,得到对应的Client ID 补充:(2016/8/9) 有很多人留言或者发私信说一直登陆失败。然后我就自己写了一个demo,核心代码完全复制博客里面的GoogleLogin (代码见第六个标题,6、Google SDK 二次封装) 里面的代码,真的是一行代码都没有改,完完全全复制的。最后实现登陆成功,可见博客里面的代码是没有问题的。我在操作过程中,有几个关键的地方提一下。 1、权限问题 只需要添加联网权限即可 <uses-permission android:name="android.permission.INTERNET"></uses-permission> 2、签名问题 在开发者后台创建app的时候,需要添加 SHA-1的值,这个值是从你的签名里面获取的。注意,在你运行demo的时候,如果直接运行是不行的,因为直接运行,android studio 会为你的app使用默认签名,这个签名是系统自带的,这个签名的SHA-1值肯定和你真正的签名文件SHA-1值不一样,所以必然会登录失败。 你需要修改你的app debug 时的签名和 发布时的签名一直就好了。

优秀的个人博客,低调大师

RustDesk 1.4.0 远程桌面,全面支持 Web Socket

新增功能 锁屏时允许使用登录屏幕密码 截屏功能 使用主机名作为专业版的标识 Windows 自动更新,Windows 和 Mac 手动更新 所有平台支持 WebSocket 调整触控板速度 #11680 变更 移除 reqwest 的系统代理依赖 显示名称首字母大写 Socks5 代理仅使用 TCP,因为许多用户未能正确设置 UDP,包括我们自己 托盘中的“退出”更改为“停止服务”,以避免混淆 修复 虚拟 F11 键适配 macOS (11366) 托盘启动尝试通过 sudo(被拒绝),导致发送电子邮件 #9802 使用 reqwest 的 Http 代理 隐藏 cm 局域网发现 Rdp #10039 鼠标滚动,远程标签页 #11708 2FA 登录状态 更新说明:https://github.com/rustdesk/rustdesk/releases/tag/1.4.0 顶级 Rust 开源项目期待你的加入,请发送简历到emhvdUBydXN0ZGVzay5jb20gICA=

优秀的个人博客,低调大师

RustDesk 远程桌面 1.2.3 发布,增强 Wayland 支持

简介 RustDesk 项目发布 v1.2.3 版本,访问下载体验。 升级内容 改进 Wayland 支持,光标/剪贴板/多显示器等,但高度依赖 Xwayland,在 GNOME 上运行良好,在 KDE 上兼容性较差。 我们将继续在增强 Wayland 支持 添加组选项卡 添加基于 Github 最新标签的软件更新检查 针对卡巴斯基合规性的一些修复,https://github.com/rustdesk/rustdesk/discussions/5624 自 1.2.2 以来进行了大量修复 我们仍在努力开发针对多显示器的多窗口支持和新硬件编解码器,希望能在 1.2.4 中发布

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册