├── .gitattributes
├── .gitignore
├── AndroidManifest.xml
├── README.md
├── gen
└── cstdr
│ └── weibosdk
│ └── demo
│ ├── BuildConfig.java
│ └── R.java
├── libs
├── SinaWeiboSDK.jar
├── TencentWeiboSDK.jar
├── TencentWeiboSDKComponent.jar
├── android-support-v4.jar
└── commons-httpclient-3.0.1.jar
├── proguard-project.txt
├── project.properties
├── res
├── drawable-hdpi
│ └── ic_launcher.png
├── drawable-mdpi
│ └── ic_launcher.png
├── drawable-xhdpi
│ └── ic_launcher.png
├── layout
│ └── main.xml
├── menu
│ └── activity_main.xml
├── values-v11
│ └── styles.xml
├── values-v14
│ └── styles.xml
└── values
│ ├── strings.xml
│ └── styles.xml
└── src
└── cstdr
└── weibosdk
└── demo
├── MainActivity.java
├── share
├── Constants.java
├── SinaWeiboAPI.java
├── SinaWeiboUtil.java
├── TencentTO.java
├── TencentWebAuthActivity.java
├── TencentWeiboAPI.java
└── TencentWeiboUtil.java
└── util
├── LOG.java
├── PreferenceUtil.java
└── Util.java
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 |
22 | # Locally stored "Eclipse launch configurations"
23 | *.launch
24 |
25 | # CDT-specific
26 | .cproject
27 |
28 | # PDT-specific
29 | .buildpath
30 |
31 |
32 | #################
33 | ## Visual Studio
34 | #################
35 |
36 | ## Ignore Visual Studio temporary files, build results, and
37 | ## files generated by popular Visual Studio add-ons.
38 |
39 | # User-specific files
40 | *.suo
41 | *.user
42 | *.sln.docstates
43 |
44 | # Build results
45 |
46 | [Dd]ebug/
47 | [Rr]elease/
48 | x64/
49 | build/
50 | [Bb]in/
51 | [Oo]bj/
52 |
53 | # MSTest test Results
54 | [Tt]est[Rr]esult*/
55 | [Bb]uild[Ll]og.*
56 |
57 | *_i.c
58 | *_p.c
59 | *.ilk
60 | *.meta
61 | *.obj
62 | *.pch
63 | *.pdb
64 | *.pgc
65 | *.pgd
66 | *.rsp
67 | *.sbr
68 | *.tlb
69 | *.tli
70 | *.tlh
71 | *.tmp
72 | *.tmp_proj
73 | *.log
74 | *.vspscc
75 | *.vssscc
76 | .builds
77 | *.pidb
78 | *.log
79 | *.scc
80 |
81 | # Visual C++ cache files
82 | ipch/
83 | *.aps
84 | *.ncb
85 | *.opensdf
86 | *.sdf
87 | *.cachefile
88 |
89 | # Visual Studio profiler
90 | *.psess
91 | *.vsp
92 | *.vspx
93 |
94 | # Guidance Automation Toolkit
95 | *.gpState
96 |
97 | # ReSharper is a .NET coding add-in
98 | _ReSharper*/
99 | *.[Rr]e[Ss]harper
100 |
101 | # TeamCity is a build add-in
102 | _TeamCity*
103 |
104 | # DotCover is a Code Coverage Tool
105 | *.dotCover
106 |
107 | # NCrunch
108 | *.ncrunch*
109 | .*crunch*.local.xml
110 |
111 | # Installshield output folder
112 | [Ee]xpress/
113 |
114 | # DocProject is a documentation generator add-in
115 | DocProject/buildhelp/
116 | DocProject/Help/*.HxT
117 | DocProject/Help/*.HxC
118 | DocProject/Help/*.hhc
119 | DocProject/Help/*.hhk
120 | DocProject/Help/*.hhp
121 | DocProject/Help/Html2
122 | DocProject/Help/html
123 |
124 | # Click-Once directory
125 | publish/
126 |
127 | # Publish Web Output
128 | *.Publish.xml
129 | *.pubxml
130 |
131 | # NuGet Packages Directory
132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
133 | #packages/
134 |
135 | # Windows Azure Build Output
136 | csx
137 | *.build.csdef
138 |
139 | # Windows Store app package directory
140 | AppPackages/
141 |
142 | # Others
143 | sql/
144 | *.Cache
145 | ClientBin/
146 | [Ss]tyle[Cc]op.*
147 | ~$*
148 | *~
149 | *.dbmdl
150 | *.[Pp]ublish.xml
151 | *.pfx
152 | *.publishsettings
153 |
154 | # RIA/Silverlight projects
155 | Generated_Code/
156 |
157 | # Backup & report files from converting an old project file to a newer
158 | # Visual Studio version. Backup files are not needed, because we have git ;-)
159 | _UpgradeReport_Files/
160 | Backup*/
161 | UpgradeLog*.XML
162 | UpgradeLog*.htm
163 |
164 | # SQL Server files
165 | App_Data/*.mdf
166 | App_Data/*.ldf
167 |
168 | #############
169 | ## Windows detritus
170 | #############
171 |
172 | # Windows image file caches
173 | Thumbs.db
174 | ehthumbs.db
175 |
176 | # Folder config file
177 | Desktop.ini
178 |
179 | # Recycle Bin used on file shares
180 | $RECYCLE.BIN/
181 |
182 | # Mac crap
183 | .DS_Store
184 |
185 |
186 | #############
187 | ## Python
188 | #############
189 |
190 | *.py[co]
191 |
192 | # Packages
193 | *.egg
194 | *.egg-info
195 | dist/
196 | build/
197 | eggs/
198 | parts/
199 | var/
200 | sdist/
201 | develop-eggs/
202 | .installed.cfg
203 |
204 | # Installer logs
205 | pip-log.txt
206 |
207 | # Unit test / coverage reports
208 | .coverage
209 | .tox
210 |
211 | #Translations
212 | *.mo
213 |
214 | #Mr Developer
215 | .mr.developer.cfg
216 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### 新浪微博、腾讯微博开放平台DEMO(WeiboSDKDemo)
2 |
3 | > ####20140105 因为新浪官方微博更新频繁,并且现在新浪的文档比较完善,建议大家先浏览[新浪官方GitHub][SinaWeiboGitHub]~
4 |
5 | * 最近学习开放平台,官方文档和Demo有点坑爹,经过几天的努力,写了一个DEMO,整合了新浪微博和腾讯微博,均能够SSO授权、网页授权和发微博,如果需要可以去看看源码,里面有注释说明
6 | * 代码使用自己感觉舒服的方式进行封装和整合,使用前需要修改的地方在下面有详细说明,如果有问题请随时联系我,或者咱们一起完善!~
7 | * 代码并没有整合所有API方法(其实我觉得这也没必要),当你需要哪个API接口,可以马上去官网查看API文档(文档也会变的),然后添加上去就可以啦~
8 |
9 | * 官方新浪微博SDK地址:https://github.com/mobileresearch/weibo_android_sdk
10 | * 新浪API文档:http://open.weibo.com/wiki/%E5%BE%AE%E5%8D%9AAPI
11 |
12 | * 官方腾讯微博SDK地址:http://wiki.open.t.qq.com/index.php/%E7%A7%BB%E5%8A%A8%E5%BA%94%E7%94%A8%E6%8E%A5%E5%85%A5
13 | * 腾讯API文档:http://wiki.open.t.qq.com/index.php/API%E6%96%87%E6%A1%A3
14 |
15 | ***
16 |
17 | ### WeiboSDKDemo使用方法
18 |
19 | * 请先熟悉官方文档,虽然其中有一些问题:)
20 | * 根据文档申请开放平台帐号,特别注意回调地址,官网和代码中要保持一致,这个经常出现错误;
21 | * 运行Demo前,先确定下载完Demo的所有文件,有关jar包的问题可以参考官方文档,都是必须的依赖包;
22 | * 然后修改开放平台的AppKey和AppSecret:
23 |
24 | 1. 新浪微博需要在Constants类中把appkey、appsecret修改成自己应用对应的appkey和appsecret,回调地址不需要修改;
25 | 1. 腾讯微博需要修改配置文件,目标文件config.properties在Android_SDK.jar包config文件夹下(我已经改名为TencentWeiboSDK.jar),把appkey、appsecret修改成自己应用对应的appkey和appsecret,这里再次提醒注意回调地址要和网上你填写的一致,别管文档怎么说.
26 |
27 | * 修改完后,clean工程,运行测试吧!
28 |
29 | ### 网友反馈QA
30 |
31 | * 特别注意!
32 |
33 | 如果使用Eclipse无法直接导入工程,请新建一个工程,将代码资源等复制到新工程,再根据上面的步骤修改AppKey等内容~
34 |
35 | * (20131024)Q:新浪微博SSO授权无法正常授权,我是新注册的开发者账号。
36 | > A:根据最新的官方文档,原因应该是没有在网站注册包名和签名,注册步骤可以参考官方文档,不多说啦~
37 |
38 | * (20130901)Q:新浪微博SSO授权还让输入一次账号密码。
39 | > A:这是我自己使用的时候发现的,用公司审核过的APP可以直接SSO授权不会再次输入,也许这就是原因吧~(请参考20131024的反馈)
40 |
41 | * (20130830)Q:新浪微博SSO正常,但是网页授权不成功。
42 | > A:最近也有几个开发者反馈给我,同样的代码,用我以前申请的账号的Key可以授权成功,开发者新申请的账号Key却不能,一个开发者用其他Demo可以正常授权,猜想是SDK版本不同导致的授权问题,我目前的Demo使用的是3个月前的SDK,周末会更新到最新SDK,期待到时候问题会解决~(已经更新到最新SDK0821)(请参考20131024的反馈)
43 |
44 | * (20130819)Q:新浪微博我都按照文档设置了,为啥还是获取不到token?
45 | > A:也许是你没有设置“测试账号”,“管理中心”->左面的“应用信息”->“测试账号”,已关联测试帐号只能添加15个人~
46 |
47 | * (20130629)Q:导入工程后点击腾讯微博授权(没有安装腾讯微博客户端),结果报错找不到类TencentWebAuthActivity?
48 | > A:请到Manifest文件重新设置改类的路径地址~
49 |
50 | * (20130625)Q:新浪微博的回调地址在哪里设置?
51 | > A:“管理中心”->左面的“应用信息”->“高级信息”->左面的“授权回调页”,就是这个地方,使用代码中的默认地址(https://api.weibo.com/oauth2/default.html )即可,注意保持一致~
52 |
53 | * (20130619)Q:腾讯微博的jar包如何修改Appkey等参数?
54 | > A:不能在Eclipse中打开,要到项目的目录下用任何解压缩工具打开jar包并修改config.properties文件然后保存即可~
55 |
56 | * (20130604)Q:腾讯微博的回调地址在哪里设置?
57 | > A:“管理中心”->“基本信息”->“应用地址”,就是这个地方,注意保持一致~
58 |
59 | 感谢大家的反馈和建议!~
60 |
61 | 下面是我自己的一点总结,如果你有好的建议,请分享下吧~
62 |
63 | ***
64 |
65 | ### 新浪微博平台:
66 |
67 | * SSO一直没有测试成功,运行官方DEMO也如此,没有找到解决方法,已经确认是新浪的问题,没有开放大量注册,官方建议先使用老版本SDK ;今天发现新浪更新了文档和jar包,SSO可以正常使用,返回Token、uid、userName等信息;
68 | * SSO和网页授权得到的都是授权Code,不是Token,所以还需要根据Code去获取Token,调用getAccessTokenByCode 方法利用官方API接口获取到Token;
69 | * 目前网页授权、微博分享都操作已经整合到工程中,测试正常;
70 | * 新浪另一个问题,token过期后需要用户登陆重新授权。
71 |
72 | ### 新浪SSO授权返回值:(缺少UserName,所以授权后再去获取了一次取)
73 |
74 | 1. key = uid value = 1111111111 ;
75 | 1. key = userName value = cstdr ;(最新SDK0821已经没有返回这个字段)
76 | 1. key = expires_in value = 157186399 ;
77 | 1. key = remind_in value = 157186399 ;
78 | 1. key = access_token value = 2.00KNDUIDyonFnC99e5598a960gYir2 。
79 |
80 | ### 新浪网页授权返回值:(缺少UserName,所以授权后再去获取了一次)
81 |
82 | 1. key = uid value = 1111111111 ;
83 | 1. key = expires_in value = 157185966 ;
84 | 1. key = remind_in value = 157185966 ;
85 | 1. key = access_token value = 2.00KNDUIDyonFnC99e5598a960gYir2 。
86 |
87 | ***
88 |
89 | ### 腾讯微博平台:
90 |
91 | * SSO可以正常获取;
92 | * 因为获取授权时Refreshtoken 总为null,所以不能使用官方SDK自带方法,于是把新浪微博的方法修改,使之适用于腾讯微博;
93 | * 回调地址文档说可以为空,但是实际上为空不能网页授权,必须与网站上填写的一致,否则分享微博的时候总是说回调地址错误,所以重新修改了网页授权的Activity;
94 | * 网页授权的Activity不仅仅是回调地址为空问题,还因为没有回调方法,不能得到授权正确与否的消息,也就不能修改UI和数据,所以修改后添加了回调方法。
95 |
96 | ### 腾讯SSO授权返回值:(返回WeiboToken ,但是缺少UserName,还需要再获取一次)
97 |
98 | 1. token.accessToken = 8e509ffc2cbad04e1678d9e2b1822970 ;
99 | 1. token.expiresIn = 604800 ;
100 | 1. token.omasKey = 9a23c968893edb64fc35fa33f7b44c05 ;
101 | 1. token.omasToken = 010000008790cc668e6ed810b2cffc374f9a3dd9ed126be4a279eff1c0c1a6852ea048019c4c6746cb40ce72 ;
102 | 1. token.openID = 5789a9d103704e1f63102b1dba348690 ;(即uid)
103 | 1. token.refreshToken = 。(总为空)
104 |
105 | ### 腾讯网页授权返回值:(所需全有,不用再获取)
106 |
107 | 1. accessToken = 8e509ffc2cbad04e1678d9e2b1822970 ;
108 | 1. expiresIn = 8035200 ;
109 | 1. omasKey = 090FF697B85D63703AAA4AB6642650EB ;
110 | 1. openID = 5789A9D103704E1F63102B1DBA348690 ;
111 | 1. refreshToken = 359107cbc9f7a43b69ccaaafadf14ff1 ;
112 | 1. state = 111 ;
113 | 1. name = name ;
114 | 1. nick = nick 。
115 |
116 | ***
117 |
118 | ## 联系或反馈
119 |
120 | 如果你有任何问题、建议或者想交个朋友,请联系我吧~
121 |
122 | 我的邮箱: cstdingran(at)gmail.com (讨论问题请通过邮件)
123 |
124 |
125 | [](https://bitdeli.com/free "Bitdeli Badge")
126 |
127 | [SinaWeiboGitHub]:https://github.com/mobileresearch/weibo_android_sdk
128 |
--------------------------------------------------------------------------------
/gen/cstdr/weibosdk/demo/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /** Automatically generated file. DO NOT MODIFY */
2 | package cstdr.weibosdk.demo;
3 |
4 | public final class BuildConfig {
5 | public final static boolean DEBUG = true;
6 | }
--------------------------------------------------------------------------------
/gen/cstdr/weibosdk/demo/R.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 |
8 | package cstdr.weibosdk.demo;
9 |
10 | public final class R {
11 | public static final class attr {
12 | }
13 | public static final class drawable {
14 | public static final int ic_launcher=0x7f020000;
15 | }
16 | public static final class id {
17 | public static final int btn_add_sina=0x7f070008;
18 | public static final int btn_add_tx=0x7f070003;
19 | public static final int btn_auth_sina=0x7f070007;
20 | public static final int btn_auth_tx=0x7f070002;
21 | public static final int btn_logout_sina=0x7f070009;
22 | public static final int btn_logout_tx=0x7f070004;
23 | public static final int menu_settings=0x7f07000a;
24 | public static final int tv_auth_sina=0x7f070005;
25 | public static final int tv_auth_tx=0x7f070000;
26 | public static final int tv_token_sina=0x7f070006;
27 | public static final int tv_token_tx=0x7f070001;
28 | }
29 | public static final class layout {
30 | public static final int main=0x7f030000;
31 | }
32 | public static final class menu {
33 | public static final int activity_main=0x7f060000;
34 | }
35 | public static final class string {
36 | public static final int app_name=0x7f040000;
37 | public static final int hello_world=0x7f040001;
38 | public static final int menu_settings=0x7f040002;
39 | }
40 | public static final class style {
41 | /**
42 | Base application theme, dependent on API level. This theme is replaced
43 | by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
44 |
45 |
46 | Theme customizations available in newer API levels can go in
47 | res/values-vXX/styles.xml, while customizations related to
48 | backward-compatibility can go here.
49 |
50 |
51 | Base application theme for API 11+. This theme completely replaces
52 | AppBaseTheme from res/values/styles.xml on API 11+ devices.
53 |
54 | API 11 theme customizations can go here.
55 |
56 | Base application theme for API 14+. This theme completely replaces
57 | AppBaseTheme from BOTH res/values/styles.xml and
58 | res/values-v11/styles.xml on API 14+ devices.
59 |
60 | API 14 theme customizations can go here.
61 | */
62 | public static final int AppBaseTheme=0x7f050000;
63 | /** Application theme.
64 | All customizations that are NOT specific to a particular API-level can go here.
65 | */
66 | public static final int AppTheme=0x7f050001;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/libs/SinaWeiboSDK.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cstdr/WeiboSDKDemo/572ca4c79ededc39fe71cd516044ef78c74aac32/libs/SinaWeiboSDK.jar
--------------------------------------------------------------------------------
/libs/TencentWeiboSDK.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cstdr/WeiboSDKDemo/572ca4c79ededc39fe71cd516044ef78c74aac32/libs/TencentWeiboSDK.jar
--------------------------------------------------------------------------------
/libs/TencentWeiboSDKComponent.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cstdr/WeiboSDKDemo/572ca4c79ededc39fe71cd516044ef78c74aac32/libs/TencentWeiboSDKComponent.jar
--------------------------------------------------------------------------------
/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cstdr/WeiboSDKDemo/572ca4c79ededc39fe71cd516044ef78c74aac32/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/libs/commons-httpclient-3.0.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cstdr/WeiboSDKDemo/572ca4c79ededc39fe71cd516044ef78c74aac32/libs/commons-httpclient-3.0.1.jar
--------------------------------------------------------------------------------
/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-17
15 |
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cstdr/WeiboSDKDemo/572ca4c79ededc39fe71cd516044ef78c74aac32/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cstdr/WeiboSDKDemo/572ca4c79ededc39fe71cd516044ef78c74aac32/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cstdr/WeiboSDKDemo/572ca4c79ededc39fe71cd516044ef78c74aac32/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
20 |
21 |
25 |
26 |
31 |
32 |
37 |
38 |
43 |
44 |
45 |
51 |
52 |
58 |
59 |
63 |
64 |
69 |
70 |
75 |
76 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/res/menu/activity_main.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | WeiboSDKDemo
5 | Hello world!
6 | Settings
7 |
8 |
--------------------------------------------------------------------------------
/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
--------------------------------------------------------------------------------
/src/cstdr/weibosdk/demo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package cstdr.weibosdk.demo;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 | import android.os.Handler;
8 | import android.text.TextUtils;
9 | import android.util.Log;
10 | import android.view.Menu;
11 | import android.view.View;
12 | import android.view.View.OnClickListener;
13 | import android.widget.Button;
14 | import android.widget.TextView;
15 | import cstdr.weibosdk.demo.share.Constants;
16 | import cstdr.weibosdk.demo.share.SinaWeiboUtil;
17 | import cstdr.weibosdk.demo.share.TencentWeiboUtil;
18 | import cstdr.weibosdk.demo.util.LOG;
19 | import cstdr.weibosdk.demo.util.PreferenceUtil;
20 | import cstdr.weibosdk.demo.util.Util;
21 |
22 | /**
23 | * 主界面
24 | *
25 | * @author cstdingran@gmail.com
26 | *
27 | */
28 | public class MainActivity extends Activity {
29 |
30 | private static final String TAG = "MainActivity";
31 |
32 | private Context mContext = null;
33 |
34 | private static Handler mHandler;
35 |
36 | // 腾讯微博===================================
37 |
38 | private TextView mTvAuthTX;
39 |
40 | private TextView mTvTokenTX;
41 |
42 | private Button mBtnAuthTX;
43 |
44 | private Button mBtnAddTX;
45 |
46 | private Button mBtnLogoutTX;
47 |
48 | // 新浪微博===================================
49 |
50 | private TextView mTvAuthSina;
51 |
52 | private TextView mTvTokenSina;
53 |
54 | private Button mBtnAuthSina;
55 |
56 | private Button mBtnAddSina;
57 |
58 | private Button mBtnLogoutSina;
59 |
60 | @Override
61 | protected void onCreate(Bundle savedInstanceState) {
62 | super.onCreate(savedInstanceState);
63 | setContentView(R.layout.main);
64 | Log.i(TAG, "============onCreate==================");
65 | mContext = this;
66 | initView();
67 | refreshView();
68 | }
69 |
70 | private void initView() {
71 | // TX
72 | initTvAuthTX();
73 | initTvTokenTX();
74 | initBtnAuthTX();
75 | initBtnAddTX();
76 | initBtnLogoutTX();
77 | // sina
78 | initTvAuthSina();
79 | initTvTokenSina();
80 | initBtnAuthSina();
81 | initBtnAddSina();
82 | initBtnLogoutSina();
83 | }
84 |
85 | // TX ================================================================
86 |
87 | private void initBtnLogoutTX() {
88 | mBtnLogoutTX = (Button) findViewById(R.id.btn_logout_tx);
89 | mBtnLogoutTX.setOnClickListener(new OnClickListener() {
90 |
91 | @Override
92 | public void onClick(View v) {
93 | TencentWeiboUtil.getInstance(mContext).logout(new WeiboListener() {
94 |
95 | @Override
96 | public void onResult() {
97 | refreshView();
98 | }
99 |
100 | });
101 | }
102 | });
103 | }
104 |
105 | private void initBtnAddTX() {
106 | mBtnAddTX = (Button) findViewById(R.id.btn_add_tx);
107 | mBtnAddTX.setOnClickListener(new OnClickListener() {
108 |
109 | @Override
110 | public void onClick(View v) {
111 | TencentWeiboUtil.getInstance(mContext).addWeibo("腾讯微博开放平台,Hello world!~", 0, 0, 0, 0);
112 | }
113 | });
114 | }
115 |
116 | private void initBtnAuthTX() {
117 | mBtnAuthTX = (Button) findViewById(R.id.btn_auth_tx);
118 | mBtnAuthTX.setOnClickListener(new OnClickListener() {
119 |
120 | @Override
121 | public void onClick(View v) {
122 | if (Util.checkNet(mContext)) {
123 | TencentWeiboUtil.getInstance(mContext).auth(new WeiboListener() {
124 |
125 | @Override
126 | public void onResult() {
127 | MainActivity.getHandler().post(new Runnable() {
128 |
129 | @Override
130 | public void run() {
131 | refreshView();
132 | }
133 | });
134 | }
135 | });
136 | }
137 | }
138 | });
139 | }
140 |
141 | private void initTvTokenTX() {
142 | mTvTokenTX = (TextView) findViewById(R.id.tv_token_tx);
143 | }
144 |
145 | private void initTvAuthTX() {
146 | mTvAuthTX = (TextView) findViewById(R.id.tv_auth_tx);
147 | }
148 |
149 | // sina
150 | // ==========================================================================
151 |
152 | private void initBtnLogoutSina() {
153 | mBtnLogoutSina = (Button) findViewById(R.id.btn_logout_sina);
154 | mBtnLogoutSina.setOnClickListener(new OnClickListener() {
155 |
156 | @Override
157 | public void onClick(View v) {
158 | SinaWeiboUtil.getInstance(mContext).logout(new WeiboListener() {
159 |
160 | @Override
161 | public void onResult() {
162 | refreshView();
163 | }
164 |
165 | });
166 | }
167 | });
168 | }
169 |
170 | private void initBtnAddSina() {
171 | mBtnAddSina = (Button) findViewById(R.id.btn_add_sina);
172 | mBtnAddSina.setOnClickListener(new OnClickListener() {
173 |
174 | @Override
175 | public void onClick(View v) {
176 | SinaWeiboUtil.getInstance(mContext).update("新浪微博开放平台,Hello world!~", null, null);
177 |
178 | // TODO 发送本地图片微博
179 | // String dir =
180 | // Environment.getExternalStorageDirectory().getAbsolutePath();
181 | // String picPath = dir + "/cstdrpic.jpg"; // 需要改成你SD卡下的图片地址
182 | // SinaWeiboUtil.getInstance(mContext).upload("测试,新浪微博开放平台图片微博~~",
183 | // picPath, null, null);
184 | // LOG.cstdr(TAG, "picPath = " + picPath);
185 |
186 | // TODO 指定一个图片URL地址抓取后上传并同时发布一条新微博
187 | // // 图片的URL地址,必须以http开头。
188 | // String picUrl =
189 | // "https://www.google.com.hk/images/srpr/logo4w.png";
190 | // SinaWeiboUtil.getInstance(mContext).uploadUrlText("测试,新浪微博开放平台图片微博~~",
191 | // picUrl, null, null);
192 | // LOG.cstdr(TAG, "picUrl = " + picUrl);
193 | }
194 | });
195 | }
196 |
197 | private void initBtnAuthSina() {
198 | mBtnAuthSina = (Button) findViewById(R.id.btn_auth_sina);
199 | mBtnAuthSina.setOnClickListener(new OnClickListener() {
200 |
201 | @Override
202 | public void onClick(View v) {
203 | if (Util.checkNet(mContext)) {
204 | SinaWeiboUtil.getInstance(mContext).auth(new WeiboListener() {
205 |
206 | @Override
207 | public void onResult() {
208 | MainActivity.getHandler().post(new Runnable() {
209 |
210 | @Override
211 | public void run() {
212 | refreshView();
213 | }
214 | });
215 | }
216 | });
217 | }
218 | }
219 | });
220 | }
221 |
222 | private void initTvTokenSina() {
223 | mTvTokenSina = (TextView) findViewById(R.id.tv_token_sina);
224 | }
225 |
226 | private void initTvAuthSina() {
227 | mTvAuthSina = (TextView) findViewById(R.id.tv_auth_sina);
228 | }
229 |
230 | //
231 |
232 | /**
233 | * 刷新View
234 | */
235 | private void refreshView() {
236 | String sinaToken = PreferenceUtil.getInstance(mContext).getString(Constants.PREF_SINA_ACCESS_TOKEN, "");
237 | String tencentToken = PreferenceUtil.getInstance(mContext).getString(Constants.PREF_TX_ACCESS_TOKEN, "");
238 | LOG.cstdr("refreshUserView", "sinaToken = " + sinaToken + " tencentToken = " + tencentToken);
239 |
240 | if (TextUtils.isEmpty(sinaToken) && TextUtils.isEmpty(tencentToken)) { // 未授权
241 | MainActivity.getHandler().post(new Runnable() {
242 |
243 | @Override
244 | public void run() {
245 | mTvAuthTX.setText("未授权");
246 | mTvAuthSina.setText("未授权");
247 | Util.showToast(mContext, "未授权");
248 | }
249 | });
250 | } else {
251 | if (!TextUtils.isEmpty(tencentToken)) { // 初始化腾讯微博,判断是否授权过期
252 | TencentWeiboUtil.getInstance(mContext).initTencentWeibo(new WeiboListener() {
253 |
254 | @Override
255 | public void init(boolean isValid) {
256 | LOG.cstdr("txtxt~~~~~~~~~~~~isValid = ", isValid + "");
257 | if (isValid) {
258 | mTvAuthTX.setText("腾讯微博已授权");
259 | String token = PreferenceUtil.getInstance(mContext).getString(
260 | Constants.PREF_TX_ACCESS_TOKEN, "");
261 | String openId = PreferenceUtil.getInstance(mContext).getString(Constants.PREF_TX_OPEN_ID,
262 | "");
263 | String name = PreferenceUtil.getInstance(mContext).getString(Constants.PREF_TX_NAME, "");
264 | String expiresTime = PreferenceUtil.getInstance(mContext).getString(
265 | Constants.PREF_TX_EXPIRES_TIME, "");
266 | String clientIp = PreferenceUtil.getInstance(mContext).getString(
267 | Constants.PREF_TX_CLIENT_IP, "");
268 | mTvTokenTX.setText("token = " + token + "\nopenId = " + openId + "\nname = " + name
269 | + "\nexpiresTime = " + expiresTime + "\nclientIp = " + clientIp);
270 |
271 | MainActivity.getHandler().post(new Runnable() {
272 |
273 | @Override
274 | public void run() {
275 | Util.showToast(mContext, "腾讯微博已授权");
276 | }
277 | });
278 | } else {
279 | mTvAuthTX.setText("授权已过期");
280 | MainActivity.getHandler().post(new Runnable() {
281 |
282 | @Override
283 | public void run() {
284 | Util.showToast(mContext, "腾讯微博授权已过期,请重新绑定。");
285 | }
286 | });
287 | }
288 | }
289 | });
290 | }
291 | if (!TextUtils.isEmpty(sinaToken)) { // 初始化新浪微博,判断是否授权过期
292 | SinaWeiboUtil.getInstance(mContext).initSinaWeibo(new WeiboListener() {
293 |
294 | @Override
295 | public void init(boolean isValid) {
296 | LOG.cstdr("sina~~~~~~~~~~~~isValid = ", isValid + "");
297 | if (isValid) {
298 | mTvAuthSina.setText("新浪微博已授权");
299 | String token = PreferenceUtil.getInstance(mContext).getString(
300 | Constants.PREF_SINA_ACCESS_TOKEN, "");
301 | long expiresTime = PreferenceUtil.getInstance(mContext).getLong(
302 | Constants.PREF_SINA_EXPIRES_TIME, 0);
303 | String uid = PreferenceUtil.getInstance(mContext).getString(Constants.PREF_SINA_UID, "");
304 | String userName = PreferenceUtil.getInstance(mContext).getString(
305 | Constants.PREF_SINA_USER_NAME, "");
306 | String remindIn = PreferenceUtil.getInstance(mContext).getString(
307 | Constants.PREF_SINA_REMIND_IN, "");
308 | mTvTokenSina.setText("access_token 仍在有效期内,无需再次登录: \naccess_token:" + token
309 | + "\nexpiresTime:" + expiresTime + "\nuid:" + uid + "\nuserName:" + userName
310 | + "\nremindIn:" + remindIn);
311 |
312 | MainActivity.getHandler().post(new Runnable() {
313 |
314 | @Override
315 | public void run() {
316 | Util.showToast(mContext, "新浪微博已授权");
317 | }
318 | });
319 | } else {
320 | mTvAuthSina.setText("授权已过期");
321 | MainActivity.getHandler().post(new Runnable() {
322 |
323 | @Override
324 | public void run() {
325 | Util.showToast(mContext, "新浪微博授权已过期,请重新绑定。");
326 | }
327 | });
328 | }
329 | }
330 | });
331 | }
332 | }
333 | }
334 |
335 | @Override
336 | public boolean onCreateOptionsMenu(Menu menu) {
337 | // Inflate the menu; this adds items to the action bar if it is present.
338 | getMenuInflater().inflate(R.menu.activity_main, menu);
339 | return true;
340 | }
341 |
342 | @Override
343 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
344 | super.onActivityResult(requestCode, resultCode, data);
345 | LOG.cstdr(TAG, "===================onActivityResult===========requestCode = " + requestCode);
346 | // sso 授权回调
347 | if (requestCode == 32973) {
348 | SinaWeiboUtil.getInstance(mContext).authCallBack(requestCode, resultCode, data);
349 | } else if (requestCode == 1) {
350 | TencentWeiboUtil.getInstance(mContext).webAuthOnResult();
351 | }
352 | }
353 |
354 | /**
355 | * 授权回调类
356 | */
357 | public class WeiboListener {
358 |
359 | public void init(boolean isValid) {
360 | }
361 |
362 | public void onResult() {
363 | }
364 | }
365 |
366 | public static Handler getHandler() {
367 | if (mHandler == null) {
368 | mHandler = new Handler();
369 | }
370 | return mHandler;
371 | }
372 |
373 | @Override
374 | protected void onResume() {
375 | super.onResume();
376 | Log.i(TAG, "============onResume==================");
377 | }
378 |
379 | @Override
380 | protected void onRestart() {
381 | super.onRestart();
382 | Log.i(TAG, "============onRestart==================");
383 |
384 | }
385 |
386 | @Override
387 | protected void onPause() {
388 | super.onPause();
389 | Log.i(TAG, "============onPause==================");
390 |
391 | }
392 |
393 | @Override
394 | protected void onStop() {
395 | super.onStop();
396 | Log.i(TAG, "============onStop==================");
397 |
398 | }
399 |
400 | @Override
401 | protected void onDestroy() {
402 | super.onDestroy();
403 | Log.i(TAG, "============onDestroy==================");
404 | }
405 |
406 | }
407 |
--------------------------------------------------------------------------------
/src/cstdr/weibosdk/demo/share/Constants.java:
--------------------------------------------------------------------------------
1 | package cstdr.weibosdk.demo.share;
2 |
3 | /**
4 | * 开放平台常量,注意修改相关字段
5 | *
6 | * @author cstdingran@gmail.com
7 | *
8 | */
9 | public interface Constants {
10 |
11 | // 新浪微博======================================================
12 |
13 | /** 申请的appkey,修改成你自己的才能使用 **/
14 | String SINA_APP_KEY = "230409856";
15 |
16 | /** 申请的App Secret,修改成你自己的才能使用 **/
17 | String SINA_APP_SECRET = "c4bb2921f622f256d3e2766c8aeb72a1";
18 |
19 | // 回调地址,移动APP使用官方默认地址
20 | String SINA_REDIRECT_URL = "https://api.weibo.com/oauth2/default.html";
21 |
22 | // 新支持scope 支持传入多个scope权限,用逗号分隔,暂时用不上
23 | String SINA_SCOPE = "email,direct_messages_read,direct_messages_write,"
24 | + "friendships_groups_read,friendships_groups_write,statuses_to_me_read," + "follow_app_official_microblog";
25 |
26 | /** 认证Code **/
27 | String SINA_CODE = "code";
28 |
29 | String SINA_ACCESS_TOKEN = "access_token";
30 |
31 | String SINA_EXPIRES_IN = "expires_in";
32 |
33 | String SINA_UID = "uid";
34 |
35 | String SINA_USER_NAME = "userName";
36 |
37 | String SINA_NAME = "name";
38 |
39 | String SINA_REMIND_IN = "remind_in";
40 |
41 | String SINA_DATE_PATTERN = "yyyy/MM/dd HH:mm:ss";
42 |
43 | String SINA_CLIENT_ID = "client_id";
44 |
45 | String SINA_CLIENT_SECRET = "client_secret";
46 |
47 | String SINA_GRANT_TYPE = "grant_type";
48 |
49 | String SINA_GRANT_TYPE_VALUE = "authorization_code";
50 |
51 | String SINA_REDIRECT_URI = "redirect_uri";
52 |
53 | // 新浪微博首选项
54 |
55 | String PREF_SINA_ACCESS_TOKEN = "SINA_ACCESS_TOKEN";
56 |
57 | String PREF_SINA_EXPIRES_TIME = "SINA_EXPIRES_TIME";
58 |
59 | String PREF_SINA_UID = "SINA_UID";
60 |
61 | String PREF_SINA_USER_NAME = "SINA_USER_NAME";
62 |
63 | String PREF_SINA_REMIND_IN = "SINA_REMIND_IN";
64 |
65 | // 腾讯微博======================================================
66 |
67 | // 1. 修改配置文件,目标文件config.properties在Android_SDK.jar包config文件夹下(我已经改名为
68 | // TencentWeiboSDK.jar),把appkey、appsecret修改成自己应用对应的appkey和appsecret.
69 |
70 | /** 腾讯微博的Appkey请参考文档修改 **/
71 | String TX_APP_KEY = "APP_KEY";
72 |
73 | String TX_APP_KEY_SEC = "APP_KEY_SEC";
74 |
75 | // 腾讯微博首选项
76 |
77 | String PREF_TX_ACCESS_TOKEN = "TX_ACCESS_TOKEN";
78 |
79 | String PREF_TX_EXPIRES_IN = "TX_EXPIRES_IN";
80 |
81 | String PREF_TX_OPEN_ID = "TX_OPEN_ID";
82 |
83 | String PREF_TX_OPEN_KEY = "TX_OPEN_KEY";
84 |
85 | String PREF_TX_REFRESH_TOKEN = "TX_REFRESH_TOKEN";
86 |
87 | String PREF_TX_NAME = "TX_NAME";
88 |
89 | String PREF_TX_CLIENT_ID = "TX_CLIENT_ID";
90 |
91 | String PREF_TX_EXPIRES_TIME = "TX_EXPIRES_TIME";
92 |
93 | String PREF_TX_CLIENT_IP = "TX_CLIENT_IP";
94 |
95 | String PREF_TX_UID = "TX_UID";
96 |
97 | // TX API请求字段
98 |
99 | String TX_API_APP_KEY = "oauth_consumer_key";
100 |
101 | String TX_API_ACCESS_TOKEN = "access_token";
102 |
103 | String TX_API_OPEN_ID = "openid";
104 |
105 | String TX_API_CLIENT_IP = "clientip";
106 |
107 | String TX_API_OAUTH_VERSION = "oauth_version";
108 |
109 | String TX_API_SCOPE = "scope";
110 |
111 | String TX_API_CONTENT = "content";
112 |
113 | String TX_API_FORMAT = "format";
114 |
115 | String TX_API_LONGITUDE = "longitude";
116 |
117 | String TX_API_LATITUDE = "latitude";
118 |
119 | String TX_API_SYNCFLAG = "syncflag";
120 |
121 | String TX_API_COMPATIBLEFLAG = "compatibleflag";
122 | }
123 |
--------------------------------------------------------------------------------
/src/cstdr/weibosdk/demo/share/SinaWeiboAPI.java:
--------------------------------------------------------------------------------
1 | package cstdr.weibosdk.demo.share;
2 |
3 | import android.text.TextUtils;
4 |
5 | import com.weibo.sdk.android.Oauth2AccessToken;
6 | import com.weibo.sdk.android.WeiboParameters;
7 | import com.weibo.sdk.android.net.AsyncWeiboRunner;
8 | import com.weibo.sdk.android.net.RequestListener;
9 |
10 | /**
11 | * 新浪微博API,可以根据自己的需要添加API
12 | *
13 | * @author cstdingran@gmail.com
14 | *
15 | */
16 | public class SinaWeiboAPI {
17 |
18 | /**
19 | * 访问微博服务接口的地址
20 | */
21 | private static final String API_SERVER = "https://api.weibo.com/2";
22 |
23 | private static final String URL_USERS = API_SERVER + "/users";
24 |
25 | private static final String URL_STATUSES = API_SERVER + "/statuses";
26 |
27 | private static final String URL_ACCOUNT = API_SERVER + "/account";
28 |
29 | /** OAuth2的access_token接口 http://open.weibo.com/wiki/OAuth2/access_token **/
30 | private static final String URL_ACCESS_TOKEN = "https://api.weibo.com/oauth2/access_token";
31 |
32 | /** 根据用户ID获取用户信息 http://open.weibo.com/wiki/2/users/show **/
33 | private static final String URL_USERS_SHOW = URL_USERS + "/show.json";
34 |
35 | /** 发布一条新微博 http://open.weibo.com/wiki/2/statuses/update **/
36 | private static final String URL_STATUSES_UPDATE = URL_STATUSES + "/update.json";
37 |
38 | /**
39 | * 上传图片并发布一条新微博 http://open.weibo.com/wiki/2/statuses/upload
40 | * PS:这个url真的有点奇怪。。。
41 | **/
42 | private static final String URL_STATUSES_UPLOAD = "https://upload.api.weibo.com/2/statuses/upload.json";
43 |
44 | /**
45 | * 指定一个图片URL地址抓取后上传并同时发布一条新微博
46 | * http://open.weibo.com/wiki/2/statuses/upload_url_text
47 | **/
48 | private static final String URL_STATUSES_UPLOAD_URL_TEXT = URL_STATUSES + "/upload_url_text.json";
49 |
50 | /** 退出登录 http://open.weibo.com/wiki/2/account/end_session **/
51 | private static final String URL_ACCOUNT_END_SESSION = URL_ACCOUNT + "/end_session.json";
52 |
53 | /**
54 | * post请求方式
55 | */
56 | public static final String HTTPMETHOD_POST = "POST";
57 |
58 | /**
59 | * get请求方式
60 | */
61 | public static final String HTTPMETHOD_GET = "GET";
62 |
63 | private Oauth2AccessToken oAuth2accessToken;
64 |
65 | private String accessToken;
66 |
67 | /**
68 | * 构造函数,使用各个API接口提供的服务前必须先获取Oauth2AccessToken
69 | *
70 | * @param accesssToken
71 | * Oauth2AccessToken
72 | */
73 | public SinaWeiboAPI(Oauth2AccessToken oauth2AccessToken) {
74 | this.oAuth2accessToken = oauth2AccessToken;
75 | if (oAuth2accessToken != null) {
76 | accessToken = oAuth2accessToken.getToken();
77 | }
78 | }
79 |
80 | /**
81 | * 根据code获取AccessToken
82 | */
83 | public void getAccessTokenByCode(String code, RequestListener listener) {
84 | WeiboParameters params = new WeiboParameters();
85 | params.add(Constants.SINA_CLIENT_ID, Constants.SINA_APP_KEY);
86 | params.add(Constants.SINA_CLIENT_SECRET, Constants.SINA_APP_SECRET);
87 | params.add(Constants.SINA_GRANT_TYPE, Constants.SINA_GRANT_TYPE_VALUE);
88 | params.add(Constants.SINA_CODE, code);
89 | params.add(Constants.SINA_REDIRECT_URI, Constants.SINA_REDIRECT_URL);
90 | AsyncWeiboRunner.request(URL_ACCESS_TOKEN, params, HTTPMETHOD_POST, listener);
91 | }
92 |
93 | /**
94 | * 执行请求
95 | *
96 | * @param url
97 | * @param params
98 | * @param httpMethod
99 | * @param listener
100 | */
101 | private void request(final String url, final WeiboParameters params, final String httpMethod,
102 | RequestListener listener) {
103 | params.add("access_token", accessToken);
104 | AsyncWeiboRunner.request(url, params, httpMethod, listener);
105 | }
106 |
107 | /**
108 | * 根据用户ID获取用户信息
109 | *
110 | * @param uid
111 | * 需要查询的用户ID。
112 | * @param listener
113 | */
114 | public void show(long uid, RequestListener listener) {
115 | WeiboParameters params = new WeiboParameters();
116 | params.add("uid", uid);
117 | request(URL_USERS_SHOW, params, HTTPMETHOD_GET, listener);
118 | }
119 |
120 | /**
121 | * 发布一条新微博(连续两次发布的微博不可以重复)
122 | *
123 | * @param content
124 | * 要发布的微博文本内容,内容不超过140个汉字。
125 | * @param lat
126 | * 纬度,有效范围:-90.0到+90.0,+表示北纬,默认为0.0。
127 | * @param lon
128 | * 经度,有效范围:-180.0到+180.0,+表示东经,默认为0.0。
129 | * @param listener
130 | */
131 | public void update(String content, String lat, String lon, RequestListener listener) {
132 | WeiboParameters params = new WeiboParameters();
133 | params.add("status", content);
134 | if (!TextUtils.isEmpty(lon)) {
135 | params.add("long", lon);
136 | }
137 | if (!TextUtils.isEmpty(lat)) {
138 | params.add("lat", lat);
139 | }
140 | request(URL_STATUSES_UPDATE, params, HTTPMETHOD_POST, listener);
141 | }
142 |
143 | /**
144 | * 上传图片并发布一条新微博,此方法会处理urlencode
145 | *
146 | * @param content
147 | * 要发布的微博文本内容,内容不超过140个汉字
148 | * @param file
149 | * 要上传的图片,仅支持JPEG、GIF、PNG格式,图片大小小于5M。
150 | * @param lat
151 | * 纬度,有效范围:-90.0到+90.0,+表示北纬,默认为0.0。
152 | * @param lon
153 | * 经度,有效范围:-180.0到+180.0,+表示东经,默认为0.0。
154 | * @param listener
155 | */
156 | public void upload(String content, String file, String lat, String lon, RequestListener listener) {
157 | WeiboParameters params = new WeiboParameters();
158 | params.add("status", content);
159 | params.add("pic", file);
160 | if (!TextUtils.isEmpty(lon)) {
161 | params.add("long", lon);
162 | }
163 | if (!TextUtils.isEmpty(lat)) {
164 | params.add("lat", lat);
165 | }
166 | request(URL_STATUSES_UPLOAD, params, HTTPMETHOD_POST, listener);
167 | }
168 |
169 | /**
170 | * 指定一个图片URL地址抓取后上传并同时发布一条新微博
171 | *
172 | * @param content
173 | * 要发布的微博文本内容,内容不超过140个汉字
174 | * @param url
175 | * 图片的URL地址,必须以http开头。
176 | * @param lat
177 | * 纬度,有效范围:-90.0到+90.0,+表示北纬,默认为0.0。
178 | * @param lon
179 | * 经度,有效范围:-180.0到+180.0,+表示东经,默认为0.0。
180 | * @param listener
181 | */
182 | public void uploadUrlText(String content, String url, String lat, String lon, RequestListener listener) {
183 | WeiboParameters params = new WeiboParameters();
184 | params.add("status", content);
185 | params.add("url", url);
186 | if (!TextUtils.isEmpty(lon)) {
187 | params.add("long", lon);
188 | }
189 | if (!TextUtils.isEmpty(lat)) {
190 | params.add("lat", lat);
191 | }
192 | request(URL_STATUSES_UPLOAD_URL_TEXT, params, HTTPMETHOD_POST, listener);
193 | }
194 |
195 | /**
196 | * 退出登录
197 | *
198 | * @param listener
199 | */
200 | public void endSession(RequestListener listener) {
201 | WeiboParameters params = new WeiboParameters();
202 | request(URL_ACCOUNT_END_SESSION, params, HTTPMETHOD_GET, listener);
203 | }
204 | }
205 |
--------------------------------------------------------------------------------
/src/cstdr/weibosdk/demo/share/SinaWeiboUtil.java:
--------------------------------------------------------------------------------
1 | package cstdr.weibosdk.demo.share;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.IOException;
5 | import java.text.SimpleDateFormat;
6 |
7 | import org.json.JSONException;
8 | import org.json.JSONObject;
9 |
10 | import android.app.Activity;
11 | import android.content.Context;
12 | import android.content.Intent;
13 | import android.os.Bundle;
14 |
15 | import com.weibo.sdk.android.Oauth2AccessToken;
16 | import com.weibo.sdk.android.Weibo;
17 | import com.weibo.sdk.android.WeiboAuthListener;
18 | import com.weibo.sdk.android.WeiboDialogError;
19 | import com.weibo.sdk.android.WeiboException;
20 | import com.weibo.sdk.android.net.RequestListener;
21 | import com.weibo.sdk.android.sso.SsoHandler;
22 |
23 | import cstdr.weibosdk.demo.MainActivity.WeiboListener;
24 | import cstdr.weibosdk.demo.util.LOG;
25 | import cstdr.weibosdk.demo.util.PreferenceUtil;
26 | import cstdr.weibosdk.demo.util.Util;
27 |
28 | /**
29 | * 新浪微博工具类
30 | *
31 | * @author cstdingran@gmail.com
32 | *
33 | */
34 | public class SinaWeiboUtil {
35 |
36 | private static final String TAG = "SinaWeiboUtil";
37 |
38 | private static Context mContext;
39 |
40 | private static SinaWeiboUtil mInstantce;
41 |
42 | private static Weibo mWeibo;
43 |
44 | /** 保存token等参数 **/
45 | private static Oauth2AccessToken mAccessToken;
46 |
47 | /** 调用SSO授权 **/
48 | private static SsoHandler mSsoHandler;
49 |
50 | private WeiboListener listener;
51 |
52 | public SinaWeiboUtil() {
53 | mWeibo = Weibo.getInstance(Constants.SINA_APP_KEY, Constants.SINA_REDIRECT_URL, Constants.SINA_SCOPE);
54 | }
55 |
56 | public static SinaWeiboUtil getInstance(Context context) {
57 | mContext = context;
58 | if (mInstantce == null) {
59 | mInstantce = new SinaWeiboUtil();
60 | }
61 | return mInstantce;
62 | }
63 |
64 | /**
65 | * 初始化新浪微博
66 | *
67 | * @param l
68 | * 授权是否过期回调函数
69 | */
70 | public void initSinaWeibo(WeiboListener l) {
71 | String token = PreferenceUtil.getInstance(mContext).getString(Constants.PREF_SINA_ACCESS_TOKEN, "");
72 | long expiresTime = PreferenceUtil.getInstance(mContext).getLong(Constants.PREF_SINA_EXPIRES_TIME, 0);
73 | String uid = PreferenceUtil.getInstance(mContext).getString(Constants.PREF_SINA_UID, "");
74 | String userName = PreferenceUtil.getInstance(mContext).getString(Constants.PREF_SINA_USER_NAME, "");
75 | String remindIn = PreferenceUtil.getInstance(mContext).getString(Constants.PREF_SINA_REMIND_IN, "");
76 | mAccessToken = new Oauth2AccessToken();
77 | mAccessToken.setToken(token);
78 | mAccessToken.setExpiresTime(expiresTime);
79 | LOG.cstdr(TAG, "accessToken = " + mAccessToken);
80 | LOG.cstdr(TAG, "accessToken.getToken() = " + mAccessToken.getToken());
81 | LOG.cstdr(TAG, "accessToken.getExpiresTime() = " + mAccessToken.getExpiresTime());
82 | LOG.cstdr(TAG, "uid = " + uid);
83 | LOG.cstdr(TAG, "userName = " + userName);
84 | LOG.cstdr(TAG, "remindIn = " + remindIn);
85 |
86 | if (mAccessToken.isSessionValid()) { // 判断是否已授权
87 | String date = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss").format(new java.util.Date(mAccessToken
88 | .getExpiresTime()));
89 | LOG.cstdr(TAG, "access_token 仍在有效期内,无需再次登录: \naccess_token:" + mAccessToken.getToken() + "\n有效期:" + date
90 | + "\nuid:" + uid + "\nuserName:" + userName + "\nremindIn:" + remindIn);
91 | l.init(true);
92 | } else {
93 | LOG.cstdr(TAG, "使用SSO登录前,请检查手机上是否已经安装新浪微博客户端," + "目前仅3.0.0及以上微博客户端版本支持SSO;如果未安装,将自动转为Oauth2.0进行认证");
94 | l.init(false);
95 | }
96 | }
97 |
98 | /**
99 | * SSO授权
100 | *
101 | * @param l
102 | */
103 | public void auth(WeiboListener l) {
104 | // SSO授权
105 | mSsoHandler = new SsoHandler((Activity) mContext, mWeibo);
106 | mSsoHandler.authorize(new AuthDialogListener());
107 |
108 | listener = l;
109 |
110 | // test 网页授权
111 | // mWeibo.authorize(mContext, new AuthDialogListener());
112 | }
113 |
114 | /**
115 | * 授权回调函数
116 | */
117 | class AuthDialogListener implements WeiboAuthListener {
118 |
119 | @Override
120 | public void onCancel() {
121 | LOG.cstdr(TAG, "===================AuathDialogListener=Auth cancel==========");
122 | Util.showToast(mContext, "取消授权操作。");
123 | }
124 |
125 | @Override
126 | public void onComplete(Bundle values) {
127 | LOG.cstdr(TAG, "===================AuthDialogListener=onComplete==========");
128 | for (String key : values.keySet()) {
129 | LOG.cstdr(TAG, "values:key = " + key + " value = " + values.getString(key));
130 | }
131 | String code = values.getString(Constants.SINA_CODE);
132 | getAccessTokenByCode(code);
133 | }
134 |
135 | @Override
136 | public void onError(WeiboDialogError e) {
137 | LOG.cstdr(TAG, "===================AuthDialogListener=onError=WeiboDialogError = " + e.getMessage());
138 | Util.showToast(mContext, "授权失败,请检查网络连接。出错信息:" + e.getMessage());
139 | }
140 |
141 | @Override
142 | public void onWeiboException(WeiboException e) {
143 | LOG.cstdr(TAG, "===================AuthDialogListener=onWeiboException=WeiboException = " + e.getMessage());
144 | Util.showToast(mContext, "授权失败,请检查网络连接。出错信息:" + e.getMessage());
145 | }
146 | }
147 |
148 | /**
149 | * SSO授权回调函数
150 | *
151 | * @param requestCode
152 | * @param resultCode
153 | * @param data
154 | */
155 | public void authCallBack(int requestCode, int resultCode, Intent data) {
156 | if (mSsoHandler != null) {
157 | LOG.cstdr(TAG, "=====onActivityResult=mSsoHandler resultCode = " + resultCode + " requestCode = "
158 | + requestCode);
159 | mSsoHandler.authorizeCallBack(requestCode, resultCode, data);
160 | }
161 | }
162 |
163 | /**
164 | * 根据code获取AccessToken
165 | *
166 | * @param code
167 | */
168 | private void getAccessTokenByCode(String code) {
169 | SinaWeiboAPI api = new SinaWeiboAPI(mAccessToken);
170 | api.getAccessTokenByCode(code, new RequestListener() {
171 |
172 | @Override
173 | public void onIOException(IOException e) {
174 | LOG.cstdr(TAG,
175 | "===================getAccessTokenByCode=onIOException=WeiboDialogError = " + e.getMessage());
176 | Util.showToast(mContext, "根据code获取AccessToken失败,请检查网络连接。出错信息:" + e.getMessage());
177 | }
178 |
179 | @Override
180 | public void onError(WeiboException e) {
181 | LOG.cstdr(TAG, "===================getAccessTokenByCode=onError=WeiboDialogError = " + e.getMessage());
182 | Util.showToast(mContext, "根据code获取AccessToken失败,请检查网络连接。出错信息:" + e.getMessage());
183 | }
184 |
185 | @Override
186 | public void onComplete4binary(ByteArrayOutputStream arg0) {
187 | }
188 |
189 | @Override
190 | public void onComplete(String json) {
191 | LOG.cstdr(TAG, "===================getAccessTokenByCode=onComplete==========");
192 | LOG.cstdr(TAG, "json = " + json);
193 | JSONObject object;
194 | try {
195 | object = new JSONObject(json);
196 | String token = object.optString(Constants.SINA_ACCESS_TOKEN);
197 | String uid = object.optString(Constants.SINA_UID);
198 | String expiresIn = object.optString(Constants.SINA_EXPIRES_IN); // expiresIn
199 | // 是授权时长,因为要初始化,所以为String类型
200 | String remindIn = object.optString(Constants.SINA_REMIND_IN);
201 | mAccessToken = new Oauth2AccessToken(token, expiresIn);
202 | if (mAccessToken.isSessionValid()) {
203 | PreferenceUtil.getInstance(mContext).saveString(Constants.PREF_SINA_ACCESS_TOKEN, token);
204 | PreferenceUtil.getInstance(mContext).saveString(Constants.PREF_SINA_UID, uid);
205 | PreferenceUtil.getInstance(mContext).saveLong(Constants.PREF_SINA_EXPIRES_TIME,
206 | mAccessToken.getExpiresTime()); // 存入的是到期时间
207 | PreferenceUtil.getInstance(mContext).saveString(Constants.PREF_SINA_REMIND_IN, remindIn);
208 | show(Long.parseLong(uid));
209 | LOG.cstdr(TAG, "isSessionValid~~~~~~~token = " + token + " uid = " + uid + " expiresIn = "
210 | + expiresIn + " remindIn = " + remindIn);
211 |
212 | }
213 |
214 | } catch (JSONException e) {
215 | e.printStackTrace();
216 | }
217 | }
218 | });
219 | }
220 |
221 | /**
222 | * 网页授权时,需要单独获取UserName
223 | *
224 | * @param uid
225 | */
226 | public void show(long uid) {
227 | SinaWeiboAPI api = new SinaWeiboAPI(mAccessToken);
228 | api.show(uid, new RequestListener() {
229 |
230 | @Override
231 | public void onIOException(IOException e) {
232 | LOG.cstdr(TAG, "onIOException---e = " + e.getMessage());
233 | Util.showToast(mContext, "获取UserName失败,请检查网络连接。出错信息:" + e.getMessage());
234 | }
235 |
236 | @Override
237 | public void onError(WeiboException e) {
238 | LOG.cstdr(TAG, "WeiboException---e = " + e.getMessage());
239 | Util.showToast(mContext, "获取UserName失败,请检查网络连接。出错信息:" + e.getMessage());
240 | }
241 |
242 | @Override
243 | public void onComplete(String json) {
244 | JSONObject object;
245 | try {
246 | object = new JSONObject(json);
247 | String userName = object.optString(Constants.SINA_NAME);
248 | LOG.cstdr(TAG, "show---onComplete---userName = " + userName);
249 | PreferenceUtil.getInstance(mContext).saveString(Constants.PREF_SINA_USER_NAME, userName);
250 | if (listener != null) {
251 | listener.onResult();
252 | }
253 | } catch (JSONException e) {
254 | e.printStackTrace();
255 | }
256 | }
257 |
258 | @Override
259 | public void onComplete4binary(ByteArrayOutputStream arg0) {
260 | }
261 | });
262 | }
263 |
264 | /**
265 | * 发布一条新微博(连续两次发布的微博不可以重复)
266 | *
267 | * @param content
268 | * 要发布的微博文本内容,内容不超过140个汉字。
269 | * @param lat
270 | * 纬度,有效范围:-90.0到+90.0,+表示北纬,默认为0.0。
271 | * @param lon
272 | * 经度,有效范围:-180.0到+180.0,+表示东经,默认为0.0。
273 | * @param listener
274 | */
275 | public void update(String content, String lat, String lon) {
276 | SinaWeiboAPI api = new SinaWeiboAPI(mAccessToken);
277 | api.update(content, lat, lon, new RequestListener() {
278 |
279 | @Override
280 | public void onIOException(IOException e) {
281 | LOG.cstdr(TAG, "onIOException---e = " + e.getMessage());
282 | Util.showToast(mContext, "分享失败,请检查网络连接。出错信息:" + e.getMessage());
283 | }
284 |
285 | @Override
286 | public void onError(WeiboException e) {
287 | LOG.cstdr(TAG, "onError---e = " + e.getMessage() + " e.getStatusCode() = " + e.getStatusCode());
288 | if (e.getStatusCode() == 400) { // 相同内容短时间内不能分享
289 | Util.showToast(mContext, "分享失败,相同内容短时间内不能分享,请稍候再试吧。出错信息:" + e.getMessage());
290 | } else {
291 | Util.showToast(mContext, "分享失败,请检查网络连接。出错信息:" + e.getMessage());
292 | }
293 | }
294 |
295 | @Override
296 | public void onComplete(String str) {
297 | LOG.cstdr(TAG, "onComplete---str = " + str);
298 | Util.showToast(mContext, "分享成功,去你绑定的新浪微博看看吧!");
299 | }
300 |
301 | @Override
302 | public void onComplete4binary(ByteArrayOutputStream arg0) {
303 | }
304 | });
305 | }
306 |
307 | /**
308 | * 指定一个图片URL地址抓取后上传并同时发布一条新微博
309 | *
310 | * @param content
311 | * 要发布的微博文本内容,内容不超过140个汉字
312 | * @param url
313 | * 图片的URL地址,必须以http开头。
314 | * @param lat
315 | * 纬度,有效范围:-90.0到+90.0,+表示北纬,默认为0.0。
316 | * @param lon
317 | * 经度,有效范围:-180.0到+180.0,+表示东经,默认为0.0。
318 | */
319 | public void uploadUrlText(String content, String url, String lat, String lon) {
320 | SinaWeiboAPI api = new SinaWeiboAPI(mAccessToken);
321 | api.uploadUrlText(content, url, lat, lon, new RequestListener() {
322 |
323 | @Override
324 | public void onIOException(IOException e) {
325 | LOG.cstdr(TAG, "onIOException---e = " + e.getMessage());
326 | Util.showToast(mContext, "分享失败,请检查网络连接。出错信息:" + e.getMessage());
327 | }
328 |
329 | @Override
330 | public void onError(WeiboException e) {
331 | LOG.cstdr(TAG, "onError---e = " + e.getMessage() + " e.getStatusCode() = " + e.getStatusCode());
332 | if (e.getStatusCode() == 400) { // 相同内容短时间内不能分享,判断还以促出错信息为准
333 | Util.showToast(mContext, "分享失败,相同内容短时间内不能分享,请稍候再试吧。出错信息:" + e.getMessage());
334 | } else {
335 | Util.showToast(mContext, "分享失败,请检查网络连接。出错信息:" + e.getMessage());
336 | }
337 | }
338 |
339 | @Override
340 | public void onComplete(String str) {
341 | LOG.cstdr(TAG, "onComplete---str = " + str);
342 | Util.showToast(mContext, "分享成功,去你绑定的新浪微博看看吧!");
343 | }
344 |
345 | @Override
346 | public void onComplete4binary(ByteArrayOutputStream arg0) {
347 | }
348 | });
349 | }
350 |
351 | /**
352 | * 上传图片并发布一条新微博,此方法会处理urlencode
353 | *
354 | * @param content
355 | * 要发布的微博文本内容,内容不超过140个汉字
356 | * @param file
357 | * 要上传的图片,仅支持JPEG、GIF、PNG格式,图片大小小于5M。
358 | * @param lat
359 | * 纬度,有效范围:-90.0到+90.0,+表示北纬,默认为0.0。
360 | * @param lon
361 | * 经度,有效范围:-180.0到+180.0,+表示东经,默认为0.0。
362 | */
363 | public void upload(String content, String file, String lat, String lon) {
364 | SinaWeiboAPI api = new SinaWeiboAPI(mAccessToken);
365 | api.upload(content, file, lat, lon, new RequestListener() {
366 |
367 | @Override
368 | public void onIOException(IOException e) {
369 | LOG.cstdr(TAG, "onIOException---e = " + e.getMessage());
370 | Util.showToast(mContext, "分享失败,请检查网络连接。出错信息:" + e.getMessage());
371 | }
372 |
373 | @Override
374 | public void onError(WeiboException e) {
375 | LOG.cstdr(TAG, "onError---e = " + e.getMessage() + " e.getStatusCode() = " + e.getStatusCode());
376 | if (e.getStatusCode() == 400) { // 相同内容短时间内不能分享,判断还以促出错信息为准
377 | Util.showToast(mContext, "分享失败,相同内容短时间内不能分享,请稍候再试吧。出错信息:" + e.getMessage());
378 | } else {
379 | Util.showToast(mContext, "分享失败,请检查网络连接。出错信息:" + e.getMessage());
380 | }
381 | }
382 |
383 | @Override
384 | public void onComplete(String str) {
385 | LOG.cstdr(TAG, "onComplete---str = " + str);
386 | Util.showToast(mContext, "分享成功,去你绑定的新浪微博看看吧!");
387 | }
388 |
389 | @Override
390 | public void onComplete4binary(ByteArrayOutputStream arg0) {
391 | }
392 | });
393 | }
394 |
395 | /**
396 | * 注销授权
397 | *
398 | * @param l
399 | */
400 | public void logout(final WeiboListener l) {
401 | SinaWeiboAPI api = new SinaWeiboAPI(mAccessToken);
402 | api.endSession(new RequestListener() {
403 |
404 | @Override
405 | public void onIOException(IOException e) {
406 | LOG.cstdr(TAG, "onIOException---e = " + e.getMessage());
407 | Util.showToast(mContext, "注销授权失败,请检查网络连接。出错信息:" + e.getMessage());
408 | }
409 |
410 | @Override
411 | public void onError(WeiboException e) {
412 | LOG.cstdr(TAG, "onError---e = " + e.getMessage());
413 | Util.showToast(mContext, "注销授权失败,请检查网络连接。出错信息:" + e.getMessage());
414 | }
415 |
416 | @Override
417 | public void onComplete4binary(ByteArrayOutputStream arg0) {
418 | }
419 |
420 | @Override
421 | public void onComplete(String arg0) {
422 | PreferenceUtil.getInstance(mContext).remove(Constants.PREF_SINA_ACCESS_TOKEN);
423 | l.onResult();
424 | }
425 | });
426 | }
427 |
428 | /**
429 | * 检查是否已授权
430 | *
431 | * @return true 已授权,false 未授权
432 | */
433 | public boolean isAuth() {
434 | String token = PreferenceUtil.getInstance(mContext).getString(Constants.PREF_SINA_ACCESS_TOKEN, "");
435 | long expiresTime = PreferenceUtil.getInstance(mContext).getLong(Constants.PREF_SINA_EXPIRES_TIME, 0);
436 | mAccessToken = new Oauth2AccessToken();
437 | mAccessToken.setToken(token);
438 | mAccessToken.setExpiresTime(expiresTime);
439 | if (mAccessToken.isSessionValid()) { // 判断是否已授权
440 | String date = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss").format(new java.util.Date(mAccessToken
441 | .getExpiresTime()));
442 | LOG.cstdr(TAG, "access_token 仍在有效期内,无需再次登录: \naccess_token:" + mAccessToken.getToken() + "\n有效期:" + date);
443 | return true;
444 | }
445 | LOG.cstdr(TAG, "access_token 过期");
446 | return false;
447 | }
448 |
449 | }
450 |
--------------------------------------------------------------------------------
/src/cstdr/weibosdk/demo/share/TencentTO.java:
--------------------------------------------------------------------------------
1 | package cstdr.weibosdk.demo.share;
2 |
3 | /**
4 | * 腾讯微博TO类
5 | *
6 | * @author cstdingran@gmail.com
7 | *
8 | */
9 | public class TencentTO {
10 |
11 | private String appkey;
12 |
13 | private String accessToken;
14 |
15 | private String openId;
16 |
17 | private String clientIp;
18 |
19 | public String getAppkey() {
20 | return appkey;
21 | }
22 |
23 | public void setAppkey(String appkey) {
24 | this.appkey = appkey;
25 | }
26 |
27 | public String getAccessToken() {
28 | return accessToken;
29 | }
30 |
31 | public void setAccessToken(String accessToken) {
32 | this.accessToken = accessToken;
33 | }
34 |
35 | public String getOpenId() {
36 | return openId;
37 | }
38 |
39 | public void setOpenId(String openId) {
40 | this.openId = openId;
41 | }
42 |
43 | public String getClientIp() {
44 | return clientIp;
45 | }
46 |
47 | public void setClientIp(String clientIp) {
48 | this.clientIp = clientIp;
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/cstdr/weibosdk/demo/share/TencentWebAuthActivity.java:
--------------------------------------------------------------------------------
1 | package cstdr.weibosdk.demo.share;
2 |
3 | import java.io.UnsupportedEncodingException;
4 | import java.net.URLDecoder;
5 |
6 | import android.app.Activity;
7 | import android.app.AlertDialog;
8 | import android.app.Dialog;
9 | import android.app.ProgressDialog;
10 | import android.content.Context;
11 | import android.content.DialogInterface;
12 | import android.graphics.Color;
13 | import android.os.Bundle;
14 | import android.os.Handler;
15 | import android.os.Message;
16 | import android.text.TextUtils;
17 | import android.util.DisplayMetrics;
18 | import android.view.View;
19 | import android.view.Window;
20 | import android.view.WindowManager;
21 | import android.webkit.WebChromeClient;
22 | import android.webkit.WebSettings;
23 | import android.webkit.WebView;
24 | import android.webkit.WebViewClient;
25 | import android.widget.Button;
26 | import android.widget.LinearLayout;
27 | import android.widget.RelativeLayout;
28 | import android.widget.TextView;
29 | import android.widget.Toast;
30 |
31 | import com.tencent.weibo.sdk.android.api.util.BackGroudSeletor;
32 | import com.tencent.weibo.sdk.android.api.util.Util;
33 |
34 | import cstdr.weibosdk.demo.util.LOG;
35 | import cstdr.weibosdk.demo.util.PreferenceUtil;
36 |
37 | /**
38 | * 腾讯微博网页授权组件
39 | *
40 | * @author cstdingran@gmail.com
41 | *
42 | */
43 | public class TencentWebAuthActivity extends Activity {
44 |
45 | private static final String TAG = "TencentWebAuthActivity";
46 |
47 | WebView webView;
48 |
49 | String _url;
50 |
51 | String _fileName;
52 |
53 | public static int WEBVIEWSTATE_1 = 0;
54 |
55 | int webview_state = 0;
56 |
57 | String path;
58 |
59 | Dialog _dialog;
60 |
61 | public static final int ALERT_DOWNLOAD = 0;
62 |
63 | public static final int ALERT_FAV = 1;
64 |
65 | public static final int PROGRESS_H = 3;
66 |
67 | public static final int ALERT_NETWORK = 4;
68 |
69 | private ProgressDialog dialog;
70 |
71 | private LinearLayout layout = null;
72 |
73 | private String redirectUri = null;
74 |
75 | private String clientId = null;
76 |
77 | private boolean isShow = false;
78 |
79 | @Override
80 | protected void onCreate(Bundle savedInstanceState) {
81 | // TODO Auto-generated method stub
82 | super.onCreate(savedInstanceState);
83 | if (!Util.isNetworkAvailable(this)) {
84 | showDialog(ALERT_NETWORK);
85 | } else {
86 | DisplayMetrics displaysMetrics = new DisplayMetrics();
87 | getWindowManager().getDefaultDisplay().getMetrics(displaysMetrics);
88 | String pix = displaysMetrics.widthPixels + "x" + displaysMetrics.heightPixels;
89 | BackGroudSeletor.setPix(pix);
90 |
91 | try {
92 | // Bundle bundle = getIntent().getExtras();
93 | clientId = Util.getConfig().getProperty("APP_KEY");// bundle.getString("APP_KEY");
94 | redirectUri = Util.getConfig().getProperty("REDIRECT_URI");// bundle.getString("REDIRECT_URI");
95 | if (clientId == null || "".equals(clientId) || redirectUri == null || "".equals(redirectUri)) {
96 | Toast.makeText(TencentWebAuthActivity.this, "请在配置文件中填写相应的信息", Toast.LENGTH_SHORT).show();
97 | }
98 | LOG.cstdr("redirectUri", redirectUri);
99 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
100 | WindowManager.LayoutParams.FLAG_FULLSCREEN);
101 | requestWindowFeature(Window.FEATURE_NO_TITLE);
102 | int state = (int) Math.random() * 1000 + 111;
103 | path = "https://open.t.qq.com/cgi-bin/oauth2/authorize?client_id=" + clientId
104 | + "&response_type=token&redirect_uri=" + redirectUri + "&state=" + state;
105 | this.initLayout();
106 | } catch (Exception e) {
107 | e.printStackTrace();
108 | }
109 | }
110 | }
111 |
112 | /**
113 | * 初始化界面使用控件,并设置相应监听
114 | */
115 | public void initLayout() {
116 | RelativeLayout.LayoutParams fillParams = new RelativeLayout.LayoutParams(
117 | RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
118 | RelativeLayout.LayoutParams fillWrapParams = new RelativeLayout.LayoutParams(
119 | RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
120 | RelativeLayout.LayoutParams wrapParams = new RelativeLayout.LayoutParams(
121 | RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
122 |
123 | dialog = new ProgressDialog(this);
124 | dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
125 | dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
126 | dialog.setMessage("请稍后...");
127 | dialog.setIndeterminate(false);
128 | dialog.setCancelable(false);
129 | dialog.show();
130 |
131 | layout = new LinearLayout(this);
132 | layout.setLayoutParams(fillParams);
133 | layout.setOrientation(LinearLayout.VERTICAL);
134 |
135 | RelativeLayout cannelLayout = new RelativeLayout(this);
136 | cannelLayout.setLayoutParams(fillWrapParams);
137 | // cannelLayout.setBackgroundDrawable(BackGroudSeletor.getdrawble("up_bg2x",
138 | // getApplication()));
139 | cannelLayout.setGravity(LinearLayout.HORIZONTAL);
140 |
141 | Button returnBtn = new Button(this);
142 | String[] pngArray = { "quxiao_btn2x", "quxiao_btn_hover" };
143 | // returnBtn.setBackgroundDrawable(BackGroudSeletor.createBgByImageIds(pngArray,
144 | // getApplication()));
145 | returnBtn.setText("取消");
146 | wrapParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
147 | wrapParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
148 | wrapParams.leftMargin = 10;
149 | wrapParams.topMargin = 10;
150 | wrapParams.bottomMargin = 10;
151 |
152 | returnBtn.setLayoutParams(wrapParams);
153 | returnBtn.setOnClickListener(new View.OnClickListener() {
154 |
155 | @Override
156 | public void onClick(View v) {
157 | // TODO Auto-generated method stub
158 | TencentWebAuthActivity.this.finish();
159 | }
160 | });
161 | cannelLayout.addView(returnBtn);
162 |
163 | TextView title = new TextView(this);
164 | title.setText("授权");
165 | title.setTextColor(Color.WHITE);
166 | title.setTextSize(24f);
167 | RelativeLayout.LayoutParams titleParams = new RelativeLayout.LayoutParams(
168 | RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
169 | titleParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
170 | title.setLayoutParams(titleParams);
171 | cannelLayout.addView(title);
172 |
173 | layout.addView(cannelLayout);
174 |
175 | webView = new WebView(this);
176 | LinearLayout.LayoutParams wvParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
177 | LinearLayout.LayoutParams.WRAP_CONTENT);
178 | webView.setLayoutParams(wvParams);
179 | WebSettings webSettings = webView.getSettings();
180 | webView.setVerticalScrollBarEnabled(false);
181 | webSettings.setJavaScriptEnabled(true);
182 | webSettings.setUseWideViewPort(true);
183 | webSettings.setLoadWithOverviewMode(false);
184 | webView.loadUrl(path);
185 | webView.setWebChromeClient(new WebChromeClient() {
186 |
187 | @Override
188 | public void onProgressChanged(WebView view, int newProgress) {
189 | super.onProgressChanged(view, newProgress);
190 | // LOG.cstdr("newProgress", newProgress + "..");
191 | // if (dialog!=null&& !dialog.isShowing()) {
192 | // dialog.show();
193 | // }
194 |
195 | }
196 |
197 | });
198 | webView.setWebViewClient(new WebViewClient() {
199 |
200 | @Override
201 | public void onPageFinished(WebView view, String url) {
202 | LOG.cstdr("backurl", url);
203 | if (url.indexOf("access_token") != -1 && !isShow) {
204 | jumpResultParser(url);
205 | }
206 | if (dialog != null && dialog.isShowing()) {
207 | dialog.cancel();
208 | }
209 |
210 | }
211 |
212 | @Override
213 | public boolean shouldOverrideUrlLoading(WebView view, String url) {
214 | if (url.indexOf("access_token") != -1 && !isShow) {
215 | jumpResultParser(url);
216 | }
217 | return false;
218 | }
219 | });
220 | layout.addView(webView);
221 | this.setContentView(layout);
222 | }
223 |
224 | /**
225 | * 获取授权后的返回地址,并对其进行解析
226 | */
227 | public void jumpResultParser(String result) {
228 | String resultParam = result.split("#")[1];
229 | String params[] = resultParam.split("&");
230 | String accessToken = params[0].split("=")[1];
231 | String expiresIn = params[1].split("=")[1];
232 | String openId = params[2].split("=")[1];
233 | String openkey = params[3].split("=")[1];
234 | String refreshToken = params[4].split("=")[1];
235 | String state = params[5].split("=")[1];
236 | String name = params[6].split("=")[1];
237 | String nick = params[7].split("=")[1];
238 | Context context = this.getApplicationContext();
239 | if (!TextUtils.isEmpty(accessToken)) {
240 | StringBuffer sb = new StringBuffer();
241 | try {
242 | sb.append("accessToken = " + accessToken).append("\nexpiresIn = " + expiresIn)
243 | .append("\nomasKey = " + openkey).append("\nopenID = " + openId)
244 | .append("\nrefreshToken = " + refreshToken).append("\nstate = " + state)
245 | .append("\nname = " + URLDecoder.decode(name, "UTF-8"))
246 | .append("\nnick = " + URLDecoder.decode(nick, "UTF-8"));
247 | } catch (UnsupportedEncodingException e) {
248 | e.printStackTrace();
249 | }
250 | LOG.cstdr(TAG, "jumpResultParser = " + sb.toString());
251 |
252 | String clientId = Util.getConfig().getProperty(Constants.TX_APP_KEY);
253 | String clientIp = TencentWeiboUtil.getClientIp();
254 | PreferenceUtil.getInstance(context).saveString(Constants.PREF_TX_ACCESS_TOKEN, accessToken);
255 | PreferenceUtil.getInstance(context).saveString(Constants.PREF_TX_EXPIRES_IN, expiresIn);
256 | PreferenceUtil.getInstance(context).saveString(Constants.PREF_TX_OPEN_ID, openId);
257 | PreferenceUtil.getInstance(context).saveString(Constants.PREF_TX_OPEN_KEY, openkey);
258 | PreferenceUtil.getInstance(context).saveString(Constants.PREF_TX_REFRESH_TOKEN, refreshToken); // 总是为null
259 | PreferenceUtil.getInstance(context).saveString(Constants.PREF_TX_NAME, name);
260 | PreferenceUtil.getInstance(context).saveString(Constants.PREF_TX_CLIENT_ID, clientId);
261 | PreferenceUtil.getInstance(context).saveString(Constants.PREF_TX_EXPIRES_TIME,
262 | String.valueOf(System.currentTimeMillis() + Long.parseLong(expiresIn) * 1000));
263 | PreferenceUtil.getInstance(context).saveString(Constants.PREF_TX_CLIENT_IP, clientIp);
264 | isShow = true;
265 | this.setResult(1); // TODO
266 | this.finish();
267 | }
268 | }
269 |
270 | Handler handle = new Handler() {
271 |
272 | @Override
273 | public void handleMessage(Message msg) {
274 | // TODO Auto-generated method stub
275 | super.handleMessage(msg);
276 | switch (msg.what) {
277 | case 100:
278 | // LOG.cstdr("showDialog", "showDialog");
279 | showDialog(ALERT_NETWORK);
280 | break;
281 | }
282 | }
283 | };
284 |
285 | @Override
286 | protected Dialog onCreateDialog(int id) {
287 | switch (id) {
288 |
289 | case PROGRESS_H:
290 | _dialog = new ProgressDialog(this);
291 | ((ProgressDialog) _dialog).setMessage("加载中...");
292 | break;
293 | case ALERT_NETWORK:
294 | AlertDialog.Builder builder2 = new AlertDialog.Builder(this);
295 | builder2.setTitle("网络连接异常,是否重新连接?");
296 | builder2.setPositiveButton("是", new DialogInterface.OnClickListener() {
297 |
298 | @Override
299 | public void onClick(DialogInterface dialog, int which) {
300 | if (Util.isNetworkAvailable(TencentWebAuthActivity.this)) {
301 |
302 | webView.loadUrl(path);
303 | } else {
304 | Message msg = Message.obtain();
305 | msg.what = 100;
306 | handle.sendMessage(msg);
307 | }
308 | }
309 |
310 | });
311 | builder2.setNegativeButton("否", new DialogInterface.OnClickListener() {
312 |
313 | @Override
314 | public void onClick(DialogInterface dialog, int which) {
315 | TencentWebAuthActivity.this.finish();
316 | }
317 | });
318 | _dialog = builder2.create();
319 | break;
320 | }
321 | return _dialog;
322 | }
323 |
324 | }
325 |
--------------------------------------------------------------------------------
/src/cstdr/weibosdk/demo/share/TencentWeiboAPI.java:
--------------------------------------------------------------------------------
1 | package cstdr.weibosdk.demo.share;
2 |
3 | import com.weibo.sdk.android.WeiboParameters;
4 | import com.weibo.sdk.android.net.AsyncWeiboRunner;
5 | import com.weibo.sdk.android.net.RequestListener;
6 |
7 | /**
8 | * 腾讯微博API,可以根据自己的需要添加API
9 | *
10 | * @author cstdingran@gmail.com
11 | *
12 | */
13 | public class TencentWeiboAPI {
14 |
15 | /**
16 | * 访问微博服务接口的地址
17 | */
18 | public static final String API_SERVER = "https://open.t.qq.com/api";
19 |
20 | private static final String URL_ADD = API_SERVER + "/t/add";
21 |
22 | private static final String URL_USER_INFO = API_SERVER + "/user/info";
23 |
24 | /**
25 | * post请求方式
26 | */
27 | public static final String HTTPMETHOD_POST = "POST";
28 |
29 | /**
30 | * get请求方式
31 | */
32 | public static final String HTTPMETHOD_GET = "GET";
33 |
34 | private TencentTO tencentTO;
35 |
36 | /**
37 | * 构造函数
38 | */
39 | public TencentWeiboAPI(TencentTO tencentTO) {
40 | this.tencentTO = tencentTO;
41 | }
42 |
43 | /**
44 | * 执行请求
45 | *
46 | * @param url
47 | * @param params
48 | * @param httpMethod
49 | * @param listener
50 | */
51 | private void request(final String url, final WeiboParameters params, final String httpMethod,
52 | RequestListener listener) {
53 | params.add(Constants.TX_API_APP_KEY, tencentTO.getAppkey());
54 | params.add(Constants.TX_API_ACCESS_TOKEN, tencentTO.getAccessToken());
55 | params.add(Constants.TX_API_OPEN_ID, tencentTO.getOpenId());
56 | params.add(Constants.TX_API_CLIENT_IP, tencentTO.getClientIp());
57 | params.add(Constants.TX_API_OAUTH_VERSION, "2.a");
58 | params.add(Constants.TX_API_SCOPE, "all");
59 | params.add(Constants.TX_API_FORMAT, "json"); // 返回数据的格式(json或xml)
60 | AsyncWeiboRunner.request(url, params, httpMethod, listener);
61 | }
62 |
63 | /**
64 | * 发送一条微博
65 | *
66 | * @param content
67 | * 微博内容(若在此处@好友,需正确填写好友的微博账号,而非昵称),不超过140字
68 | * @param longitude
69 | * 经度,为实数,如113.421234(最多支持10位有效数字,可以填空)不是必填
70 | * @param latitude
71 | * 纬度,为实数,如22.354231(最多支持10位有效数字,可以填空) 不是必填
72 | * @param syncflag
73 | * 微博同步到空间分享标记(可选,0-同步,1-不同步,默认为0),目前仅支持oauth1.0鉴权方式 不是必填
74 | * @param compatibleflag
75 | * 容错标志,支持按位操作,默认为0。 0x20-微博内容长度超过140字则报错 0-以上错误做容错处理,即发表普通微博
76 | * 不是必填
77 | * @param listener
78 | * 回调函数
79 | */
80 | public void addWeibo(String content, long longitude, long latitude, int syncflag, int compatibleflag,
81 | RequestListener listener) {
82 | WeiboParameters params = new WeiboParameters();
83 | params.add(Constants.TX_API_CONTENT, content);
84 | params.add(Constants.TX_API_LONGITUDE, longitude);
85 | params.add(Constants.TX_API_LATITUDE, latitude);
86 | params.add(Constants.TX_API_SYNCFLAG, syncflag);
87 | params.add(Constants.TX_API_COMPATIBLEFLAG, compatibleflag);
88 | request(URL_ADD, params, HTTPMETHOD_POST, listener);
89 | }
90 |
91 | /**
92 | * OAuth授权之后,获取授权用户的信息
93 | *
94 | * @param listener
95 | */
96 | public void getUserInfo(RequestListener listener) {
97 | WeiboParameters params = new WeiboParameters();
98 | request(URL_USER_INFO, params, HTTPMETHOD_GET, listener);
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/src/cstdr/weibosdk/demo/share/TencentWeiboUtil.java:
--------------------------------------------------------------------------------
1 | package cstdr.weibosdk.demo.share;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.IOException;
5 | import java.net.InetAddress;
6 | import java.net.NetworkInterface;
7 | import java.net.SocketException;
8 | import java.util.Enumeration;
9 |
10 | import org.json.JSONException;
11 | import org.json.JSONObject;
12 |
13 | import android.app.Activity;
14 | import android.content.Context;
15 | import android.content.Intent;
16 | import android.text.TextUtils;
17 | import android.util.Log;
18 |
19 | import com.tencent.weibo.sdk.android.component.sso.AuthHelper;
20 | import com.tencent.weibo.sdk.android.component.sso.OnAuthListener;
21 | import com.tencent.weibo.sdk.android.component.sso.WeiboToken;
22 | import com.weibo.sdk.android.WeiboException;
23 | import com.weibo.sdk.android.net.RequestListener;
24 |
25 | import cstdr.weibosdk.demo.MainActivity.WeiboListener;
26 | import cstdr.weibosdk.demo.util.LOG;
27 | import cstdr.weibosdk.demo.util.PreferenceUtil;
28 | import cstdr.weibosdk.demo.util.Util;
29 |
30 | /**
31 | * 腾讯微博工具类
32 | *
33 | * @author cstdingran@gmail.com
34 | *
35 | */
36 | public class TencentWeiboUtil {
37 |
38 | private static final String TAG = "TencentWeiboUtil";
39 |
40 | private static Context mContext;
41 |
42 | private static TencentWeiboUtil tencentWeiboUtil;
43 |
44 | /** 微博相关API **/
45 | private static TencentWeiboAPI weiboAPI;
46 |
47 | /** 保存token等参数 **/
48 | private static TencentTO tencentTO;
49 |
50 | private WeiboListener listener;
51 |
52 | public TencentWeiboUtil() {
53 | tencentTO = new TencentTO();
54 | }
55 |
56 | public static TencentWeiboUtil getInstance(Context context) {
57 | mContext = context;
58 | if (tencentWeiboUtil == null) {
59 | tencentWeiboUtil = new TencentWeiboUtil();
60 | }
61 | return tencentWeiboUtil;
62 | }
63 |
64 | /**
65 | * 网页授权回调函数
66 | */
67 | public void webAuthOnResult() {
68 | LOG.cstdr(TAG, "initTencentWeibo=======listener = " + listener);
69 | if (listener != null) {
70 | listener.onResult();
71 | }
72 | }
73 |
74 | /**
75 | * 初始化腾讯微博
76 | *
77 | * @param l
78 | * 授权是否过期回调函数
79 | */
80 | public void initTencentWeibo(WeiboListener l) {
81 | String accessToken = PreferenceUtil.getInstance(mContext).getString(Constants.PREF_TX_ACCESS_TOKEN, "");
82 | if (TextUtils.isEmpty(accessToken)) { // 未授权
83 | l.init(false);
84 | } else {
85 | long expiresTime = Long.parseLong(PreferenceUtil.getInstance(mContext).getString(
86 | Constants.PREF_TX_EXPIRES_TIME, ""));
87 | LOG.cstdr(TAG, "expiresTime = " + expiresTime);
88 | LOG.cstdr(TAG, "expiresTime - System.currentTimeMillis() = " + (expiresTime - System.currentTimeMillis()));
89 | if (expiresTime - System.currentTimeMillis() > 0) { // 已授权未过期
90 | String openId = PreferenceUtil.getInstance(mContext).getString(Constants.PREF_TX_OPEN_ID, "");
91 | String clientId = PreferenceUtil.getInstance(mContext).getString(Constants.PREF_TX_CLIENT_ID, "");
92 | String clientIp = PreferenceUtil.getInstance(mContext).getString(Constants.PREF_TX_CLIENT_IP, "");
93 | tencentTO.setAccessToken(accessToken);
94 | tencentTO.setOpenId(openId);
95 | tencentTO.setAppkey(clientId);
96 | tencentTO.setClientIp(clientIp);
97 | l.init(true);
98 | } else { // 已过期
99 | l.init(false);
100 | }
101 | }
102 | }
103 |
104 | /**
105 | * SSO授权
106 | *
107 | * @param appId
108 | * @param appSecket
109 | * @param l
110 | */
111 | public void auth(final WeiboListener l) {
112 | long appId = Long.valueOf(com.tencent.weibo.sdk.android.api.util.Util.getConfig().getProperty(
113 | Constants.TX_APP_KEY));
114 | String appSecket = com.tencent.weibo.sdk.android.api.util.Util.getConfig()
115 | .getProperty(Constants.TX_APP_KEY_SEC);
116 | listener = l;
117 | LOG.cstdr(TAG, "appId = " + appId + " appSecket = " + appSecket);
118 | // test 网页授权
119 | // Intent intent=new Intent(mContext, TencentWebAuthActivity.class);
120 | // ((Activity)mContext).startActivityForResult(intent, 1);
121 |
122 | AuthHelper.register(mContext, appId, appSecket, new OnAuthListener() {
123 |
124 | @Override
125 | public void onWeiboVersionMisMatch() {
126 | Util.showToast(mContext, "腾讯微博版本不符合");
127 | Intent intent = new Intent(mContext, TencentWebAuthActivity.class);
128 | ((Activity) mContext).startActivityForResult(intent, 1);
129 | }
130 |
131 | @Override
132 | public void onWeiBoNotInstalled() {
133 | Util.showToast(mContext, "腾讯微博客户端没有安装");
134 | Intent intent = new Intent(mContext, TencentWebAuthActivity.class);
135 | ((Activity) mContext).startActivityForResult(intent, 1);
136 | }
137 |
138 | @Override
139 | public void onAuthPassed(String name, WeiboToken token) {
140 | StringBuffer sb = new StringBuffer();
141 | sb.append("token.accessToken = " + token.accessToken).append("\ntoken.expiresIn = " + token.expiresIn)
142 | .append("\ntoken.omasKey = " + token.omasKey).append("\ntoken.omasToken = " + token.omasToken)
143 | .append("\ntoken.openID = " + token.openID)
144 | .append("\ntoken.refreshToken = " + token.refreshToken);
145 | LOG.cstdr(TAG, "onAuthPassed---name = " + name + " token = " + token);
146 | LOG.cstdr(TAG, "onAuthPassed = " + sb.toString());
147 | String clientId = com.tencent.weibo.sdk.android.api.util.Util.getConfig().getProperty(
148 | Constants.TX_APP_KEY);
149 | String clientIp = getClientIp();
150 | PreferenceUtil.getInstance(mContext).saveString(Constants.PREF_TX_ACCESS_TOKEN, token.accessToken);
151 | PreferenceUtil.getInstance(mContext).saveString(Constants.PREF_TX_EXPIRES_IN,
152 | String.valueOf(token.expiresIn));
153 | PreferenceUtil.getInstance(mContext).saveString(Constants.PREF_TX_OPEN_ID, token.openID);
154 | PreferenceUtil.getInstance(mContext).saveString(Constants.PREF_TX_OPEN_KEY, token.omasKey);
155 | PreferenceUtil.getInstance(mContext).saveString(Constants.PREF_TX_REFRESH_TOKEN, token.refreshToken); // 总是为null
156 | PreferenceUtil.getInstance(mContext).saveString(Constants.PREF_TX_CLIENT_ID, clientId);
157 | PreferenceUtil.getInstance(mContext).saveString(Constants.PREF_TX_EXPIRES_TIME,
158 | String.valueOf(System.currentTimeMillis() + token.expiresIn * 1000));
159 | PreferenceUtil.getInstance(mContext).saveString(Constants.PREF_TX_CLIENT_IP, clientIp);
160 |
161 | tencentTO.setAccessToken(token.accessToken);
162 | tencentTO.setAppkey(clientId);
163 | tencentTO.setClientIp(clientIp);
164 | tencentTO.setOpenId(token.openID);
165 |
166 | LOG.cstdr(TAG, "clientIp = " + clientIp);
167 | getUserInfo(listener);
168 | }
169 |
170 | @Override
171 | public void onAuthFail(int result, String error) {
172 | LOG.cstdr(TAG, "onAuthFail---result = " + result + " error = " + error);
173 | Util.showToast(mContext, "授权失败。出错信息:" + error);
174 | }
175 | });
176 | AuthHelper.auth(mContext, "");
177 | }
178 |
179 | /**
180 | * 获得客户端IP
181 | *
182 | * @return
183 | */
184 | public static String getClientIp() {
185 | try {
186 | for (Enumeration mEnumeration = NetworkInterface.getNetworkInterfaces(); mEnumeration
187 | .hasMoreElements();) {
188 | NetworkInterface intf = mEnumeration.nextElement();
189 | for (Enumeration enumIPAddr = intf.getInetAddresses(); enumIPAddr.hasMoreElements();) {
190 | InetAddress inetAddress = enumIPAddr.nextElement();
191 | // 如果不是回环地址
192 | if (!inetAddress.isLoopbackAddress()) {
193 | // 直接返回本地IP地址
194 | return inetAddress.getHostAddress().toString();
195 | }
196 | }
197 | }
198 | } catch (SocketException ex) {
199 | Log.e("Error", ex.toString());
200 | }
201 | return null;
202 | }
203 |
204 | /**
205 | * 获得用户信息
206 | *
207 | * @param l
208 | */
209 | private void getUserInfo(final WeiboListener l) {
210 | weiboAPI = new TencentWeiboAPI(tencentTO);
211 | weiboAPI.getUserInfo(new RequestListener() {
212 |
213 | @Override
214 | public void onIOException(IOException e) {
215 | LOG.cstdr(TAG, "onIOException");
216 | Util.showToast(mContext, "获取用户信息失败。出错信息:" + e.getMessage());
217 | }
218 |
219 | @Override
220 | public void onError(WeiboException e) {
221 | LOG.cstdr(TAG, "onError = " + e.getMessage());
222 | Util.showToast(mContext, "获取用户信息失败。出错信息:" + e.getMessage());
223 | }
224 |
225 | @Override
226 | public void onComplete(String json) {
227 | LOG.cstdr(TAG, "onComplete---json = " + json);
228 | try {
229 | JSONObject object = new JSONObject(json);
230 | JSONObject data = object.getJSONObject("data");
231 | String name = data.optString("name"); // name : 用户帐户名
232 | // String nick=data.optString("nick"); // nick : 用户昵称
233 | LOG.cstdr(TAG, "name = " + name);
234 | // LOG.cstdr(TAG, "nick = " + nick);
235 | PreferenceUtil.getInstance(mContext).saveString(Constants.PREF_TX_NAME, name);
236 | if (l != null) {
237 | l.onResult();
238 | }
239 | } catch (JSONException e) {
240 | e.printStackTrace();
241 | }
242 |
243 | }
244 |
245 | @Override
246 | public void onComplete4binary(ByteArrayOutputStream arg0) {
247 | }
248 | });
249 | }
250 |
251 | /**
252 | * 发送一条微博
253 | *
254 | * @param content
255 | * 微博内容(若在此处@好友,需正确填写好友的微博账号,而非昵称),不超过140字
256 | * @param longitude
257 | * 经度,为实数,如113.421234(最多支持10位有效数字,可以填空)不是必填
258 | * @param latitude
259 | * 纬度,为实数,如22.354231(最多支持10位有效数字,可以填空) 不是必填
260 | * @param syncflag
261 | * 微博同步到空间分享标记(可选,0-同步,1-不同步,默认为0),目前仅支持oauth1.0鉴权方式 不是必填
262 | * @param compatibleflag
263 | * 容错标志,支持按位操作,默认为0。 0x20-微博内容长度超过140字则报错 0-以上错误做容错处理,即发表普通微博
264 | * 不是必填
265 | * @param listener
266 | * 回调函数
267 | */
268 | public void addWeibo(String content, long longitude, long latitude, int syncflag, int compatibleflag) {
269 | TencentWeiboAPI weiboAPI = new TencentWeiboAPI(tencentTO);
270 | weiboAPI.addWeibo(content, longitude, latitude, syncflag, compatibleflag, new RequestListener() {
271 |
272 | @Override
273 | public void onIOException(IOException e) {
274 | LOG.cstdr(TAG, "onIOException---e = " + e.getMessage());
275 | Util.showToast(mContext, "分享失败,请检查网络连接。出错信息:" + e.getMessage());
276 | }
277 |
278 | @Override
279 | public void onError(WeiboException e) {
280 | LOG.cstdr(TAG, "onError---e = " + e.getMessage());
281 | Util.showToast(mContext, "分享失败,请检查网络连接。出错信息:" + e.getMessage());
282 | }
283 |
284 | @Override
285 | public void onComplete(String str) {
286 | LOG.cstdr(TAG, "onComplete---str = " + str);
287 | Util.showToast(mContext, "分享成功,去你绑定的腾讯微博看看吧!");
288 | }
289 |
290 | @Override
291 | public void onComplete4binary(ByteArrayOutputStream arg0) {
292 | }
293 | });
294 | }
295 |
296 | /**
297 | * 注销授权
298 | *
299 | * @param l
300 | */
301 | public void logout(WeiboListener l) {
302 | PreferenceUtil.getInstance(mContext).remove(Constants.PREF_TX_ACCESS_TOKEN);
303 | l.onResult();
304 | }
305 |
306 | /**
307 | * 检查是否已授权
308 | *
309 | * @return true 已授权,false 未授权
310 | */
311 | public boolean isAuth() {
312 | String token = PreferenceUtil.getInstance(mContext).getString(Constants.PREF_TX_ACCESS_TOKEN, "");
313 | if (TextUtils.isEmpty(token)) {
314 | return false;
315 | }
316 | return true;
317 | }
318 |
319 | }
320 |
--------------------------------------------------------------------------------
/src/cstdr/weibosdk/demo/util/LOG.java:
--------------------------------------------------------------------------------
1 | package cstdr.weibosdk.demo.util;
2 |
3 | import android.util.Log;
4 |
5 | /**
6 | * 日志工具
7 | *
8 | * @author cstdingran@gmail.com
9 | *
10 | */
11 | public abstract class LOG {
12 |
13 | public static final boolean DEBUG = true;
14 |
15 | public static void cstdr(String TAG, String msg) {
16 | if (DEBUG) {
17 | Log.i("cstdr", TAG + "~~~" + msg);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/cstdr/weibosdk/demo/util/PreferenceUtil.java:
--------------------------------------------------------------------------------
1 | package cstdr.weibosdk.demo.util;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.content.SharedPreferences.Editor;
6 |
7 | /**
8 | * 首选项工具类
9 | *
10 | * @author cstdingran@gmail.com
11 | *
12 | */
13 | public class PreferenceUtil {
14 |
15 | private static final String PREFERENCE_NAME = "WEIBO_SDK_DEMO";
16 |
17 | private static PreferenceUtil preferenceUtil;
18 |
19 | private SharedPreferences sp;
20 |
21 | private Editor ed;
22 |
23 | private PreferenceUtil(Context context) {
24 | init(context);
25 | }
26 |
27 | public void init(Context context) {
28 | if (sp == null || ed == null) {
29 | try {
30 | sp = context.getSharedPreferences(PREFERENCE_NAME, 0);
31 | ed = sp.edit();
32 | } catch (Exception e) {
33 | }
34 | }
35 | }
36 |
37 | public static PreferenceUtil getInstance(Context context) {
38 | if (preferenceUtil == null) {
39 | preferenceUtil = new PreferenceUtil(context);
40 | }
41 | return preferenceUtil;
42 | }
43 |
44 | public void saveLong(String key, long l) {
45 | ed.putLong(key, l);
46 | ed.commit();
47 | }
48 |
49 | public long getLong(String key, long defaultlong) {
50 | return sp.getLong(key, defaultlong);
51 | }
52 |
53 | public void saveBoolean(String key, boolean value) {
54 | ed.putBoolean(key, value);
55 | ed.commit();
56 | }
57 |
58 | public boolean getBoolean(String key, boolean defaultboolean) {
59 | return sp.getBoolean(key, defaultboolean);
60 | }
61 |
62 | public void saveInt(String key, int value) {
63 | if (ed != null) {
64 | ed.putInt(key, value);
65 | ed.commit();
66 | }
67 | }
68 |
69 | public int getInt(String key, int defaultInt) {
70 | return sp.getInt(key, defaultInt);
71 | }
72 |
73 | public String getString(String key, String defaultInt) {
74 | return sp.getString(key, defaultInt);
75 | }
76 |
77 | public String getString(Context context, String key, String defaultValue) {
78 | if (sp == null || ed == null) {
79 | sp = context.getSharedPreferences(PREFERENCE_NAME, 0);
80 | ed = sp.edit();
81 | }
82 | if (sp != null) {
83 | return sp.getString(key, defaultValue);
84 | }
85 | return defaultValue;
86 | }
87 |
88 | public void saveString(String key, String value) {
89 | ed.putString(key, value);
90 | ed.commit();
91 | }
92 |
93 | public void remove(String key) {
94 | ed.remove(key);
95 | ed.commit();
96 | }
97 |
98 | public void destroy() {
99 | sp = null;
100 | ed = null;
101 | preferenceUtil = null;
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/cstdr/weibosdk/demo/util/Util.java:
--------------------------------------------------------------------------------
1 | package cstdr.weibosdk.demo.util;
2 |
3 | import android.content.Context;
4 | import android.net.ConnectivityManager;
5 | import android.widget.Toast;
6 | import cstdr.weibosdk.demo.MainActivity;
7 |
8 | /**
9 | * 工具类
10 | *
11 | * @author cstdingran@gmail.com
12 | *
13 | */
14 | public class Util {
15 |
16 | /**
17 | * 判断网络
18 | *
19 | * @return
20 | */
21 | public static boolean checkNet(Context context) {
22 | if (hasConnectedNetwork(context)) {
23 | return true;
24 | }
25 | showToast(context, "无网络连接...");
26 | return false;
27 | }
28 |
29 | /**
30 | * 是否网络连接
31 | *
32 | * @param context
33 | * @return
34 | */
35 | public static boolean hasConnectedNetwork(Context context) {
36 | ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
37 | if (connectivity == null) {
38 | return false;
39 | }
40 | return connectivity.getActiveNetworkInfo() != null;
41 | }
42 |
43 | /**
44 | * 显示toast
45 | *
46 | * @param context
47 | * @param s
48 | */
49 | public static void showToast(final Context context, final String s) {
50 | MainActivity.getHandler().post(new Runnable() {
51 |
52 | @Override
53 | public void run() {
54 | Toast.makeText(context, s, Toast.LENGTH_SHORT).show();
55 | }
56 | });
57 | }
58 |
59 | /**
60 | * 显示toast(长时间)
61 | *
62 | * @param context
63 | * @param s
64 | */
65 | public static void showToastLong(Context context, String s) {
66 | Toast.makeText(context, s, Toast.LENGTH_LONG).show();
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------