Android_SDK环境搭建
以下以eclipse为开发的IDE进行范例说明(sdk3.5.12前支持maven):
(1)创建一个工程,并把open-sdk.jar(压缩包中文件名为:open_sdk_xxxx_lite.jar)文件拷贝到libs(或lib)目录下,如下图所示:
(2)将open-sdk.jar加入编译路径中。
在build.gradle中添加
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
}
(3)配置AndroidManifest;
在应用的AndroidManifest.xml增加配置的<application>节点下增加以下配置(注:不配置将会导致无法调用API);
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <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你的AppId" /> </intent-filter> </activity> <activity android:name="com.tencent.connect.common.AssistActivity" android:configChanges="orientation|keyboardHidden|screenSize" android:screenOrientation="behind" android:theme="@android:style/Theme.Translucent.NoTitleBar" /> <application>
通过以上两个步骤,工程就已经配置完成了。接下来就可以在代码里使用QQ互联的SDK进行开发了。
2. 初始化SDK
3.5.7版本新增接口提供用户设置是否已授权获取设备信息,在调用互联SDK相关功能接口之前,需要应用在确认用户已授权应用获取设备信息后,调用下面代码通知 SDK:
Tencent.setIsPermissionGranted(true);
如果未调用该接口或传参为false时,调用其它功能接口将直接返回失败。
3.5.9版本中可以调用Tencent.setisPermissionGranted(true, Build.Model)传入Build.Model,传入后SDK内部不再自行获取。
3. 创建实例
Tencent是SDK的功能入口,所有的接口调用都得通过Tencent进行调用。因此,调用SDK,首先需要创建一个Tencent实例,其代码如下:
@Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Tencent类是SDK的主要实现类,开发者可通过Tencent类访问腾讯开放的OpenAPI。 // 其中APP_ID是分配给第三方应用的appid,类型为String。 // 其中Authorities为 Manifest文件中注册FileProvider时设置的authorities属性值 mTencent = Tencent.createInstance(APP_ID, this.getApplicationContext(), Authorities); // 1.4版本:此处需新增参数,传入应用程序的全局context,可通过activity的getApplicationContext方法获取 // 初始化视图 initViews(); }
其中,如果你已经添加了”android.permission.INTERNET”和”android.permission.ACCESS_NETWORK_STATE”权限,则无需重复添加。
而”你的AppId”则要替换成具体应用的AppId,例如你的AppId是”222222″,则<data>标签应该是这样的:
<data android:scheme="tencent222222" />
4. 实现回调
所有的SDK接口调用,都会传入一个回调,用以接收SDK返回的调用结果。回调的主要接口有两种:
(1) 实现回调 IUiListener
调用SDK已经封装好的接口时,例如:登录、快速支付登录、应用分享、应用邀请等接口,需传入该回调的实例。
IUiListener的实现示例代码如下:
private class BaseUiListener implements IUiListener { @Override public void onComplete(JSONObject response) { mBaseMessageText.setText("onComplete:"); mMessageText.setText(response.toString()); doComplete(response); } protected void doComplete(JSONObject values) { } @Override public void onError(UiError e) { showResult("onError:", "code:" + e.errorCode + ", msg:" + e.errorMessage + ", detail:" + e.errorDetail); } @Override public void onCancel() { showResult("onCancel", ""); } }
(2) 实现回调 IRequestListener
使用requestAsync、request等通用方法调用sdk未封装的接口时,例如上传图片、查看相册等,需传入该回调的实例。
IRequestListener的实现示例代码如下:
private class BaseApiListener implements IRequestListener { @Override public void onComplete(final JSONObject response, Object state) { showResult("IRequestListener.onComplete:", response.toString()); doComplete(response, state); } protected void doComplete(JSONObject response, Object state) { } @Override public void onIOException(final IOException e, Object state) { showResult("IRequestListener.onIOException:", e.getMessage()); } @Override public void onMalformedURLException(final MalformedURLException e, Object state) { showResult("IRequestListener.onMalformedURLException", e.toString()); } @Override public void onJSONException(final JSONException e, Object state) { showResult("IRequestListener.onJSONException:", e.getMessage()); } @Override public void onConnectTimeoutException(ConnectTimeoutException arg0, Object arg1) { // TODO Auto-generated method stub } @Override public void onSocketTimeoutException(SocketTimeoutException arg0, Object arg1) { // TODO Auto-generated method stub } //1.4版本中IRequestListener 新增两个异常 @Override public void onNetworkUnavailableException(NetworkUnavailableException e, Object state){ // 当前网络不可用时触发此异常 } @Override public void onHttpStatusException(HttpStatusException e, Object state) { // http请求返回码非200时触发此异常 } public void onUnknowException(Exception e, Object state) { // 出现未知错误时会触发此异常 } }
应用在调用SDK提供的接口时,将实现了对应回调接口的实例传入。当SDK的接口调用完成后,具体如登录、应用邀请和应用分享调用完成后,会回调传入的接口实例。
(3) 特别注意:
应用调用Andriod_SDK接口时,如果要成功接收到回调,需要在调用接口的Activity的onActivityResult方法中增加如下代码:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { mTencent.onActivityResult(requestCode, resultCode, data); }
5. 调用QQ登录接口
(1)QQ登录示例代码:
代码中的listener是IUiListener的一个实例。
public void login() { mTencent = Tencent.createInstance(AppId, this.getApplicationContext(), Authorities); if (!mTencent.isSessionValid()) { mTencent.login(this, Scope, listener); } }
注意:SDK内部采用弱引用的方式持有接口实例,因此在调用 Tencent.login() 时传入的 IUiListener 对象,应该定义为当前类的成员变量,避免用户拉起QQ的授权登录页面后,在登录页面停留较长时间后才进行授权时,SDK内部的弱引用被系统回收而导致回调没有被执行的问题。
(2) 效果展示:
如果用户手机上安装了最新版本的手机QQ,将会调用相应的客户端,通过SSO方式进行登录。此方式可以避免用户多次输入用户名和密码,提升用户的登录体验。
授权完成后,界面会自动返回应用界面。用户在应用中进行后续操作。
(3) 登录成功后获取的数据
登录成功后调用public void onComplete(JSONObject arg0) 回传的JsonObject, 其中包含OpenId, AccessToken等重要数据。
{ "ret":0, "pay_token":"xxxxxxxxxxxxxxxx", "pf":"openmobile_android", "expires_in":"7776000", "openid":"xxxxxxxxxxxxxxxxxxx", "pfkey":"xxxxxxxxxxxxxxxxxxx", "msg":"sucess", "access_token":"xxxxxxxxxxxxxxxxxxxxx" }
(4) 调用QQ注销接口
public void logout() { mTencent.logout(this); } 注:3.5.9版本中SDK内部只会在首次调用SDK接口时调用系统接口获取设备中QQ/Tim的安装信息,并缓存在内存中提供后续接口使用。当用户在设备中未安装QQ/Tim时启动接入应用,SDK获取到设备中未安装QQ/Tim并缓存了查询结果,如果接入应用需要引导用户安装QQ/Tim时,需要接入应用在调用接口重置SDK缓存的安装信息, 保证SDK能够正确判断设备中是否已经安装QQ。可以调用 tencent.isQQInstalled()方法判断SDK内存缓存中QQ是否已经安装,调用Tencent.resetTargetAppInfoCache()方法重置内存缓存。
6. 获取用户信息
(1) 异步方式调用
public void getUserInfo() { mTencent.requestAsync(Constants.GRAPH_SIMPLE_USER_INFO, null, Constants.HTTP_GET, new BaseApiListener("get_simple_userinfo", false), null); }
(2)同步方式调用
注意:由于同步调用直接访问网络,是延时性操作,需要放入线程中执行。
同步调用方式如下:
public void getUserInfoInThread() { new Thread(){ @Override public void run() { JSONObject json = mTencent.request(Constants.GRAPH_SIMPLE_USER_INFO, null, Constants.HTTP_GET); System.out.println(json); } }.start(); }
(3)用户信息详情:
{ "is_yellow_year_vip": "0", "ret": 0, "figureurl_qq_1": "http://q.qlogo.cn/qqapp/222222/8C75BBE3DC6B0E9A64BD31449A3C8CB0/40", "figureurl_qq_2": "http://q.qlogo.cn/qqapp/222222/8C75BBE3DC6B0E9A64BD31449A3C8CB0/100", "nickname": "小罗", "yellow_vip_level": "0", "msg": "", "figureurl_1": "http://qzapp.qlogo.cn/qzapp/222222/8C75BBE3DC6B0E9A64BD31449A3C8CB0/50", "vip": "0", "level": "0", "figureurl_2": "http://qzapp.qlogo.cn/qzapp/222222/8C75BBE3DC6B0E9A64BD31449A3C8CB0/100", "is_yellow_vip": "0", "gender": "男", "figureurl": "http://qzapp.qlogo.cn/qzapp/222222/8C75BBE3DC6B0E9A64BD31449A3C8CB0/30" }