Cocos creator needs to call the static method of the Android native platform to realize qq login:
First, on the cocos creator side, write the java static method using the emission mechanism:
//qq login interface QQLogin : function(){ this.resultString = ''; this.isLoginSuccess = false; this.userInfoString = ''; console.log("this.isLoginSuccess is " + this.isLoginSuccess); //If it is an Android system, enter the relevant method if(cc.sys.isNative){ / / Call the java static method to achieve qq login this.resultString = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "doLogin","()Ljava/lang/String;"); this.schedule(function(){ // Determine whether the login is successful this.isLoginSuccess = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "isLoginSu","()Z"); console.log("in schedule isLoginSuccess is " + this.isLoginSuccess); if(this.isLoginSuccess){ this.unscheduleAllCallbacks(); this.resultString = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "doLogin","()Ljava/lang/String;"); this.userInfoString = jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "getQQInfo","()Ljava/lang/String;"); //Get the string after successful qq login console.log("resultString is " + this.resultString); //Display user information console.log("userInfoString is " + this.userInfoString); console.log("typeof userInfoString is " + typeof(this.userInfoString)); var resultObject = JSON.parse(this.resultString); if(resultObject != null){ //Get openid after successful login console.log("resultObject's openid is " + resultObject.openid); // get access token console.log("access_token is " + resultObject.access_token); // switch scene } try{ var userInfoObject = JSON.parse(this.userInfoString); if(userInfoObject != null){ // get user information console.log("userInfoObject is " + userInfoObject); // store the avatar address UserInfo.iconURL = userInfoObject.figureurl; console.log("iconURL is " + UserInfo.iconURL); //User's Nickname UserInfo.nickname = userInfoObject.nickname; console.log("nickname is " + UserInfo.nickname); //qq login status is set to true UserInfo.qqLogin = true; //load avatar this.loadIcon(); } }catch(e){ console.log("*********"); console.log("exception is " + e); } } //Execute once every second }.bind(this),1); console.log("isLoginSuccess is " + this.isLoginSuccess); }else{ alert("Temporarily unsupported browser page"); return; } }, //Load qq avatar loadIcon : function(){ var self = this; //If the qq login is successful, enter this method to render the avatar if(UserInfo.qqLogin){ //The visibility of qq avatar is set to true this.qqIcon.active = true; //The visibility of QQ nickname is set to true this.qqNickname.active = true; //qq avatar url var iconUrl = UserInfo.iconURL; console.log("iconUrl is " + iconUrl); var nickname = UserInfo.nickname; console.log("nickname is " + nickname); this.qqNickname.getComponent(cc.Label).fontSize = 20; this.qqNickname.getComponent(cc.Label).string = nickname; //Remote load resource cc.loader.load({url:iconUrl,type:'jpg'},function(err,texture){ var spriteFra = self.qqIcon.getComponent(cc.Sprite).spriteFrame; console.log("spriteRra is " + spriteFra); console.log("texture is " + texture); spriteFra.setTexture(texture); }.bind(this)); } },
2: After packaging by cocos creator, generate an android studio project, open the project, and set the class or jar package required for qq login:
a: Import the jar package:
I need even a jar package below. These jar packages are available in the QQ login demo, so I will not upload them here.
b: Add the corresponding manifests file
<application
android:allowBackup="true"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher">
<!-- Tell Cocos2dxActivity the name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="cocos2djs" />
<activity
android:name="org.cocos2dx.javascript.AppActivity"
android:screenOrientation="sensorLandscape"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.tencent.tauth.AuthActivity"
android:noHistory="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tencent1106774691" />
</intent-filter>
</activity>
<activity
android:name="com.tencent.connect.common.AssistActivity"
android:screenOrientation="behind"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:configChanges="orientation|keyboardHidden">
</activity>
</application>
The ones marked in red are the activities that need to be added for the QQ login authorization interface.
c: Override the onActivityResult method in the AppActivity class:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == Constants.REQUEST_LOGIN) { Tencent.onActivityResultData(requestCode,resultCode,data,listener); } super.onActivityResult(requestCode, resultCode, data); SDKWrapper.getInstance().onActivityResult(requestCode, resultCode, data); }
3: Add a formal login method to obtain user information:
public class AppActivity extends Cocos2dxActivity { //activity of this game public static AppActivity app; //appID public static String mAppid; //Tencent instance generated according to appid public static Tencent mTencent = null; //The string that needs to be passed to the js side public static String message = null; //The listener is used for callback after Tencent login successfully public static IUiListener listener = null; //socket for long connection private static Socket mSocket; public static String userMessage = null; //User Info public static UserInfo mInfo = null; public static boolean isLoginSuccess = false; static { try { mSocket = IO.socket("http://192.168.1.162:3000"); System.out.println("Connection succeeded"); }catch (Exception e){ } } private IntentFilter intentFilter; //get network status public BroadcastReceiver br = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { ConnectivityManager connectivityManager= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo=connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); NetworkInfo wifiinfo=connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); if(!networkInfo.isConnected()&&!wifiinfo.isConnected()){ /** * */ Toast.makeText(context,"Network unavailable!",Toast.LENGTH_SHORT).show(); System.out.println("Network unavailable"); }else{ if(wifiinfo.isConnected()){ Toast.makeText(context,"wifi连接中!",Toast.LENGTH_SHORT).show(); System.out.println("wifi connection"); } if(networkInfo.isConnected()){ Toast.makeText(context,"traffic connection!",Toast.LENGTH_SHORT).show(); System.out.println("Traffic in use"); } } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate (savedInstanceState); // Workaround in https://stackoverflow.com/questions/16283079/re-launch-of-activity-on-home-button-but-only-the-first-time/16447508 if (!isTaskRoot()) { // Android launched another instance of the root activity into an existing task // so just quietly finish and go away, dropping the user back into the activity // at the top of the stack (ie: the last state of this task) // Don't need to finish it again since it's finished in super.onCreate . return; } // DO OTHER INITIALIZATION BELOW SDKWrapper.getInstance().init(this); intentFilter = new IntentFilter(); intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(br,intentFilter); //socket connection mSocket.connect(); //Initialize appid mAppid = "The qq appId you applied for"; //Assign the current activey to the app app = this; SDKWrapper.getInstance().init(this); //Get Tencent instance mTencent = Tencent.createInstance(mAppid,app); listener = new BaseUILi(); System.out.println("listener is " + listener); } //define a listener class public static class BaseUILi implements IUiListener{ public BaseUILi(){ } @Override public void onComplete(Object o){ //Only after the login is successful, the user information can be successfully obtained, and this object o object is used System.out.println("Authorization succeeded"); System.out.println("o is " + o); JSONObject obj = (JSONObject) o; AppActivity.isLoginSuccess = true; //Set the mTencent object accordingly so that it has the corresponding openid, access_token and other information initOpenidAndToken(obj); System.out.println("obj is " + obj); message = obj.toString(); System.out.println("message is " + message); //get user information getUserInfo(); } //Set token and openid information private void initOpenidAndToken(JSONObject jsonObject) { try { String openid = jsonObject.getString("openid"); String token = jsonObject.getString("access_token"); String expires = jsonObject.getString("expires_in"); //The key step to make the mTencent object have token information and opendid information mTencent.setAccessToken(token, expires); //Set openid information mTencent.setOpenId(openid); } catch (JSONException e) { e.printStackTrace (); } } private void getUserInfo() { //sdk provides us with a class UserInfo, this class encapsulates some information of QQ users, we can get this information through this class QQToken mQQToken = mTencent.getQQToken (); //When UserInfo, pass the current activity and qqtoken into it UserInfo userInfo = new UserInfo(app, mQQToken); // get user information userInfo.getUserInfo(new IUiListener() { @Override public void onComplete(final Object o) { System.out.println("********************************@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); System.out.println("has entered userInfo method"); JSONObject userInfoJson = (JSONObject) o; userMessage = userInfoJson.toString(); System.out.println("userInfoJson is " + userInfoJson); System.out.println("Hahahahaha"); Message msgNick = new Message(); msgNick.what = 0; // Nickname try { msgNick.obj = userInfoJson.getString("nickname");//Pass the content of a nickname directly } catch (JSONException e) { e.printStackTrace (); } } @Override public void onError(UiError uiError) { } @Override public void onCancel () { } } ); } @Override public void onError(UiError uiError) { System.out.println("-------------> error"); } @Override public void onCancel () { System.out.println("-------------> User has canceled"); } } public static boolean isLoginSu(){ System.out.println("in isLoginSu isLoginSuccess is " + AppActivity.isLoginSuccess); return AppActivity.isLoginSuccess; } //qq login method public static String doLogin(){ // asynchronous operation mTencent.login(AppActivity.app,"all",listener); System.out.println("in dologin function message is " + message); System.out.println("userMessage is " + userMessage); System.out.println("in doLogin function isLoginSuccess is " + isLoginSu()); if(message != null){ return message; }else{ return ""; } } public static String getQQInfo(){ return userMessage; } @Override public Cocos2dxGLSurfaceView onCreateView() { Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this); // TestCpp should create stencil buffer glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8); SDKWrapper.getInstance().setGLSurfaceView(glSurfaceView); return glSurfaceView; } @Override protected void onResume(){ super.onResume(); SDKWrapper.getInstance().onResume(); } @Override protected void onPause() { super.onPause(); SDKWrapper.getInstance().onPause(); } @Override protected void onDestroy() { super.onDestroy (); SDKWrapper.getInstance (). OnDestroy (); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == Constants.REQUEST_LOGIN) { Tencent.onActivityResultData(requestCode,resultCode,data,listener); } super.onActivityResult(requestCode, resultCode, data); SDKWrapper.getInstance().onActivityResult(requestCode, resultCode, data); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); SDKWrapper.getInstance().onNewIntent(intent); } @Override protected void onRestart() { super.onRestart(); SDKWrapper.getInstance().onRestart(); } @Override protected void onStop() { super.onStop(); SDKWrapper.getInstance().onStop(); } @Override public void onBackPressed() { SDKWrapper.getInstance().onBackPressed(); super.onBackPressed(); } @Override public void onConfigurationChanged(Configuration newConfig) { SDKWrapper.getInstance().onConfigurationChanged(newConfig); super.onConfigurationChanged(newConfig); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { SDKWrapper.getInstance (). OnRestoreInstanceState (savedInstanceState); super.onRestoreInstanceState (savedInstanceState); } @Override protected void onSaveInstanceState(Bundle outState) { SDKWrapper.getInstance().onSaveInstanceState(outState); super.onSaveInstanceState(outState); } @Override protected void onStart() { SDKWrapper.getInstance().onStart(); super.onStart(); } }
/** Merchant private key, pkcs8 format*/ /** The following private key, RSA2_PRIVATE or RSA_PRIVATE only needs to be filled in one */ /** If the merchant has set both, RSA2_PRIVATE is preferred */ /** RSA2_PRIVATE can be guaranteed Merchant transactions are conducted in a more secure environment, it is recommended to use RSA2_PRIVATE */ /** to obtain RSA2_PRIVATE, and it is recommended to use the public and private key generation tool provided by Alipay to generate, */ /** Tool address: https://doc.open.alipay. com/docs/doc.htm?treeId=291&articleId=106097&docType=1 */ public static final String RSA2_PRIVATE = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCDIlVznW8S+hP8aZzF1oLZ1IOiLwYKgv5zpEQvzbxwG7uRXndhOFm8MxwlhymQ5GAquuRbabIb9n1dJouo7ZnHhCashOoJRe0xaFJnb7u2VaO4ixayO3wuqMS+l+ea0xbwA4VvdIs7los6449sLO8xyUa1CwKusdiIOdypUi2I2ocMWG6kjpysGmNEQPxz5IeImgGW8GJSUgsKM8AImSwXaoi8WZUPAq9yc2rwX7GZLdbPYe0qaqwPfYVKzBIMgSBJjAZMp4g3rj8FQDCW6V0SXYQMUrlyBwuOmi1mqjbIwkO5r7efwkA5D3D6ZYbN4zsq6lPK2eNkGSeX71j7Lf5hAgMBAAECggEAbzYC+lYeCR4FLR/0UOQnfM16BWWT3f5SBYjeOxxkHz+lxxcyb0T29WDzEfCbE8JavGJboBr3bjeRAhrafp1iuY4drlnakZq4Ghq7J/XeYDgo7S0oRmekXX3LvUfep7M11L9nvqo8GoEF+x9aVweUo8hrKsb3s2golv9bYE3NSC2srlmBcxBVnVumUzewwC1nI7sCKyYjMPBGiNiE5o9Djv4L1l1zKx/FgV87cC8eH4pJn8u7yj6BJ8U0WjG+XRuj6MbfupaJSYOrOVFAfhCWdMcMaqOoL4o0NCYX1JmQ/tLByZjHxhx65E7KwT9w4imXdJsJ85YEN8U/pKdQBgYVAQKBgQDoIvkcMTG8PSwhUfUtyM1MRt1M744ss6vUBlgfCH5EB7VLhjnezlkMQNAFvRP9VtHvm0YLhGCtyZwOVk9hqZ+ZoJYtCIuKFYw64CN/i79H5Lber85F8Dm16WLmzo6goieMx+1nMT+ZCJGs999bEXT1egSn0exC3sk6tG6Yd9WCWQKBgQCQnVOt2VSxf/eLcdEo2piWuegC8gkspsuLTJmNgx3c7EV8M2jdu3swHO0pLZKR+oEA5TFwdiUPi0qEY4lhaIciOrxdIzZW5kA1pTrJsqthFBcQI3VP6nBU+KWr/KP4pKSyk4cFEIweS9fOu31o4Ki+AeCJw/plTFICi+I6zgILSQKBgQCGCROPfLQ7/ZJKlvkbe5NW1KAZOUT9eKzhWtxs5smJXG4I8rLdfIYcNhwnBBrTr9q+IAjcw43TKtMJ0Do7qOZ3nSq5S/LOQ0zZ/ethTP6gc2ZHxHk1FtUrvVuW63OdOqPdfN8OM3iGU1VR6zmzaqv+xXqEsAhcQCku1Vn6fU7x2QKBgHvrxQwBYxjjPl3ov0HR59WpIs57Vy9DEsKgdiiUhZ+Ne5GNgDwZbttwvi1+Fs4uqiL5Q19KbkGeq9E8djnZV4sWZ9kr1mGq1rThjLnP+BmtHIJA0EMV8wJtO5JgYKYtd9BqqNXHMzq25QwLD9EySobfluiW3le1icUS115qr8e5AoGAc0EJ/DSoIrbRrgbC6aJ53xZD50Qv0ssxBpquHdJ7vdJX50xqmxNK+Qp4Q2Q2dCLgJpmjGeU+AWm8agiLRiE1VYoNpIBn0kDg+NPcC1bwUKcYNd8amnDLHx5NJz9B4iwTGFVLOjY+DuvXUI6L1PDiHj6IlcCfvlAVveEb9WTilMA="; public static final String RSA_PRIVATE = "";private static final int SDK_PAY_FLAG = 1; private static final int SDK_AUTH_FLAG = 2; /* * * Alipay business data declaration ends* * */ /** * * qq login business data begins* * */ public static String mAppid; // The Tencent instance generated according to the appid public static Tencent mTencent = null; //The string that needs to be passed to the js side public static String message = null; //The listener is used for the callback after Tencent has successfully logged in public static IUiListener listener = null; public static String userMessage = null; //User information public static UserInfo mInfo = null; public static boolean isLoginSuccess = false; /** * * qq login business data ends* * */ @Override protected void onCreate(Bundle savedInstanceState) { EnvUtils.setEnv( EnvUtils.EnvEnum.SANDBOX); super.onCreate(savedInstanceState); // Workaround in https://stackoverflow.com/questions/16283079/re-launch-of-activity-on-home-button-but-only-the- first-time/16447508 if (!isTaskRoot()) { // Android launched another instance of the root activity into an existing task // so just quietly finish and go away, dropping the user back into the activity // at the top of the stack (ie: the last state of this task) // Don't need to finish it again since it's finished in super.onCreate . return; } // DO OTHER INITIALIZATION BELOW SDKWrapper.getInstance().init(this); //initialize appid mAppid = "1106774691 "; //Static variable points to your current Activity app = this; //Create a Tencent instance mTencent = Tencent.createInstance(mAppid,app); listener = new BaseUILi(); System.out.println("listener is " + listener); }4: After doing this, you can log in to qq normallyonCreate . return; } // DO OTHER INITIALIZATION BELOW SDKWrapper.getInstance().init(this); //Initialize appid mAppid = "1106774691"; //Static variable points to your current Activity app = this; //Create a Tencent Instance mTencent = Tencent.createInstance(mAppid,app); listener = new BaseUILi(); System.out.println("listener is " + listener); }4: After doing this, you can log in to qq normallyonCreate . return; } // DO OTHER INITIALIZATION BELOW SDKWrapper.getInstance().init(this); //Initialize appid mAppid = "1106774691"; //Static variable points to your current Activity app = this; //Create a Tencent Instance mTencent = Tencent.createInstance(mAppid,app); listener = new BaseUILi(); System.out.println("listener is " + listener); }4: After doing this, you can log in to qq normally