titanium module: shareSDK 的第三方登陆
访问量: 3770
shareSDK 是不错的第三方组件. 可以用它来做分享,登陆.
refer to: http://wiki.mob.com/%E7%AC%AC%E4%B8%89%E6%96%B9%E7%99%BB%E5%BD%95/
帮助在:http://dashboard.mob.com/ShareSDK/#/quickstarts/android
因为每个系统都会有自己的用户体系(数据库的用户表), 所以我们仅仅让用户与自己的happystock账号做关联.
1. 注册 mob.com
2. 下载对应的 shareSDK.tar.gz 文件,解压缩后, 得到了对应的文件.
对于titanium module的开发,最核心的两点是:
1. 会写,会看懂基本的 java/ oc代码,知道如何获取activiry , context等
2. 知道如何配置好第三方包的路径(在java下,直接copy jar文件到 lib/ 目录下)
然后,官方给出的使用步骤是:
要数据,不要功能
如果你的应用拥有用户系统,就是说你的应用自己就有注册和登录功能,使用第三方登录只是为了拥有更多用户,那么你可以依照下面的步骤来做:
1、用户触发第三方登录事件
2、showUser(null)请求授权用户的资料(这个过程中可能涉及授权操作)
3、如果onComplete()方法被回调,将其参数Hashmap代入你应用的Login流程
4、否则提示错误,调用removeAccount()方法,删除可能的授权缓存数据
5、Login时客户端发送用户资料中的用户ID给服务端
6、服务端判定用户是已注册用户,则引导用户进入系统,否则返回特定错误码
7、客户端收到“未注册用户”错误码以后,代入用户资料到你应用的Register流程
8、Register时在用户资料中挑选你应用的注册所需字段,并提交服务端注册
9、服务端完成用户注册,成功则反馈客户端引导用户进入系统
10、否则提示错误,调用removeAccount()方法,删除可能的授权缓存数据
看起来比较复杂, 待我仔细敲边代码:
1. create ti module : test_ti_module_qq_login
2. copy 需要的jar 到 android/lib 目录
3. 确认 android/build.properties 文件 是正确的. (记得提交到 git 之后,把它变成 .example 文件后缀)
否则你可能会收到这个提示:
Neither the ANDROID_NDK environment variable, or the android.ndk property is not set to an existing Android NDK installation (check your module's build.properties)
# 如果你明明安装了NDK, $ ant 的时候还会收到错误提示说找不到ndk, 就加上 android.ndk 这一行 titanium.platform=/home/sg552/.titanium/mobilesdk/linux/3.5.1.GA/android android.platform=/workspace/coding_tools/android-sdk-linux/platforms/android-14 google.apis=/workspace/coding_tools/android-sdk-linux/add-ons/addon-google_apis-google-14 android.ndk=/workspace/coding_tools/android-ndk-r10d
4. 上来先什么代码都不要写, 直接 $ cd android, $ ant
如果出现提示找不到 gperf, 就安装之: $ sudo apt-get install gperf
如果 出现提示说 生成不了文档, :
BUILD FAILED /home/sg552/.titanium/mobilesdk/linux/3.5.1.GA/module/android/build.xml:461: /workspace/test_ti_temp/android/build/docs does not exist.我们就修改 home 目录下的对应的build.xml 文件 , 让它不生成doc:
BUILD FAILED
/home/sg552/.titanium/mobilesdk/linux/3.5.1.GA/module/android/build.xml:461: /workspace/test_ti_temp/android/build/docs does not exist.
461 <zip destfile="${dist}/${module.id}-android-${manifest.version}.zip">
462 <zipfileset file="${module.jar}" prefix="${zip.prefix}"/>
463 <zipfileset file="manifest" prefix="${zip.prefix}"/>
464 <zipfileset file="timodule.xml" prefix="${zip.prefix}"/>
465 <!--
466 <zipfileset dir="${docs}" prefix="${zip.prefix}/documentation"/>
467 -->
4. 修改: android/src/ 目录下的 两个文件之一: TestTiModuleQqLogin (另一个叫: ExampleProxy )
public static void onAppCreate(TiApplication app) { Log.d(LCAT, "inside onAppCreate"); // 增加这一行 ShareSDK.initSDK(app); // 下面两行暂时用不到. SHAREICON = getApplicationResource(SHAREICONNAME); SHAREICONPATH = copyFileIntoSDCard(app, SHAREICONNAME+".jpg"); }
5. $ ant , 会得到一个 .zip 文件
开始测试 module:
1. 新建一个 titanium project
2. 把上面得到的 my_module.zip 文件, 复制到当前的项目的根目录下。
3. 修改 tiapp.xml
<modules> <module platform="android">com.apk</module> </modules>
4. 在 app/alloy.js 中引用:
var my_module = require('com.apk'); console.info('module: ' + my_module);
5. 然后,我们就可以在 controller js 代码中调用它们了。
记得两个要点: context 就是 TiApplication的一个实例, activity 可以通过 context.getCurrentActivity() 来获取。 例如:
// src/com/happysoft/login/SomeName.java @Kroll.onAppCreate public static void onAppCreate(TiApplication app) { android_context = app ; android_current_activity = android_context.getCurrentActivity(); // 其他操作 ShareSDK.initSDK(app) }
如果这个module 用不到 android view, 那么就直接在js代码中调用。
如果这个module 需要用到自己的VIEW, 接下来就是在controller中调用这个proxy
proxy 是在生成module的时候, 总共生成的两个java 文件的一个。
对于下面的两个 方法 (getter / setter ) ,
@Kroll.getProperty @Kroll.method public String getMessage() { return "Hello World from my module"; } @Kroll.setProperty @Kroll.method public void setMessage(String message) { Log.d(LCAT, "Tried setting module message to: " + message); } // 可以在js 中, 直接 proxy = my_module.createExample() proxy.message = 'lala' a = proxy.message // a is : 'lala'
my_module.createExample() 这个方法哪里来?
从 ExampleProxy.java 这个名字派生出来。 也就是说,如果你的Proxy名叫: AnotherStuffProxy.java, 那么就可以:
my_module.createAnotherStuff()
增加对应的appkey, appid, share_sdk_id
1. android/timodule.xml 增加内容:
<?xml version="1.0" encoding="UTF-8"?>
<ti:module xmlns:ti="http://ti.appcelerator.org" xmlns:android="http://schemas.android.com/apk/res/android">
<!--
Similar to tiapp.xml, but contains module/platform specific
configuration in <iphone>, <android>, and <mobileweb> sections
-->
<iphone>
</iphone>
<android xmlns:android="http://schemas.android.com/apk/res/android">
<manifest>
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<application>
<activity
android:name="cn.sharesdk.framework.ShareSDKUIShell"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden|adjustResize" >
<intent-filter>
<data android:scheme="tencent100371282" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity> <activity
android:name=".wxapi.WXEntryActivity"
android:exported="true"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
</application>
</manifest>
</android>
<mobileweb>
</mobileweb>
</ti:module>
2. android/assets/ShareSDK.xml 增加内容:
3. 运行代码。 之后就会出现微信登录的页面。
注意:初次开发不建议使用 微信登录, 最好用微博,QQ登录
因为微信对 签名要求的很严格, 必须appid, appkey, sign 一应俱全才行。 出了错误还没提示。。。
4. 登录后,就拉到了, 发现什么事儿也没发生。为什么呢? 因为我们还需要获取用户信息(参考: http://wiki.mob.com/%E8%8E%B7%E5%8F%96%E6%8E%88%E6%9D%83%E7%94%A8%E6%88%B7%E8%B5%84%E6%96%99-2/ )
具体的代码,见:src/cn/sharesdk/tpl/SignupPage.java
private void initData(){ String gender = ""; if(platform != null){ gender = platform.getDb().getUserGender(); if(gender.equals("m")){ userInfo.setUserGender(UserInfo.Gender.BOY); gender = getContext().getString(R.string.tpl_boy); }else{ userInfo.setUserGender(UserInfo.Gender.GIRL); gender = getContext().getString(R.string.tpl_girl); } userInfo.setUserIcon(platform.getDb().getUserIcon()); userInfo.setUserName(platform.getDb().getUserName()); userInfo.setUserNote(platform.getDb().getUserId()); }
如果出现 platform.getDb() 得到的数据都是空的话({}) , 就看下 platform.isValid() 的值, 如果是false. 说明授权未通过。
为什么是空呢?
初步判定是没有使用 微信 提供的 package, 以及没有通过打包。
下面的代码是登录成功后,java会调用的:
public void onComplete(Platform platform, int action, HashMapres) { System.out.println("==== in onComplete" + res); }
所以,当我们点击QQ 空间登录,然后输入完用户名和密码之后,结果如下(知道接下来该如何做了吧):
I/System.out( 4507): ==== in onComplete {ret=0, is_yellow_year_vip=0, figureurl_qq_1=http://q.qlogo.cn/qqapp/100371282/B5BB36F4766F3DC1F48E89231F232E5B/40, nickname=思维, figureurl_qq_2=http://q.qlogo.cn/qqapp/100371282/B5BB36F4766F3DC1F48E89231F232E5B/100, yellow_vip_level=0, is_lost=0, msg=, city=朝阳, figureurl_1=http://qzapp.qlogo.cn/qzapp/100371282/B5BB36F4766F3DC1F48E89231F232E5B/50, vip=0, figureurl_2=http://qzapp.qlogo.cn/qzapp/100371282/B5BB36F4766F3DC1F48E89231F232E5B/100, level=0, province=北京, gender=男, is_yellow_vip=0, figureurl=http://qzapp.qlogo.cn/qzapp/100371282/B5BB36F4766F3DC1F48E89231F232E5B/30}