用cordova插件实现ionic第三方登录,获取信息和分享
2015-08-28 00:45
731 查看
ionic是比较流行的跨平台移动app的开发工具,但是在开发一个信息聚合平台的时候发现一个问题,就是做QQ和微博分享的时候,ionic的js就不能处理了,所以需要写cordova插件.然后我用的是友盟的社会化分享组件,可以节省很多的代码,前提是你必须要有友盟的AppKey,腾讯和新浪的AppId并且完成了账号的绑定,具体流程见
http://dev.umeng.com/social/android/operation
plugin.xml是用来配置插件的
src中是各平台的原生代码
www是javascript调用原生代码的方法
这个js文件包含两个方法,QQLogin和WBLogin,传递的参数分别是成功的回调函数和失败的回调函数.
以上的配置根据你的需求进行替换
其中的QQLogin和WBLogin分别完成了QQ登录和微博登录,并且通过callbackcontext返回了用户信息的json,其中代码都是从友盟官网copy的,详情参考文档
http://dev.umeng.com/social/android/detail-share#4
当然,在安卓项目的MainActivity中还需要做一下配置:
这里也是根据友盟的官方文档.
现在,这个安卓项目已经可以返回json数据了,我们可以在ionic项目的任何地方调用QQ和微博登陆
AppDelegate相应的配置:
这里微博的openSSOWithRedirectURL要与微博App设置的回调一致,具体的要求见友盟文档:
http://dev.umeng.com/social/ios/detail-share
最后将友盟sdk中ios的部分拖入xcode项目中得resource,如果报exit1 -lSocialSina之类的错误,是searchPath的问题,把友盟的包加入搜索路径即可.
之后在js中调用的方法与android一样.
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一样.
相关文章推荐
- Objective-C 学习笔记:从HelloWorld开始
- DT梦工厂 第25课 Scala中curring实战详解
- Python中的字符串相关转换
- 系统host文件的作用有哪些
- 多线程开发之二 NSOperation
- linux grep使用以及grep使用练习
- 第1讲:Win32 PE病毒入门
- Android 数据库SQLite的操作总结
- 如何正确获得ListView的每一个item高度
- [C++11 并发编程] 14 关联任务与期望
- C#中要使ListBox使用AddRange()时,能够触发SelectedValueChanged事件
- 从零开始学 iOS 开发的15条建议
- 从零开始学 iOS 开发的15条建议
- 京东注册页面
- ionic 开发步骤
- 时间复杂度和空间复杂度详解
- New THUer | 如何提高科研效率
- hdu1575 Tr A(矩阵快速幂)
- tomcat启动startup.bat一闪而过
- ToolBar、TabLayout加角标无从下手?且看一看我的解决方法!