您的位置:首页 > 其它

用cordova插件实现ionic第三方登录,获取信息和分享

2015-08-28 00:45 731 查看
ionic是比较流行的跨平台移动app的开发工具,但是在开发一个信息聚合平台的时候发现一个问题,就是做QQ和微博分享的时候,ionic的js就不能处理了,所以需要写cordova插件.然后我用的是友盟的社会化分享组件,可以节省很多的代码,前提是你必须要有友盟的AppKey,腾讯和新浪的AppId并且完成了账号的绑定,具体流程见

http://dev.umeng.com/social/android/operation

写一个cordova插件

cordova插件的目录结构如下:

- cordova-plugin-ThirdParty
- plugin.xml
- src
- android
- 各类友盟的jar包,类似SocialSDK_Sina.jar,SocialSDK_QQZone_1.jar
- ThirdParty.java
- ios
- ThirdParty.m
- ThirdParty.h
- www
- ThirdParty.js


plugin.xml是用来配置插件的

src中是各平台的原生代码

www是javascript调用原生代码的方法

ThirdParty.js

里面主要是调用原生代码的方法,这里以微博,QQ登录为例

var exec  = require('cordova/exec'),
cordova = require('cordova');

module.exports = {
QQLogin:function(successCallback, errorCallback){

exec(successCallback, errorCallback, "ThirdParty", "QQLogin", []);
},
WBLogin:function(successCallback, errorCallback){

exec(successCallback, errorCallback, "ThirdParty", "WBLogin", []);

},

};


这个js文件包含两个方法,QQLogin和WBLogin,传递的参数分别是成功的回调函数和失败的回调函数.

plugin.xml

这是插件的配置文件,主要代码如下:

<?xml version="1.0" encoding="UTF-8"?>

<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="cordova-plugin-thirdparty"
version="0.3.6">

<!--这是插件的名字-->
<name>ThirdParty</name>
<!--插件的描述,随你喜欢-->
<description>Cordova ThirdParty Plugin</description>

<!--require cordova version -->
<engines>
<engine name="cordova" version=">=3.5.0" />
<engine name="cordova-android" version=">=4.0.0-dev" />
</engines>

<!--这里用于生成一个全局的js对象ThirdParty,这个对象可以调用ThirdParty.js中的方法-->
<js-module src="www/ThirdParty.js" name="ThirdParty">
<clobbers target="ThirdParty" />
</js-module>

<!-- 针对ios平台 -->
<platform name="ios">
<config-file target="config.xml" parent="/*">

<feature name="ThirdParty">
<param name="ios-package" value="ThirdParty"/>
</feature>
<!--whitelist for QQ SDK-->
<access origin = "https://openmobile.qq.com/*"/>
<access origin = "http://qzs.qq.com/open/mobile/login/*"/>
<access origin = "http://qzonestyle.gtimg.cn/*"/>
<access origin = "http://pub.idqqimg.com/*"/>
<access origin = "http://appsupport.qq.com/*"/>
<access origin = "http://support.qq.com/*"/>
<access origin = "http://qzs.qq.com/*"/>
<access origin = "http://m.qzone.com/*"/>

</config-file>

<!--set ios URLTypes for QQ SDK -->
<config-file target="*-Info.plist" parent="CFBundleURLTypes">
<array>
<dict>

<key>CFBundleURLSchemes</key>
<array>
<string>tencent这里应替换成你的QQ_APP_ID</string>
</array>
</dict>
<dict>

<key>CFBundleURLSchemes</key>
<array>
<string>sina.这里应替换成你的友盟AppKey</string>
</array>
</dict>
</array>
</config-file>

<header-file src="src/ios/ThirdParty.h"/>
<source-file src="src/ios/ThirdParty.m"/>
<!--required frameworks for qq sdk-->
<framework src="CoreGraphics.framework" />
<framework src="CoreTelephony.framework" />
<framework src="SystemConfiguration.framework" />
<framework src="Security.framework" />
<framework src="libiconv.dylib" />
<framework src="libsqlite3.dylib" />
<framework src="libstdc++.dylib" />
<framework src="libz.dylib" />
<!--QQ SDK version 2.9.0-->

<info>
提示你安装ios已完成
</info>
</platform>

<!-- 针对android -->
<platform name="android">

