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

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一样.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值