<config-file target="res/xml/config.xml" parent="/*">
<feature name="ThirdParty" >
<!--这会在你的安卓项目中生成一个包,里面装着ThirdParty.java-->
<param name="android-package" value="com.shenaolin.cordova.ThirdParty"/>
</feature>
<!--whitelist for QQ SDK-->
<access origin = "https://openmobile.qq.com/*"/>
<access origin = "http://qzs.qq.com/open/mobile/login/*"/>
<access origin = "http://qzonestyle.gtimg.cn/*"/>
<access origin = "http://pub.idqqimg.com/*"/>
<access origin = "http://appsupport.qq.com/*"/>
<access origin = "http://support.qq.com/*"/>
<access origin = "http://qzs.qq.com/*"/>
<access origin = "http://m.qzone.com/*"/>

</config-file>
<!--添加权限 -->
<config-file target="AndroidManifest.xml" parent="/manifest">
<!-- 检测网络状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 获取mac地址作为用户的备用唯一标识 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 获取用户手机的IMEI,用来唯一的标识用户 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- 缓存资源优先存入SDcard -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 允许应用程序联网,以便向我们的服务器端发送数据 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- QQ、QQ空间所需权限 -->
<uses-permission android:name="android.permission.GET_TASKS" />
</config-file>
<!--QQ授权Activity -->
<config-file target="AndroidManifest.xml" parent="/manifest/application">
<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="tencent这里是QQ_APP_ID"/>
</intent-filter>
</activity>
<activity
android:name="com.tencent.connect.common.AssistActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar" >
</activity>
<meta-data
android:name="UMENG_APPKEY"
android:value="这里是你的友盟APPKEY" >
</meta-data>
</config-file>
<source-file src="src/android/ThirdParty.java" target-dir="src/com/shenaolin/cordova" />
<!--以下是我从友盟中下的库,你可以根据需要替换,这些都将出现在安卓项目的jinLib文件夹下-->
<source-file src="src/android/httpmime-4.1.3.jar" target-dir="libs/" />
<source-file src="src/android/SocialSDK_QQZone_1.jar" target-dir="libs/" />
<source-file src="src/android/SocialSDK_QQZone_2.jar" target-dir="libs/" />
<source-file src="src/android/SocialSDK_QQZone_3.jar" target-dir="libs/" />
<source-file src="src/android/SocialSDK_Sina.jar" target-dir="libs/" />
<source-file src="src/android/umeng_social_sdk.jar" target-dir="libs/" />
<source-file src="src/android/android-support-v4.jar" target-dir="libs/" />
</platform>
</plugin>


以上的配置根据你的需求进行替换

ThirdParty.java

现在要对ThirdParty.js中的请求方法进行处理,也就是在android原生环境中设置QQ登陆,微博登陆的处理方法,如下:

package com.shenaolin.cordova;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.os.AsyncTask;
import android.text.TextUtils;
import android.widget.Toast;

import com.umeng.socialize.bean.SHARE_MEDIA;
import com.umeng.socialize.bean.SocializeEntity;
import com.umeng.socialize.controller.UMServiceFactory;
import com.umeng.socialize.controller.UMSocialService;
import com.umeng.socialize.controller.listener.SocializeListeners;
import com.umeng.socialize.exception.SocializeException;
import com.umeng.socialize.sso.SinaSsoHandler;
import com.umeng.socialize.sso.UMQQSsoHandler;
import com.umeng.socialize.utils.Log;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;

import java.util.Map;
import java.util.Set;

public class ThirdParty extends CordovaPlugin {

private UMSocialService mController;

private Context context;
//初始化插件,经过试验,这个方法每次exec请求后都会执行
@Override
protected void pluginInitialize() {
super.pluginInitialize();
mController = UMServiceFactory.getUMSocialService("com.umeng.login");

mController.getConfig().setSsoHandler(new SinaSsoHandler());
context=this.cordova.getActivity();
final Activity activity = this.cordova.getActivity();

}

@Override
public boolean execute(String action, final JSONArray args,
final CallbackContext callbackContext) throws JSONException {
Log.e("SA", "+++");

if (action.equals("QQLogin")) {
return ssoLogin(callbackContext);
}
if(action.equals("WBLogin")){
return WBLogin(callbackContext);
}

return super.execute(action, args, callbackContext);
}

private boolean WBLogin(final CallbackContext callbackContext) {
mController.doOauthVerify(context, SHARE_MEDIA.SINA, new SocializeListeners.UMAuthListener() {
@Override
public void onError(SocializeException e, SHARE_MEDIA platform) {
callbackContext.error(0);
}

@Override
public void onComplete(Bundle value, SHARE_MEDIA platform) {
if (value != null && !TextUtils.isEmpty(value.getString("uid"))) {
Toast.makeText(context, "授权成功.", Toast.LENGTH_SHORT).show();
mController.getPlatformInfo(context, SHARE_MEDIA.SINA, new SocializeListeners.UMDataListener() {
@Override
public void onStart() {
Toast.makeText(context, "获取平台数据开始...", Toast.LENGTH_SHORT).show();
}

@Override
public void onComplete(int status, Map<String, Object> info) {
if (status == 200 && info != null) {
StringBuilder sb = new StringBuilder();
sb.append("{");
Set<String> keys = info.keySet();
for (String key : keys) {
sb.append("\"" + key + "\"" + ":" + "\"" + info.get(key).toString() + "\",");
}
sb.delete(sb.length() - 1, sb.length());
sb.append("}");
Log.d("TestData", sb.toString());
callbackContext.success(sb.toString());
} else {
Log.d("TestData", "发生错误:" + status);
callbackContext.error(1);
}
}
});

} else {
Toast.makeText(context, "授权失败", Toast.LENGTH_SHORT).show();
callbackContext.error(2);
}
}

@Override
public void onCancel(SHARE_MEDIA platform) {
}

@Override
public void onStart(SHARE_MEDIA platform) {
}
});

return true;
}

private boolean QQLogin(final CallbackContext callbackContext){

mController.doOauthVerify(context, SHARE_MEDIA.QQ, new SocializeListeners.UMAuthListener() {
@Override
public void onStart(SHARE_MEDIA platform) {
Toast.makeText(context, "授权开始", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(SocializeException e, SHARE_MEDIA platform) {
Toast.makeText(context, "授权错误", Toast.LENGTH_SHORT).show();
callbackContext.error(0);
}
@Override
public void onComplete(Bundle value, SHARE_MEDIA platform) {
Toast.makeText(context, "授权完成", Toast.LENGTH_SHORT).show();
//获取相关授权信息
mController.getPlatformInfo(context, SHARE_MEDIA.QQ, new SocializeListeners.UMDataListener() {
@Override
public void onStart() {
Toast.makeText(context, "获取平台数据开始...", Toast.LENGTH_SHORT).show();
}
@Override
public void onComplete(int status, Map<String, Object> info) {
if(status == 200 && info != null){
StringBuilder sb = new StringBuilder();
Set<String> keys = info.keySet();
sb.append("{");
for(String key : keys){
sb.append("\""+key+"\""+":"+"\""+info.get(key).toString()+"\",");
}
sb.delete(sb.length()-1,sb.length());
sb.append("}");
callbackContext.success(sb.toString());
Log.d("TestData",sb.toString());
}else{
Log.d("TestData","发生错误:"+status);
callbackContext.error(1);
}
}
});
}
@Override
public void onCancel(SHARE_MEDIA platform) {
Toast.makeText(context, "授权取消", Toast.LENGTH_SHORT).show();
callbackContext.error(2);
}
} );

return true;
}

}


其中的QQLogin和WBLogin分别完成了QQ登录和微博登录,并且通过callbackcontext返回了用户信息的json,其中代码都是从友盟官网copy的,详情参考文档

http://dev.umeng.com/social/android/detail-share#4

当然,在安卓项目的MainActivity中还需要做一下配置:

public class MainActivity extends CordovaActivity
{

UMSocialService mController;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mController = UMServiceFactory.getUMSocialService("com.umeng.login");
mController.getConfig().setSsoHandler(new SinaSsoHandler());
// Set by <content src="index.html" /> in config.xml
final Activity activity = this;

new AsyncTask<Object,Void,Void>(){

@Override
protected Void doInBackground(Object... params) {
UMQQSsoHandler qqSsoHandler = new UMQQSsoHandler(activity, "腾讯的AppId",
"腾讯的AppKey");
qqSsoHandler.addToSocialSDK();

return null;
}

}.execute();

loadUrl(launchUrl);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
/**使用SSO授权必须添加如下代码 */

UMSsoHandler ssoHandler = mController.getConfig().getSsoHandler(requestCode);
if(ssoHandler != null){
ssoHandler.authorizeCallBack(requestCode, resultCode, data);
}
}
}


这里也是根据友盟的官方文档.

现在,这个安卓项目已经可以返回json数据了,我们可以在ionic项目的任何地方调用QQ和微博登陆

ThirdParty.QQLogin(function(json){
//这是成功的回调
alert("QQ登陆成功,用户信息:"+json);
},function(failReason){
//这是失败的回调
alert("QQ登陆失败,失败类型:"+failReason);
});


ThirdParty.m

仿照ThirdParty.java,ThirdParty.m的写法如下:

#import "ThirdParty.h"
#import <TencentOpenAPI/QQApiInterface.h>
#import "UMSocial.h"

NSString *QQ_NOT_INSTALLED = @"QQ Client is not installed";
NSString *QQ_PARAM_NOT_FOUND = @"param is not found";
NSString *QQ_LOGIN_ERROR = @"QQ login error";
NSString *QQ_LOGIN_CANCEL = @"QQ login cancelled";
NSString *QQ_LOGIN_NETWORK_ERROR = @"QQ login network error";

@implementation ThirdParty

/**
*  QQ单点登录
*
*  @param command CDVInvokedUrlCommand
*/
- (void)QQLogin:(CDVInvokedUrlCommand *)command {
printf("登陆!");
UMSocialSnsPlatform *snsPlatform = [UMSocialSnsPlatformManager getSocialPlatformWithName:UMShareToQQ];

snsPlatform.loginClickHandler(self.viewController,[UMSocialControllerService defaultControllerService],YES,^(UMSocialResponseEntity *response){

//          获取微博用户名、uid、token等

if (response.responseCode == UMSResponseCodeSuccess) {

[[UMSocialDataService defaultDataService] requestSnsInformation:UMShareToQQ  completion:^(UMSocialResponseEntity *response){
//                NSString *string = [NSString stringWithFormat:@"%@",response.data];
NSString *sb = @"{";
NSArray *keys = response.data.keyEnumerator.allObjects;
NSArray *values = response.data.objectEnumerator.allObjects;
for (int i=0; i<response.data.count; i++) {
NSString *key_value = [NSString stringWithFormat:@"\"%@\":\"%@\",",keys[i],values[i]];
sb = [sb stringByAppendingString:key_value];
}
sb = [sb substringToIndex:sb.length-1];
sb = [sb stringByAppendingString:@"}"];
NSLog(@"%@",sb);
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:sb];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}];

}else{
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:1];

[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
});
}

//微博登陆
- (void)WBLogin:(CDVInvokedUrlCommand *)command {
printf("登陆!");
UMSocialSnsPlatform *snsPlatform = [UMSocialSnsPlatformManager getSocialPlatformWithName:UMShareToSina];

snsPlatform.loginClickHandler(self.viewController,[UMSocialControllerService defaultControllerService],YES,^(UMSocialResponseEntity *response){

//          获取微博用户名、uid、token等

if (response.responseCode == UMSResponseCodeSuccess) {

[[UMSocialDataService defaultDataService] requestSnsInformation:UMShareToSina  completion:^(UMSocialResponseEntity *response){
NSLog(@"SnsInformation is %@",response.data);
NSString *string = [NSString stringWithFormat:@"%@",response.data];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:string];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];

}];

}else{
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:1];

[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
});
}


AppDelegate相应的配置:

objective-c

[UMSocialData setAppKey:@"55d1e85c67e58e48a8000a30"];

[UMSocialQQHandler setQQWithAppId:@"QQ_APP_ID" appKey:@"QQ_APP_KEY" url:@"http://www.umeng.com/social"];

[UMSocialSinaHandler openSSOWithRedirectURL:@"http://sns.whalecloud.com/sina2/callback"];


这里微博的openSSOWithRedirectURL要与微博App设置的回调一致,具体的要求见友盟文档:

http://dev.umeng.com/social/ios/detail-share

最后将友盟sdk中ios的部分拖入xcode项目中得resource,如果报exit1 -lSocialSina之类的错误,是searchPath的问题,把友盟的包加入搜索路径即可.

之后在js中调用的方法与android一样.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  QQ登录-ion