手机新浪微博手机客户端客户端不能登录

&主题:iphone的新浪微博客户端不能用了 求解决之道
泡网分: 44.982
精华: 4帖子: 6082
注册: 2002年08月
老婆的ip4 4.2.1的系统 未破解 。
之前的weico客户端已经无法连接登录新浪微博 提示需要升级客户端 但新的客户端又不支持4.2.1的ios
新浪官方的客户端也提示必须4.3以上的ios才能安装。
升级系统的方法无法接受 潜在风险太大。
浏览器登录又麻烦。
是否还有别的 能支持4.2.1的客户端能用? 本帖最后由 hawkdai 于
01:27 编辑
作者相关热贴:
&浏览:635&&回帖:16 &&
泡网分: 44.982
精华: 4帖子: 6082
注册: 2002年08月
goto503 发表于
在手机上登陆你不同的apple id,可以找到你已购买app。
ps,win版的itunes确实不太好用现在能恢复 但恢复后自动重启直接关机 设置为新手机还没敢试
泡网分: 44.982
精华: 4帖子: 6082
注册: 2002年08月
goto503 发表于
在手机上登陆你不同的apple id,可以找到你已购买app。
ps,win版的itunes确实不太好用现在能恢复 但恢复后自动重启直接关机
泡网分: 22.337
注册: 2004年08月
在手机上登陆你不同的apple id,可以找到你已购买app。
ps,win版的itunes确实不太好用
泡网分: 44.982
精华: 4帖子: 6082
注册: 2002年08月
一直跳还有2分钟就完事,结果20分钟都还没完。
泡网分: 44.982
精华: 4帖子: 6082
注册: 2002年08月
shh123 发表于
lz怕啥捏,丢通讯录?如果不会把通讯录和outlook同步,下载个qq同步助手吧,备份到网盘,直接恢复。晚了,以为在ITUNES里面备份过就行了,现在无法恢复,机器都开不了。
不仅仅是通讯录和短信,照片,语音录音,还有一堆app的用户名密码。头疼了。 本帖最后由 hawkdai 于
21:11 编辑
泡网分: 3.275
注册: 2011年01月
lz怕啥捏,丢通讯录?如果不会把通讯录和outlook同步,下载个qq同步助手吧,备份到网盘,直接恢复。
本帖由移动终端发布
泡网分: 44.982
精华: 4帖子: 6082
注册: 2002年08月
果然还是有可能丢数据了,并且现在根本无法启动。
1.备份资料到本地后恢复6.0.1,期间正常;
2.开机后输入APPLE ID(奇怪为什么只能输一个,这个手机用过多个ID)
3.进入起始画面,大量购买的APP已经没有了(这些APP都有登录过帐号,要找回来太麻烦了),照片没有了,音频没有了,短信还在。
4.重新恢复备份
5.开机后自动关机。
唉,手贱。
泡网分: 21.466
帖子: 2996
注册: 2005年11月
升级前用iTunes做个备份就不怕丢数据了。
泡网分: 24.81
帖子: 1830
注册: 2005年01月
hawkdai 发表于
老婆的机器绝对不乱弄 丢数据的后果很可怕。
我自己的手机一个是5.1.1完美越狱 一个是6.0半完美越狱 怎么折腾都行。手机上的重要数据也就是电话本通讯录吧,还能把机密文件放手机上?
泡网分: 29.327
注册: 2002年08月
windows新建个用户,用新用户登陆后进itunes就是一个干净环境。。
备份、升级、恢复。
泡网分: 6.301
注册: 2009年12月
在电脑上将ITunes升级到最新版本,将以前的备份删除掉,(具体在偏好设置-备份 里),完了连接手机,提示升级固件,是选择 备份后自动下载,升级完毕之后,选择恢复,相片、短信、电话簿、App的纪录与内容都与原来哟摸一样的
本帖由IOS客户端发布
泡网分: 44.982
精华: 4帖子: 6082
注册: 2002年08月
操作系统原理 发表于
我估计他是怕不好越狱老婆的机器绝对不乱弄 丢数据的后果很可怕。
我自己的手机一个是5.1.1完美越狱 一个是6.0半完美越狱 怎么折腾都行。
泡网分: 44.982
精华: 4帖子: 6082
注册: 2002年08月
hywei 发表于
升级一点都没风险,所有的东西都在这个4.2.1不支持icloud 也还有备份到本地需要解决交叉多台pc同步的问题 这手机已经很久没同步过了。
想到就头疼 苹果商店能付费升级吗。
[本版禁言]
泡网分: 1.489
注册: 2011年07月
hywei 发表于
升级一点都没风险,所有的东西都在我估计他是怕不好越狱
泡网分: 6.301
注册: 2009年12月
但以前的App要重新下载
本帖由IOS客户端发布
泡网分: 6.301
注册: 2009年12月
升级一点都没风险,所有的东西都在
本帖由IOS客户端发布
&版权所有:&&桂ICP备号&增值电信业务经营许可证iTunes 的 App Store 中的“微博”
正在打开 iTunes Store。如果 iTunes 不自动打开,在 Dock 或 Windows 桌面上点击 iTunes 图标。进度指示器
正在打开 iBooks Store。如果 iBooks 未打开,请在 Dock 中打开 iBooks App。进度指示器
如要轻松整理及新增数码媒体收藏,iTunes 是全世界最简单的工具。
我们在您的电脑上找不到 iTunes。 如要下载 SINA Corporation (Nasdaq: SINA) 的免费 App 微博,请立即获取 iTunes。
已经有 iTunes 了? 现在点击「我有 iTunes」以打开 iTunes。
开发商:SINA Corporation (Nasdaq: SINA)
App Store 精华
打开 iTunes 以购买和下载 App。
新浪微博客户端是新浪官方特别打造的,集文字、图片、视频、音频、LBS于一身的全球化社交应用。新浪微博的手机客户端实现了:轻松更新浏览你关注的好友、娱乐明星、专家发布的最新微博即时获取国内外热点新闻,网络流行话题,好玩的视频和图片随时随地分享照片、文字、地点或转发有趣的内容给好友快捷发布签到微博、查看附近的微博用户和微博内容通过私信与好友和粉丝进行语音聊天,私密分享图片和地理位置主要功能:浏览微博、分组查看用户微博、关注用户、分享文字和图片、私信聊天、分享地理位置、查看周边内容、离线通讯录、搜索微博和用户、微博收藏、转发评论微博、管理个人资料、多帐号登录、更换主题皮肤。微博首页支持查看原图、GIF动画、视频、音频,查看好友微博更新及分组微博筛选;分享新鲜事儿可以快速的分享文字、图片和地址位置信息,10种精美照片滤镜供你选择;私信聊天支持发送语音、表情、图片及位置信息,私密分享也很精彩;LBS功能快捷精准的签到,向好友分享你的位置信息,还可以查看周边的人、周边的微博,了解发生在周边的趣事;管理个人信息可以更改你的微博头像、个人简介,以及微博通讯录管理;推送功能及时将@、评论和私信等消息更新推送给你,方便与好友进行联系;微博广场在这里可以查看热门评论、热门转发、热门话题等内容,还有好玩的微游戏哦;个性化设置5种精美彩色皮肤、自定义背景图片,多种语言环境可供选择,还可轻松添加和管理多账号;此版本微博支持从Apple健康应用程序中读取用户的步数等信息。此版本微博支持后台运动轨迹记录。在后台持续运行会显著降低电池续航能力。可在应用内购买微博会员两种方式购买微博会员第一种:12元/月购买微博会员,并按月自动续订。第二种:118元/年购买微博会员,并按年自动续订。购买须知账户会在到期前1天,自动续订并扣除相应费用。如需取消自动续订,请至少提前1天在个人帐户设置中取消。购买生效后,无法退款。购买后,用户可在个人帐户设置中管理或关闭自动续订。隐私政策和使用条款/page/646?entry=client马上开始你的微博之旅吧!
版本 5.3.0 中的新功能
1.#微博雷达#总有惊喜在身边 - 探索周边的人和周边优惠信息- 探索电视节目,通过手机微博参与电视节目互动2.支持iPad
Apple Watch
你已经成为我心中无敌客服了
我今天因为爱奇艺会员冲了,却看不了VIP所有电影和其他VIP视频而习惯性去问度娘,结果发现度娘给的“官方认证电话”根本打不通!贴吧更是大规模出现“爱奇艺是骗子网站”的一类内容,可是对我我这样想找客服解决问题的人来说,哦买嘎?我该怎么办!突然想起了微博,直接搜爱奇艺官方,我发现一个问题:爱奇艺可以把自己所有客服通道关了,他却不敢不理会咱们微博,几千条评论啊,客服虽然依然不回复,但是之前有地方,可以在评论里问啊~哦~微博~我爱死你了~~你的影响力让我感觉有了你存在,就有了万能客服~~~
这个还是要赞一个的,虽然我很少用
如果有一天,我们所有的医生都改行了,散落在各个角落,有的卖麻辣烫,有的当裁缝,有的做铁匠。 然后有一天熟人病了,我偷偷告诉他,走到前面巷子左拐,有一家裁缝铺,找那个戴着眼镜撅着嘴,慢吞吞一针一线缝衣服的大妈。 想象的场景,突然觉得医生成了武侠小说里的大侠,隐藏在市井中,在最关键的时刻互传暗号,亮出身份。 &你这病灶已经转移了,浸润不浅,这刀估计隔壁铁匠开不下来,得去南门找那个卖风筝的才行。 他师傅在西门卖羊肉串,实在不行只能去趟青城山请他出山了,诚意要足,记得多带上好的孜然。。。。& 记得请十六铺背麻袋的光头做麻醉…
评论里不能看查看几个人的互相评论的内容
经常会闪退,然后在评论里几个人来回评论,看不到像网页版那样的能查看评论,还得一个一个去找,这个比较麻烦。希望意见可采纳,第一次评价这个给五分好评吧,继续努力
用户购买的还有
此 App 专为 iPhone 和 iPad 设计提供 iPhone 版 Apple Watch App免费类别: 版本: 5.3.0大小: 84.3 MBApple Watch: 是语言: 简体中文, 英语开发商: SINA Corporation (Nasdaq: SINA)无限制网页访问兼容性: 需要 iOS 6.0 或更高版本。与 iPhone、iPad、iPod touch 兼容。 此 App 已针对 iPhone 5、iPhone 6 和 iPhone 6 Plus 优化。
&&&&&4923 份评分
&&&&&190718 份评分
热门 App 内购买项目
微博会员包?12.00微博会员包?118.00粉丝头条lev1?6.00微博会员包?30.00粉丝头条lev2?12.00粉丝头条lev3?18.00粉丝头条lev4?25.00粉丝头条lev5?30.00粉丝头条lev6?50.00微博会员包?60.00
更多SINA Corporation (Nasdaq: SINA)产品  如题  楼主四张微博皮  关了电脑刷微博开始是频繁显示身份验证过期 然后是说验证失败 发不了图换不了头像  小浪是在系统维修升级还是被黑了?
楼主发言:19次 发图:
  不能沉啊此帖  是在维修整顿还是怎么着
  敏感时期,你懂得。。。
  这时间点 有没有在线的?
  @绿茶的抉择
01:18:36  敏感时期,你懂得。。。  -----------------------  难道是在查造谣的?
  我也上不去
  同上不去  
  我的提示网络错误~靠
  @绿茶的抉择
01:18:36  敏感时期,你懂得。。。  -----------------------  @希范哥性格饭 4楼
01:19  难道是在查造谣的?  ------------------------------  勃起来,你懂得。。。
  同啊,不刷一遍微博我睡不现在好痛苦
  米兔啊
  原来不止我一个人  开始我以为是网速不给力  还特意关了wifi用3G 结果还是一样
  因为刚刚.cn域名挂了…  
  刚从豌豆荚看完评论,不是一个人啊,我显示的客户端信息校验失败,开始还以为网络问题,看完以后安心了,不是我一个。。。  
  @蝶恋之缘
01:23:47  因为刚刚.cn域名挂了…  -----------------------  啥意思?.cn域名挂了?服务器bug?
  我也是。。。刷新无能。。大家都这样的  
  一样啊  
  me too  
  链接错误T^T  
  同。强迫症不刷微博睡不着的路过。。
  一直说客户端认证失败哇  
  @朕你别闹了
01:27:42  同。强迫症不刷微博睡不着的路过。。  -----------------------  一样一样 不刷到没有最后一条更新坚决不睡觉
  现在打开是客户端校验失败
  电脑行么?
  @大爱威利旺卡
01:31:13  电脑行么?  -----------------------  同问  我刚关了电脑  有没有电脑在线的
  iPad和手机都登陆无能!原来不是我人品问题啊,安心了^_^
  一样  
  不行,刚试了!
  @芝麻海苔猪肉松
01:32:51  iPad和手机都登陆无能!原来不是我人品问题啊,安心了^_^  -----------------------  我开始吓一跳 以为手机中毒被盗号了呢
  iPad登陆之前是身份过期,现在是客户端失败,手机更绝,美图广告过后直接闪退。
  刚刚接到的短信
紧急通知:根据DNSPod的监控,目前.CN的根域授权DNS全线故障,所有.CN域名均无法解析。后续跟进请留意  
  嗯,我以为号被冻结了  
  好奇怪 不刷微博又不会死 就是觉得少点什么 如同剁手
  我不想知道怎么,只想知道为什么。  另:weico可以上
  加一  
  能登上
但是不能刷新不能回复
什么都不能……  
  @鱼的Ω眼泪
01:34:42  刚刚接到的短信
紧急通知:根据DNSPod的监控,目前.CN的根域授权DNS全线故障,所有.CN域名均无法解析。后续跟进请留意  -----------------------  百度是点什么 点ci 恩 还是点卡木?
  最近微信微博都不安宁  
  一样,我还重新登陆也不行,看来在维护系统吧  
  一开微博就跟我说美图秀秀出新手机了……  
  @从前有一颗软糖
01:35:43  我不想知道怎么,只想知道为什么。  另:weico可以上  -----------------------  weico可以发文字微博  我试图片来着 传不上去
  回复第11楼,@希范哥性格饭  原来不止我一个人   开始我以为是网速不给力   还特意关了wifi用3G 结果还是一样  --------------------------  我跟你的动作是一模一样的,可惜还是上不了。。。  
  iPad和手机都上不了!!!
  果然啊!客户端矫正失败,用浏览器登上去是别人的微博,吓死我了,希望快点恢复正常。  
  我也這樣 怎麼回事啊
  回复第7楼,@我就是马甲咋滴了  我的提示网络错误~靠  --------------------------  我也是,我已经卸载重装然后还把各种网络设置重设了一遍,居然是新浪自己的问题,气死了  
  哈哈,我以为我手机中毒了!一开微博就提示客户端身份验证失败,然后停止!原来大家都一样啊  
  @没事碎碎念
01:37:15  一开微博就跟我说美图秀秀出新手机了……  -----------------------  那广告神烦有没有!又不能关闭!只能等着自动消失
  原来我不是一个人...
  我也是!  
  @暧奴伊
01:38:45  原来我不是一个人...  -----------------------  +10086
  原来大家都是....我还以为手机坏掉了  
  我也是,不刷一遍睡不了觉啊,我以为是我的问题,所以就登陆了无数次,无果,就更新版本,还是无果,就去换了密码,还是无果,就去上了网页版,但是还是登不上啊!!!  
  原来我们都做了同样的事,重新登录,wifi关了再开,怎样都不行
  同上不去
  最近注册了张小皮 没怎么发微博 关注了一些人 可能怀疑我营销帐号还是怎么的 我只要关注谁必须填验证码!神烦!
  同上不去
  防民之口甚于防川。。。。        
  果断是被华丽丽的黑啦
  。。。原来不是我手机问题!!!  
  新浪官方出通知了~微博搜索?转发了?微博客服?的微博:#公告# 尊敬的用户,目前微博出现客户端登陆提示身份过期,登陆失败的问题,工作人员紧急处理,您也可以选择用电脑网页登陆,给您带来的不便敬请谅解。 ?赞[13]?原文转发[334]?原文评论[279]  转发理由:转发微博??赞[1]?转发[28]?评论[24]?8分钟前?来自微博搜索    
  看来我不是一个人,放心了。只是没刷到微博可怎么睡的安心呢……  
  还以为被封号了特意百度了封号后什么反应好吧我多心了  
  @暧奴伊
01:40:06  原来我们都做了同样的事,重新登录,wifi关了再开,怎样都不行  -----------------------------  亲,我还重新下载了客户端。
  @大爱威利旺卡
01:31:13  电脑行么?  -----------------------------  电脑可以 我特意爬起来拿电脑上了   我特么还卸载重装了!!!气死了
  啊啊啊啊啊想刷一遍再睡觉,一直打不开。。。  
  我的也上不了啊!  
  因为神喵的主人忘密码了,浪浪表示要抗议!  ……好吧,其实我也上不去……  
  哭瞎了,我也是  
  @三十九度天玩猫
01:22:07  同啊,不刷一遍微博我睡不现在好痛苦  -----------------------------  米兔。痛苦中...
  我也上不去,手机上用百度浏览器,刷来刷去是某话剧演贾宝玉的女生发的一张照片,大晚上的,挺惊悚,还有一个叫老榕的囧。不认识。  
  我也登不上,提示客户端校验失败。。。。。
还好不是我一个人。。。  
  客户端身份校验失败
  我也是 Weico可以上
  此帖总结:   不刷微博会死星人上不去微博之后几大特征   第一步:是不是我身份过期了?重新登录  第二步:是不是我网速有问题?我关了WIFI 用3G试试  第三步:还是不行 那我关了客户端再开试试?  第四步:shi特,是不是老子该清除缓存还是手机存储不足?删个软件试试?  第五步:伐克!还是不行!老子一定是被封号了!要不就是被封号了!老子没干什么啊  第六步:看看是不是我一个人……
  同上不去~洗洗碎了~
  @拍手笑鸥一身愁
01:43:58  我也上不去,手机上用百度浏览器,刷来刷去是某话剧演贾宝玉的女生发的一张照片,大晚上的,挺惊悚,还有一个叫老榕的囧。不认识。   -----------------------------  截圖上來看看吧。反正微博都不能用了
  同好奇  
  me too
  @希范哥性格饭
01:28:00  @朕你别闹了
01:27:42   同。强迫症不刷微博睡不着的路过。。   -----------------------   一样一样 不刷到没有最后一条更新坚决不睡觉  -------------------------  +1所以逛天涯来了  
  登不上。
    d  UC浏览器虽然可以打开打开怎么就是什么老榕,我没关注他啊
  我这显示客户端校验失败
  @希范哥性格饭
01:46:00  此帖总结:   不刷微博会死星人上不去微博之后几大特征   第一步:是不是我身份过期了?重新登录   第二步:是不是我网速有问题?我关了WIFI 用3G试试   第三步:还是不行 那我关了客户端再开试试?   第四步:shi特,是不是老子该清除缓存还是手机存储不足?删个软件试试?   第五步:伐克!还是不行!老子一定是被封号了!要不就是被封号了!老子没干什么啊   第六步:看看是不是我一个人……  -------------------------  除了第5步……  
  @希范哥性格饭
01:46:00  此帖总结:   不刷微博会死星人上不去微博之后几大特征   第一步:是不是我身份过期了?重新登录   第二步:是不是我网速有问题?我关了WIFI 用3G试试   第三步:还是不行 那我关了客户端再开试试?   第四步:shi特,是不是老子该清除缓存还是手机存储不足?删个软件试试?   第五步:伐克!还是不行!老子一定是被封号了!要不就是被封号了!老子没干什么啊   第六步:看看是不是我一个人……  -------------------------  打错是第4步……  
  我也上不去啊!!!卸载又安装啊,以为是身份验证的原因。但我用手机号也登不上去啊  
  不仅微薄我连微信也连不上  
  我就查了火火。。然后就登不上了。。  
  @典子的JESUS
01:55:18  不仅微薄我连微信也连不上  -----------------------  据说是.cn全线bug 估计是域名一样 所以受影响 我也不太明白
  尼玛,关机了好几次,以为是手机问题啊! 看来不是我一个人。  
  试了一下weico可以上
  一样,客户端检验失败
  我想说我也是,可是我以为我客户端坏了于是果断卸了T^T,结果现在网速慢的要死下载好慢〒_〒  
  同!  
  看来不是我网络的问题
  根据楼上各位的意见,上不去的估计一时半会也上不了。weico还能用!好评。微博上新消息很少,大概因为bug大家上不去闹的。  洗洗睡了吧?晚安
  这时候还是不登录吧,谁知道是不是病毒,我刚才想再注意一个,不行。  
  @希范哥性格饭
01:52:34  d   UC浏览器虽然可以打开打开怎么就是什么老榕,我没关注他啊    -----------------------------  我也是
使用“←”“→”快捷翻页
请遵守言论规则,不得违反国家法律法规9365人阅读
新浪微博客户端开发之授权登录+获取微博列表
最近实在是乱得不行,至于怎么乱我也不知该怎么说,那么久没发博客就证明了这点,一般如果小巫有做详尽的计划,并把时间投入到上面的话,我是可以用最短的时间里把新浪微博客户端给整出来的,但现在进度很慢,我越来越不像个称职的程序猿,因为现在的生活已经不再是代码,更多的是想多享受跟朋友们在一起的快乐。这些话也不多说了,关于这个项目,其实我也头痛了一整子,我很久之前就买了一本李宁的Android应用开发实战,里面很大篇幅就是介绍这个客户端的开发,因为一开始我是比较迷惑的,迷惑他到底有没有使用新浪开发平台提供的SDK,然而整个授权过程到获取微博的各种数据又是怎样的?我还在考虑我要做成一个怎样的,是否只是单纯的模仿呢?反正种种疑虑,一阵子找不到北了。后来我花时间研究了他的代码,慢慢的也找了了一些门道,明白了他从是怎么把整个客户端搭建起来的,他没有使用新浪给我们提供的SDK,而似乎是把SDK的实现给翻出来了,因为SDK仅仅提供了获取微博数据的封装,开发者就只需调用API,知道怎么传参数就行了,所以很多高手是不会直接使用新浪提供的Android
SDK。要我从头到尾开发,把所有业务逻辑实现,我实在不行,所以会直接参考Android应用开发实战所提供的代码,把整个新浪微博客户端开发出来给大家看看,这也算是小巫的一个提升,与大家共同进步。
本篇博客呢,主要介绍如何进行授权认证,如何获取微博列表,因为代码比较多,我不会全部都能贴出来,整个客户端也没有开发完毕,我也是实现一个功能,然后整理博客发表出来,如果想要项目源码的,可以直接找我,我的QQ:,
如果我在的话,我会尽快答复你的。
先来看看本篇博客想要实现的效果图:
看到以上的效果,我想很多人都想知道是如何实现的,不急,我们慢慢来看,这个可不是能一口吃掉的螃蟹。
我先简单介绍一下以上效果图的业务流程,启动程序后,首先需要获取用户授权,假如已经授权过了,就不会出现提示用户输入登录的界面,授权成功后,直接获取微博数据,显示到微博列表当中。整个流程其实也蛮简单的,现在我们来看看代码。
/Wwj_sina_weibo/src/com/wwj/sina/weibo/WeiboMain.java
这个类用来切换底部标签的,比较高的版本已经不推荐用这种方法实现,不过没关系,反正高版本兼容低版本。
package com.wwj.sina.
import android.app.TabA
import android.content.I
import android.os.B
import android.widget.RadioB
import android.widget.RadioG
import android.widget.RadioGroup.OnCheckedChangeL
import android.widget.TabH
import android.widget.TabHost.TabS
* 主Activity
* @author wwj
* 通过点击RadioGroup下的RadioButton来切换不同界面
@SuppressWarnings(&deprecation&)
public class WeiboMain extends TabActivity {
public TabHost mT
public static final String TAB_HOME = &TabHome&;
public static final String TAB_MSG = &TabMsg&;
public static final String TAB_SELF = &TabSelfInfo&;
public static final String TAB_DISCOVE = &TabDiscove&;
public static final String TAB_MORE = &TabMore&;
RadioButton radio_button0;
public static RadioGroup indexG
@SuppressWarnings(&static-access&)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置无标题
requestWindowFeature(getWindow().FEATURE_NO_TITLE);
this.setContentView(R.layout.tabbar);
radio_button0 = (RadioButton) this.findViewById(R.id.tabbar_home);
radio_button0.setChecked(true); // 设置首页按钮默认是按下状态
mTabhost = (TabHost) findViewById(android.R.id.tabhost); // 获取TabHost
// 设定标签、制定一个标签作为选项卡指示符
TabSpec tabSpec1 = mTabhost.newTabSpec(TAB_HOME).setIndicator(TAB_HOME);
// 指定一个加载activity的Intent对象作为选项卡内容
tabSpec1.setContent(new Intent(WeiboMain.this, HomeActivity.class));
mTabhost.addTab(tabSpec1); // 添加第一个子页
TabSpec tabSpec2 = mTabhost.newTabSpec(TAB_MSG).setIndicator(TAB_MSG);
tabSpec2.setContent(new Intent(WeiboMain.this, MessageActivity.class));
mTabhost.addTab(tabSpec2); // 添加第二个子页
TabSpec tabSpec3 = mTabhost.newTabSpec(TAB_SELF).setIndicator(TAB_SELF);
tabSpec3.setContent(new Intent(WeiboMain.this, SelfInfoActivity.class));
mTabhost.addTab(tabSpec3); // 添加第三个子页
TabSpec tabSpec4 = mTabhost.newTabSpec(TAB_DISCOVE).setIndicator(
TAB_DISCOVE);
tabSpec4.setContent(new Intent(WeiboMain.this, DiscoveActivity.class));
mTabhost.addTab(tabSpec4); // 添加第四个子页
TabSpec tabSpec5 = mTabhost.newTabSpec(TAB_MORE).setIndicator(TAB_MORE);
tabSpec5.setContent(new Intent(WeiboMain.this, MoreActivity.class));
mTabhost.addTab(tabSpec5); // 添加第一个子页
this.indexGroup = (RadioGroup) this.findViewById(R.id.main_radio);
// 实现RadioGroup的子选项点击监听
indexGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.tabbar_home: // 首页
mTabhost.setCurrentTabByTag(TAB_HOME);
case R.id.tabbar_message:// 信息
mTabhost.setCurrentTabByTag(TAB_MSG);
case R.id.tabbar_me: // 个人资料
mTabhost.setCurrentTabByTag(TAB_SELF);
case R.id.tabbar_discove: // 发现
mTabhost.setCurrentTabByTag(TAB_DISCOVE);
case R.id.tabbar_more: // 更多
mTabhost.setCurrentTabByTag(TAB_MORE);
/Wwj_sina_weibo/src/com/wwj/sina/weibo/HomeActivity.java
这个Activity就是显示微博列表的界面,代码还不完善,这里只看关键点。
package com.wwj.sina.
import java.util.L
import android.app.A
import android.content.I
import android.os.B
import android.os.H
import android.os.M
import android.view.MenuI
import android.view.MenuItem.OnMenuItemClickL
import android.view.V
import android.view.View.OnClickL
import android.view.WindowM
import android.widget.AdapterV
import android.widget.AdapterView.OnItemClickL
import android.widget.AdapterView.OnItemLongClickL
import android.widget.B
import android.widget.LinearL
import android.widget.TextV
import com.weibo.net.W
import com.wwj.sina.weibo.adapter.WeiboListA
import com.wwj.sina.weibo.interfaces.C
import com.wwj.sina.weibo.library.StorageM
import com.wwj.sina.weibo.library.WeiboD
import com.wwj.sina.weibo.library.WeiboM
import com.wwj.sina.weibo.listener.impl.StatusRequestListenerI
import com.wwj.sina.weibo.object.S
import com.wwj.sina.weibo.object.U
import com.wwj.sina.weibo.util.T
import com.wwj.sina.weibo.view.PullToRefreshListV
import com.wwj.sina.weibo.view.PullToRefreshListView.OnRefreshL
import com.wwj.sina.weibo.workqueue.DoneAndP
import com.wwj.sina.weibo.workqueue.WorkQueueM
import com.wwj.sina.weibo.workqueue.task.ParentT
import com.wwj.sina.weibo.workqueue.task.PullFileT
* @author wwj 用于显示公共微博
public class HomeActivity extends Activity implements Const, OnClickListener,
OnItemClickListener, OnItemLongClickListener, OnMenuItemClickListener,
DoneAndProcess {
public PullToRefreshListView weiboListV // 自定义ListView
private W // 微博对象
public HomeData homeD // 主界面数据
public TextV // 用户名,显示在标题栏
public Button btn_post_ // 发布微博
public Button btn_ // 加载新微博
private LinearLayout linearLayoutH
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
// 微博列表主界面的数据
public static class HomeData {
public WeiboListAdapter weiboListA
public WorkQueueMonitor imageWorkQueueM
public WorkQueueMonitor taskWorkQueueM
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
loadView();
getWindow().setBackgroundDrawable(null);
weibo = Tools.getWeibo(this);
// 获取微博对象
homeData = (HomeData) getLastNonConfigurationInstance();
if (homeData == null) {
homeData = new HomeData();
if (!(weibo == null || !weibo.isSessionValid())) {
@SuppressWarnings(&unchecked&)
List&Status& statuses = StorageManager.loadList(this,
Const.HOME);
if (statuses == null) {
statuses = WeiboManager.getHomeTimeline(this);
homeData.weiboListAdapter = WeiboData.loadWeiboListData(this,
Const.HOME, weiboListView, statuses);
protected void onResume() {
super.onResume();
public Object onRetainNonConfigurationInstance() {
return homeD
// 加载视图
private void loadView() {
weiboListView = (PullToRefreshListView) findViewById(R.id.weibolist);
linearLayoutHome = (LinearLayout) findViewById(R.id.ll_home_layout);
username = (TextView) this.findViewById(R.id.tv_home_name);
btn_post_weibo = (Button) this.findViewById(R.id.btn_home_post_weibo);
btn_reload = (Button) this.findViewById(R.id.btn_home_reload);
weiboListView.setOnItemClickListener(this);
btn_post_weibo.setOnClickListener(this);
btn_reload.setOnClickListener(this);
public void onClick(View v) {
Intent intent =
GlobalObject globalObject = Tools.getGlobalObject(this);
switch (v.getId()) {
case R.id.btn_home_post_weibo: // 发布微博
intent = new Intent(HomeActivity.this, PostWeibo.class);
startActivity(intent);
case R.id.btn_home_reload: // 刷新列表
long sinceId = homeData.weiboListAdapter.getMaxId() + 1;
WeiboManager.getHomeTimeline(this, sinceId, 0,
DEFAULT_STATUS_COUNT, true, new StatusRequestListenerImpl(
this, linearLayoutHome, HOME));
View homeReloadAnim = findViewById(R.id.pb_home_reload);
View homeReload = findViewById(R.id.btn_home_reload);
homeReloadAnim.setVisibility(View.VISIBLE);
homeReload.setVisibility(View.GONE);
public void doneProcess(ParentTask task) {
Message msg = new Message();
if (task instanceof PullFileTask) {
msg.what = HANDLER_TYPE_LOAD_PROFILE_IMAGE;
msg.obj = ((PullFileTask) task).fileU
handler.sendMessage(msg);
public boolean onMenuItemClick(MenuItem item) {
public boolean onItemLongClick(AdapterView&?& parent, View view,
int position, long id) {
public void onItemClick(AdapterView&?& parent, View view, int position,
long id) {
Intent intent =
switch (parent.getId()) {
case R.id.weibolist:
// 按更多项
// 注意:更多点击的位置
if (position == homeData.weiboListAdapter.getCount()) {
long maxId = homeData.weiboListAdapter.getMinId() - 1;
WeiboManager.getHomeTimeline(this, 0, maxId,
DEFAULT_STATUS_COUNT, true,
new StatusRequestListenerImpl(this, linearLayoutHome,
homeData.weiboListAdapter.showMoreAnim();
} else { // 点击列表项
Status status = homeData.weiboListAdapter.getStatus(position);
if (status != null) {
intent = new Intent(this, WeiboViewer.class);
WeiboViewer.status =
startActivity(intent);
上面使用到一个Tools类,这是一个工具类,用来获取微博对象和一些转换操作,稍微看一下
/Wwj_sina_weibo/src/com/wwj/sina/weibo/util/Tools.java
package com.wwj.sina.weibo.
import java.io.InputS
import java.io.OutputS
import java.text.SimpleDateF
import java.util.D
import java.util.L
import java.util.regex.M
import java.util.regex.P
import android.app.A
import android.content.C
import android.graphics.B
import android.graphics.BitmapF
import android.graphics.C
import android.text.S
import android.text.SpannableS
import android.text.S
import android.text.style.ImageS
import android.view.V
import android.widget.ImageV
import com.weibo.net.W
import com.wwj.sina.weibo.GlobalO
import com.wwj.sina.weibo.interfaces.C
import com.wwj.sina.weibo.library.FaceM
public class Tools implements Const {
* 获取微博对象
* @param activity
public static Weibo getWeibo(Activity activity) {
GlobalObject globalObject = (GlobalObject) activity
.getApplicationContext();
return globalObject.getWeibo(activity);
* 判断当前是否有微博对象
* @param activity
public static boolean hasWeibo(Activity activity) {
GlobalObject globalObject = (GlobalObject) activity
.getApplicationContext();
return globalObject.getWeibo() == null ? false :
public static GlobalObject getGlobalObject(Activity activity) {
GlobalObject globalObject = (GlobalObject) activity
.getApplicationContext();
return globalO
// 将微博的日期字符串转换为Date对象
public static Date strToDate(String str) {
// sample:Tue May 31 17:46:55 +
// E:周 MMM:字符串形式的月,如果只有两个M,表示数值形式的月 Z表示时区(+0800)
SimpleDateFormat sdf = new SimpleDateFormat(&E MMM dd HH:mm:ss Z yyyy&,
Locale.US);
Date result =
result = sdf.parse(str);
} catch (Exception e) {
// TODO: handle exception
public static void dataTransfer(InputStream is, OutputStream os) {
byte[] buffer = new byte[8192];
int count = 0;
while((count = is.read(buffer)) & -1) {
os.write(buffer, 0, count);
} catch (Exception e) {
public static void userVerified(ImageView imageView, int verifiedType) {
if (verifiedType &= 0) {
imageView.setVisibility(View.VISIBLE);
switch (verifiedType) {
imageView.setImageLevel(verifiedType);
imageView.setImageLevel(1);
public static SpannableString changeTextToFace(Context context,
Spanned spanned) {
String text = spanned.toString();
SpannableString spannableString = new SpannableString(spanned);
Pattern pattern = pile(&\\[[^\\]]+\\]&);
Matcher matcher = pattern.matcher(text);
boolean b =
while (b = matcher.find()) {
String faceText = text.substring(matcher.start(), matcher.end());
int resourceId = FaceMan.getResourceId(faceText);
if (resourceId & 0) {
Bitmap bitmap = BitmapFactory.decodeResource(
context.getResources(), resourceId);
ImageSpan imageSpan = new ImageSpan(bitmap);
spannableString.setSpan(imageSpan, matcher.start(),
matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannableS
public static String atBlue(String s) {
StringBuilder sb = new StringBuilder();
int commonTextColor = Color.BLACK;
int signColor = Color.BLUE;
int state = 1;
String str = &&;
for (int i = 0; i & s.length(); i++) {
switch (state) {
case 1: // 普通字符状态
if (s.charAt(i) == '@') {
state = 2;
str += s.charAt(i);
else if (s.charAt(i) == '#') {
str += s.charAt(i);
state = 3;
// 添加普通字符
if (commonTextColor == Color.BLACK)
sb.append(s.charAt(i));
sb.append(&&font color='& + commonTextColor + &'&&
+ s.charAt(i) + &&/font&&);
case 2: // 处理遇到@的情况
// 处理@后面的普通字符
if (Character.isJavaIdentifierPart(s.charAt(i))) {
str += s.charAt(i);
// 如果只有一个@,作为普通字符处理
if (&@&.equals(str)) {
sb.append(str);
// 将@及后面的普通字符变成蓝色
sb.append(setTextColor(str, String.valueOf(signColor)));
// @后面有#的情况,首先应将#添加到str里,这个值可能会变成蓝色,也可以作为普通字符,要看后面还有没有#了
if (s.charAt(i) == '#') {
str = String.valueOf(s.charAt(i));
state = 3;
// @后面还有个@的情况,和#类似
else if (s.charAt(i) == '@') {
str = String.valueOf(s.charAt(i));
state = 2;
// @后面有除了@、#的其他特殊字符。需要将这个字符作为普通字符处理
if (commonTextColor == Color.BLACK)
sb.append(s.charAt(i));
sb.append(&&font color='& + commonTextColor + &'&&
+ s.charAt(i) + &&/font&&);
state = 1;
case 3: // 处理遇到#的情况
// 前面已经遇到一个#了,这里处理结束的#
if (s.charAt(i) == '#') {
str += s.charAt(i);
sb.append(setTextColor(str, String.valueOf(signColor)));
state = 1;
// 如果#后面有@,那么看一下后面是否还有#,如果没有#,前面的#作废,按遇到@处理
else if (s.charAt(i) == '@') {
if (s.substring(i).indexOf(&#&) & 0) {
sb.append(str);
str = String.valueOf(s.charAt(i));
state = 2;
str += s.charAt(i);
// 处理#...#之间的普通字符
str += s.charAt(i);
if (state == 1 || state == 3) {
sb.append(str);
} else if (state == 2) {
if (&@&.equals(str)) {
sb.append(str);
sb.append(setTextColor(str, String.valueOf(signColor)));
return sb.toString();
public static String setTextColor(String s, String color) {
String result = &&font color='& + color + &'&& + s + &&/font&&;
public static String getTimeStr(Date oldTime, Date currentDate) {
long time1 = currentDate.getTime();
long time2 = oldTime.getTime();
long time = (time1 - time2) / 1000;
if (time &= 0 && time & 60) {
return &刚才&;
} else if (time &= 60 && time & 3600) {
return time / 60 + &分钟前&;
} else if (time &= 3600 && time & 3600 * 24) {
return time / 3600 + &小时前&;
SimpleDateFormat sdf = new SimpleDateFormat(&yyyy-MM-dd HH:mm&);
return sdf.format(oldTime);
上面定义了一个getWeibo()的方法,可以看到它是通过GlobalObject来获取微博对象的,那在看看这个类
/Wwj_sina_weibo/src/com/wwj/sina/weibo/GlobalObject.java
package com.wwj.sina.
import android.app.A
import android.app.A
import com.weibo.net.W
import com.wwj.sina.weibo.interfaces.C
import com.wwj.sina.weibo.listener.AuthDialogL
import com.wwj.sina.weibo.net.PullF
import com.wwj.sina.weibo.object.C
import com.wwj.sina.weibo.workqueue.WorkQueueM
import com.wwj.sina.weibo.workqueue.WorkQueueS
public class GlobalObject extends Application implements Const{
private WorkQueueStorage workQueueS
private WorkQueueMonitor imageWorkQueueM
private WorkQueueMonitor taskWorkQueueM
public Weibo getWeibo(Activity activity) {
if (weibo == null || !weibo.isSessionValid()) {
weibo = Weibo.getInstance();
// 获取Weibo对象
weibo.setupConsumerConfig(Consumer.consumerKey, Consumer.consumerSecret);
weibo.setRedirectUrl(Consumer.redirectUrl);
weibo.authorize(activity, new AuthDialogListener(activity));
public Weibo getWeibo() {
public WorkQueueStorage getWorkQueueStorage() {
if (workQueueStorage == null){
workQueueStorage = new WorkQueueStorage();
return workQueueS
public WorkQueueMonitor getWorkQueueMonitor(Activity activity) {
if (imageWorkQueueMonitor == null) {
imageWorkQueueMonitor = new WorkQueueMonitor(activity, getWorkQueueStorage(), new PullFile(), MONITOR_TYPE_IMAGE);
imageWorkQueueMonitor.start();
return imageWorkQueueM
可以看到这个类是Application级别的,说明最先加载的是这个类,来看这个类定义的getWeibo()方法,现在很直观啦,这里就是获取授权认证的地方。设置好consumerKey和consumerSecret后,就可以调用authorize()方法进行授权了。这个方法在Weibo这个类当中,这个类很重要,能不能使用微博功能就看它了。
/Wwj_sina_weibo/src/com/weibo/net/Weibo.java
* Copyright 2011 Sina.
* Licensed under the Apache License and Weibo License, Version 2.0 (the &License&);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
http://www.
http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an &AS IS& BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
package com.weibo.
import java.io.IOE
import java.net.MalformedURLE
import android.M
import android.app.A
import android.content.C
import android.content.I
import android.content.pm.PackageM
import android.os.B
import android.text.TextU
import android.util.L
import android.webkit.CookieSyncM
* Encapsulation main Weibo APIs, Include: 1. getRquestToken , 2.
* getAccessToken, 3. url request. Used as a single instance class. Implements a
* weibo api as a synchronized way.
* @author ZhangJie (zhangjie2@.cn)
public class Weibo {
// public static String SERVER = &http://api..cn/&;
public static String SERVER = &/2/&;
public static String URL_OAUTH_TOKEN = &http://api..cn/oauth/request_token&;
public static String URL_AUTHORIZE = &http://api..cn/oauth/authorize&;
public static String URL_ACCESS_TOKEN = &http://api..cn/oauth/access_token&;
public static String URL_AUTHENTICATION = &http://api..cn/oauth/authenticate&;
public static String URL_OAUTH2_ACCESS_TOKEN = &/oauth2/access_token&;
// public static String URL_OAUTH2_ACCESS_AUTHORIZE =
// &:8093/oauth2/authorize&;
public static String URL_OAUTH2_ACCESS_AUTHORIZE = &/oauth2/authorize&;
private static String APP_KEY = &&;
private static String APP_SECRET = &&;
private static Weibo mWeiboInstance =
private Token mAccessToken =
private RequestToken mRequestToken =
private WeiboDialogListener mAuthDialogL
private static final int DEFAULT_AUTH_ACTIVITY_CODE = 32973;
public static final String TOKEN = &access_token&;
public static final String EXPIRES = &expires_in&;
public static final String DEFAULT_REDIRECT_URI = &wbconnect://success&;// 暂不支持
public static final String DEFAULT_CANCEL_URI = &wbconnect://cancel&;// 暂不支持
private String mRedirectU
private Weibo() {
Utility.setRequestHeader(&Accept-Encoding&, &gzip&);
Utility.setTokenObject(this.mRequestToken);
mRedirectUrl = DEFAULT_REDIRECT_URI;
* 获取单例
public synchronized static Weibo getInstance() {
if (mWeiboInstance == null) {
mWeiboInstance = new Weibo();
return mWeiboI
// 设置accessToken
public void setAccessToken(AccessToken token) {
mAccessToken =
public Token getAccessToken() {
return this.mAccessT
* 设置第三方key和secret
* @param consumer_key
* @param consumer_secret
public void setupConsumerConfig(String consumer_key, String consumer_secret) {
Weibo.APP_KEY = consumer_
Weibo.APP_SECRET = consumer_
public static String getAppKey() {
return Weibo.APP_KEY;
public static String getAppSecret() {
return Weibo.APP_SECRET;
public void setRequestToken(RequestToken token) {
this.mRequestToken =
public static String getSERVER() {
return SERVER;
public static void setSERVER(String sERVER) {
SERVER = sERVER;
// 设置oauth_verifier
public void addOauthverifier(String verifier) {
mRequestToken.setVerifier(verifier);
public String getRedirectUrl() {
return mRedirectU
* 设置第三方回调页
* @param mRedirectUrl
public void setRedirectUrl(String mRedirectUrl) {
this.mRedirectUrl = mRedirectU
* Requst sina weibo open api by get or post
* @param url
Openapi request URL.
* @param params
http get or post parameters . e.g.
gettimeling?max=max_id&min=min_id max and max_id is a pair of
key and value for params, also the min and min_id
* @param httpMethod
http verb: e.g. &GET&, &POST&, &DELETE&
* @throws IOException
* @throws MalformedURLException
* @throws WeiboException
public String request(Context context, String url, WeiboParameters params, String httpMethod,
Token token) throws WeiboException {
String rlt = Utility.openUrl(context, url, httpMethod, params, this.mAccessToken);
public RequestToken getRequestToken(Context context, String key, String secret,
String callback_url) throws WeiboException {
Utility.setAuthorization(new RequestTokenHeader());
WeiboParameters postParams = new WeiboParameters();
postParams.add(&oauth_callback&, callback_url);
rlt = Utility.openUrl(context, Weibo.URL_OAUTH_TOKEN, &POST&, postParams, null);
RequestToken request = new RequestToken(rlt);
this.mRequestToken =
public AccessToken generateAccessToken(Context context, RequestToken requestToken)
throws WeiboException {
Utility.setAuthorization(new AccessTokenHeader());
WeiboParameters authParam = new WeiboParameters();
authParam.add(&oauth_verifier&, this.mRequestToken.getVerifier()/* &605835& */);
authParam.add(&source&, APP_KEY);
String rlt = Utility.openUrl(context, Weibo.URL_ACCESS_TOKEN, &POST&, authParam,
this.mRequestToken);
AccessToken accessToken = new AccessToken(rlt);
this.mAccessToken = accessT
return accessT
public AccessToken getXauthAccessToken(Context context, String app_key, String app_secret,
String usrname, String password) throws WeiboException {
Utility.setAuthorization(new XAuthHeader());
WeiboParameters postParams = new WeiboParameters();
postParams.add(&x_auth_username&, usrname);
postParams.add(&x_auth_password&, password);
postParams.add(&oauth_consumer_key&, APP_KEY);
String rlt = Utility.openUrl(context, Weibo.URL_ACCESS_TOKEN, &POST&, postParams, null);
AccessToken accessToken = new AccessToken(rlt);
this.mAccessToken = accessT
return accessT
* 获取Oauth2.0的accesstoken
* /oauth2/access_token?client_id=YOUR_CLIENT_ID&
* client_secret=YOUR_CLIENT_SECRET&grant_type=password&redirect_uri=
* YOUR_REGISTERED_REDIRECT_URI&username=USER_NAME&pasword=PASSWORD
* @param context
* @param app_key
* @param app_secret
* @param usrname
* @param password
* @throws WeiboException
public Oauth2AccessToken getOauth2AccessToken(Context context, String app_key,
String app_secret, String usrname, String password) throws WeiboException {
Utility.setAuthorization(new Oauth2AccessTokenHeader());
WeiboParameters postParams = new WeiboParameters();
postParams.add(&username&, usrname);
postParams.add(&password&, password);
postParams.add(&client_id&, app_key);
postParams.add(&client_secret&, app_secret);
postParams.add(&grant_type&, &password&);
String rlt = Utility.openUrl(context, Weibo.URL_OAUTH2_ACCESS_TOKEN, &POST&, postParams,
Oauth2AccessToken accessToken = new Oauth2AccessToken(rlt);
this.mAccessToken = accessT
return accessT
* Share text content or image to weibo .
public boolean share2weibo(Activity activity, String accessToken, String tokenSecret,
String content, String picPath) throws WeiboException {
if (TextUtils.isEmpty(accessToken)) {
throw new WeiboException(&token can not be null!&);
// else if (TextUtils.isEmpty(tokenSecret)) {
// throw new WeiboException(&secret can not be null!&);
if (TextUtils.isEmpty(content) && TextUtils.isEmpty(picPath)) {
throw new WeiboException(&weibo content can not be null!&);
Intent i = new Intent(activity, ShareActivity.class);
i.putExtra(ShareActivity.EXTRA_ACCESS_TOKEN, accessToken);
i.putExtra(ShareActivity.EXTRA_TOKEN_SECRET, tokenSecret);
i.putExtra(ShareActivity.EXTRA_WEIBO_CONTENT, content);
i.putExtra(ShareActivity.EXTRA_PIC_URI, picPath);
activity.startActivity(i);
private boolean startSingleSignOn(Activity activity, String applicationId,
String[] permissions, int activityCode) {
public static boolean flag =
private void startDialogAuth(Activity activity, String[] permissions) {
if(flag == true)
WeiboParameters params = new WeiboParameters();
if (permissions.length & 0) {
params.add(&scope&, TextUtils.join(&,&, permissions));
CookieSyncManager.createInstance(activity);
dialog(activity, params, new WeiboDialogListener() {
public void onComplete(Bundle values) {
// ensure any cookies set by the dialog are saved
CookieSyncManager.getInstance().sync();
if (null == mAccessToken) {
mAccessToken = new Token();
mAccessToken.setToken(values.getString(TOKEN));
mAccessToken.setExpiresIn(values.getString(EXPIRES));
if (isSessionValid()) {
Log.d(&Weibo-authorize&,
&Login Success! access_token=& + mAccessToken.getToken() + & expires=&
+ mAccessToken.getExpiresIn());
mAuthDialogListener.onComplete(values);
Log.d(&Weibo-authorize&, &Failed to receive access token&);
mAuthDialogListener.onWeiboException(new WeiboException(
&Failed to receive access token.&));
public void onError(DialogError error) {
Log.d(&Weibo-authorize&, &Login failed: & + error);
mAuthDialogListener.onError(error);
public void onWeiboException(WeiboException error) {
Log.d(&Weibo-authorize&, &Login failed: & + error);
mAuthDialogListener.onWeiboException(error);
public void onCancel() {
Log.d(&Weibo-authorize&, &Login canceled&);
mAuthDialogListener.onCancel();
* User-Agent Flow
* @param activity
* @param listener
授权结果监听器
public void authorize(Activity activity, final WeiboDialogListener listener) {
authorize(activity, new String[] {}, DEFAULT_AUTH_ACTIVITY_CODE, listener);
@SuppressWarnings(&unused&)
private void authorize(Activity activity, String[] permissions,
final WeiboDialogListener listener) {
authorize(activity, permissions, DEFAULT_AUTH_ACTIVITY_CODE, listener);
private void authorize(Activity activity, String[] permissions, int activityCode,
final WeiboDialogListener listener) {
Utility.setAuthorization(new Oauth2AccessTokenHeader());
boolean singleSignOnStarted =
mAuthDialogListener =
// Prefer single sign-on, where available.
if (activityCode &= 0) {
singleSignOnStarted = startSingleSignOn(activity, APP_KEY, permissions, activityCode);
// Otherwise fall back to traditional dialog.
if (!singleSignOnStarted) {
startDialogAuth(activity, permissions);
@SuppressWarnings(&unused&)
private void authorizeCallBack(int requestCode, int resultCode, Intent data) {
public void dialog(Context context, WeiboParameters parameters,
final WeiboDialogListener listener) {
parameters.add(&client_id&, APP_KEY);
parameters.add(&response_type&, &token&);
parameters.add(&redirect_uri&, mRedirectUrl);
parameters.add(&display&, &mobile&);
if (isSessionValid()) {
parameters.add(TOKEN, mAccessToken.getToken());
String url = URL_OAUTH2_ACCESS_AUTHORIZE + &?& + Utility.encodeUrl(parameters);
if (context.checkCallingOrSelfPermission(Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
Utility.showAlert(context, &Error&,
&Application requires permission to access the Internet&);
new WeiboDialog(this, context, url, listener).show();
public boolean isSessionValid() {
if (mAccessToken != null) {
return (!TextUtils.isEmpty(mAccessToken.getToken()) && (mAccessToken.getExpiresIn() == 0 || (System
.currentTimeMillis() & mAccessToken.getExpiresIn())));
你们自己找到authorize()看看呗,怎么弹出那个登录界面的自己研究去,这个方法需要传入一个listener,
就是这个类了AuthDialogListener
/Wwj_sina_weibo/src/com/wwj/sina/weibo/listener/AuthDialogListener.java
授权完成后,回调这个类的onComplete方法,然后就可以获取微博数据了。
package com.wwj.sina.weibo.
import android.app.A
import android.os.B
import android.widget.T
import com.weibo.net.DialogE
import com.weibo.net.WeiboDialogL
import com.weibo.net.WeiboE
import com.wwj.sina.weibo.HomeA
import com.wwj.sina.weibo.adapter.WeiboListA
import com.wwj.sina.weibo.interfaces.C
import com.wwj.sina.weibo.library.StorageM
import com.wwj.sina.weibo.library.WeiboD
import com.wwj.sina.weibo.library.WeiboM
import com.wwj.sina.weibo.object.U
import com.wwj.sina.weibo.util.SettingU
public class AuthDialogListener implements WeiboDialogListener {
public AuthDialogListener(Activity activity) {
this.activity =
public void onComplete(Bundle values) {
// 保存access_token 和 expires_in
String token = values.getString(&access_token&);
String expires_in = values.getString(&expires_in&);
SettingUtil.set(activity, SettingUtil.ACCESS_TOKEN, token);
SettingUtil.set(activity, SettingUtil.EXPIRES_IN, expires_in);
Toast.makeText(activity, &认证成功&, Toast.LENGTH_SHORT).show();
HomeActivity homeActivity = (HomeActivity)
WeiboListAdapter weiboListAdapter =
long uid = Long.parseLong(values.getString(&uid&));
User user = WeiboManager.getUser(activity, uid);
if (user != null) {
homeActivity.username.setText(user.name);
StorageManager.setValue(activity, &uid&, uid); // 保存用户UID
weiboListAdapter = WeiboData.loadWeiboListData(activity, Const.HOME,
homeActivity.weiboListView);
homeActivity.homeData.weiboListAdapter = weiboListA
public void onWeiboException(WeiboException e) {
// 当认证过程中捕获到WeiboException时调用
Toast.makeText(activity, &Auth exception:& + e.getMessage(),
Toast.LENGTH_LONG).show();
public void onError(DialogError e) {
// Oauth2.0认证过程中,当认证对话框中的webView接收数据出现错误时调用此方法
Toast.makeText(activity, &Auth error:& + e.getMessage(),
Toast.LENGTH_LONG).show();
public void onCancel() {
// Oauth2.0认证过程中,如果认证窗口被关闭或认证取消时调用
Toast.makeText(activity, &Auth cancel&, Toast.LENGTH_LONG).show();
执行完这个就已经把数据显示出来了
&WeiboData.loadWeiboListData(activity, Const.HOME,homeActivity.weiboListView);
这里又有一个WeiboData这个类,看看就明白了
package com.wwj.sina.weibo.
import java.util.L
import android.app.A
import android.widget.ListV
import com.wwj.sina.weibo.adapter.WeiboListA
import com.wwj.sina.weibo.interfaces.C
import com.wwj.sina.weibo.object.S
import com.wwj.sina.weibo.util.T
public class WeiboData implements Const {
public static WeiboListAdapter loadWeiboListData(Activity activity,
int type, ListView listView) {
return loadWeiboListData(activity, type, listView, null);
public static WeiboListAdapter loadWeiboListData(Activity activity,
int type, ListView listView, List&Status& statuses) {
WeiboListAdapter adapter =
if (Tools.hasWeibo(activity)) {
switch (type) {
case HOME:
if (statuses == null)
statuses = WeiboManager.getHomeTimeline(activity);
adapter = new WeiboListAdapter(activity, statuses, type);
listView.setAdapter(adapter);
可以看到,这里ListView就直接setAdapter了。来看到第二个loadWeiboListData方法,有一个List&Status& statuses参数,这个就是保存微博数据的参数了,是怎么得到的?我们又可以看到一个类WeiboManager里有一个getHomeTimeline的方法,这个就是返回微博数据的方法。
等不及了,进去看看。
/Wwj_sina_weibo/src/com/wwj/sina/weibo/library/WeiboManager.java
package com.wwj.sina.weibo.
import java.io.F
import java.util.L
import android.app.A
import com.weibo.net.AsyncWeiboR
import com.weibo.net.AsyncWeiboRunner.RequestL
import com.weibo.net.W
import com.weibo.net.WeiboP
import com.wwj.sina.weibo.interfaces.C
import com.wwj.sina.weibo.object.C
import com.wwj.sina.weibo.object.S
import com.wwj.sina.weibo.object.U
import com.wwj.sina.weibo.util.T
import com.wwj.sina.weibo.workqueue.DoneAndP
import com.wwj.sina.weibo.workqueue.WorkQueueS
import com.wwj.sina.weibo.workqueue.task.PullFileT
* 微博管理类,提供方法获取微博数据
* @author Administrator
public class WeiboManager implements Const {
public static List&Status& getHomeTimeline(Activity activity) {
return getHomeTimeline(activity, 0, 0, DEFAULT_STATUS_COUNT);
private static List&Status& getHomeTimeline(Activity activity,
long sinceId, long maxId, int count) {
return getHomeTimeline(activity, sinceId, maxId, count, false, null);
* 获取当前登录用户及其所关注用户的最新微博
* @param activity
* @param sinceId
* @param maxId
* @param count
* @param async
* @param listener
@SuppressWarnings(&unchecked&)
public static List&Status& getHomeTimeline(Activity activity,
long sinceId, long maxId, int count, boolean async,
RequestListener listener) {
// 访问接口url
String url = Weibo.SERVER + &statuses/home_timeline.json&;
// 获取微博对象
Weibo weibo = Tools.getWeibo(activity);
if (weibo == null || !weibo.isSessionValid()) {
WeiboParameters bundle = new WeiboParameters();
bundle.add(&source&, Consumer.consumerKey);
if (sinceId != 0)
bundle.add(&since_id&, String.valueOf(sinceId));
if (maxId != 0)
bundle.add(&max_id&, String.valueOf(maxId));
if (count != 0)
bundle.add(&count&, String.valueOf(count));
List&Status& statuses =
if (!async) {
// 请求获取JSON数据
String json = weibo.request(activity, url, bundle, &GET&,
weibo.getAccessToken());
statuses = JSONAndObject
.convert(Status.class, json, &statuses&);
AsyncWeiboRunner asyncWeiboRunner = new AsyncWeiboRunner(weibo);
asyncWeiboRunner
.request(activity, url, bundle, &GET&, listener);
} catch (Exception e) {
public static String getImageurl(Activity activity, String url) {
return getImageurl(activity, url, null);
public static String getImageurl(Activity activity, String url,
DoneAndProcess doneAndProcess) {
String result =
if (url == null || &&.equals(url))
result = PATH_FILE_CACHE + &/& + url.hashCode();
File file = new File(PATH_FILE_CACHE + &/& + url.hashCode());
if (file.exists()) {
WorkQueueStorage workQueueStorage = Tools.getGlobalObject(activity)
.getWorkQueueStorage();
if (workQueueStorage != null) {
if (doneAndProcess == null) {
workQueueStorage.addDoneWebFileUrl(url);
PullFileTask pullFileTask = new PullFileTask();
pullFileTask.doneAndProcess = doneAndP
pullFileTask.fileUrl =
workQueueStorage.addTask(pullFileTask);
public static boolean hasPicture(Status status) {
if (status.thumbnail_pic != null && !&&.equals(status.thumbnail_pic))
if (status.retweeted_status != null) {
if (status.retweeted_status.thumbnail_pic != null
&& !&&.equals(status.retweeted_status.thumbnail_pic)) {
public static User getUser(Activity activity, long uid) {
return getUser(activity, uid, null, false, null);
public static User getUser(Activity activity, String screen_name) {
return getUser(activity, 0, screen_name, false, null);
public static User getUser(Activity activity, long uid, String screen_name,
boolean async, RequestListener listener) {
String url = Weibo.SERVER + &users/show.json&;
Weibo weibo = Tools.getWeibo(activity);
if (weibo == null || !weibo.isSessionValid()) {
User user =
WeiboParameters bundle = new WeiboParameters();
bundle.add(&source&, Consumer.consumerKey);
if (uid & 0) {
bundle.add(&uid&, String.valueOf(uid));
} else if (screen_name != null) {
bundle.add(&screen_name&, screen_name);
if (!async) {
String json = weibo.request(activity, url, bundle, &GET&,
weibo.getAccessToken());
user = new User();
JSONAndObject.convertSingleObject((Object) user, json);
AsyncWeiboRunner asyncWeiboRunner = new AsyncWeiboRunner(weibo);
asyncWeiboRunner
.request(activity, url, bundle, &GET&, listener);
} catch (Exception e) {
只看getHomeTimeline()这个方法,一直追踪,很快就可以知道这个微博数据是怎么得到的了。
public static List&Status& getHomeTimeline(Activity activity,
long sinceId, long maxId, int count, boolean async,
RequestListener listener) {
// 访问接口url
String url = Weibo.SERVER + &statuses/home_timeline.json&;
// 获取微博对象
Weibo weibo = Tools.getWeibo(activity);
if (weibo == null || !weibo.isSessionValid()) {
WeiboParameters bundle = new WeiboParameters();
bundle.add(&source&, Consumer.consumerKey);
if (sinceId != 0)
bundle.add(&since_id&, String.valueOf(sinceId));
if (maxId != 0)
bundle.add(&max_id&, String.valueOf(maxId));
if (count != 0)
bundle.add(&count&, String.valueOf(count));
List&Status& statuses =
if (!async) {
// 请求获取JSON数据
String json = weibo.request(activity, url, bundle, &GET&,
weibo.getAccessToken());
statuses = JSONAndObject
.convert(Status.class, json, &statuses&);
AsyncWeiboRunner asyncWeiboRunner = new AsyncWeiboRunner(weibo);
asyncWeiboRunner
.request(activity, url, bundle, &GET&, listener);
} catch (Exception e) {
就是这个方法了,通过调用weibo对象的request()方法,返回Json字符串,通过解析得到的JSON字符串得到statuses数组。这里需要进行的转换,全靠JSONAndObject这个类
package com.wwj.sina.weibo.
import java.lang.reflect.F
import java.util.ArrayL
import java.util.L
import org.json.JSONA
import org.json.JSONO
import android.util.L
import com.wwj.sina.weibo.interfaces.WeiboO
public class JSONAndObject {
* 将一个对象转换为JSON格式的字符串,只转换public类型的变量
* @param obj
public static String convertSingleObjectToJson(Object obj) {
String json =
if (obj == null) {
Field[] fields = obj.getClass().getFields();
json = &{&;
// 开始转换每一个public类型的变量
for (int i = 0; i & fields. i++) {
Field field = fields[i];
if (field.getType() == String.class) {
// 属性值为null, 用空字符串取代
String temp = ((field.get(obj) == null) ? && : String
.valueOf(field.get(obj)));
// 处理字符串中的双引号
// JSON字符串中不能直接使用双引号
temp = temp.replaceAll(&\&&, &\\\\\&&);
json += &\&& + field.getName() + &\&:\&& + temp + &\&&;
// long类型
else if (field.getType() == long.class) {
json += &\&& + field.getName() + &\&:& + field.getLong(obj);
// int类型
else if (field.getType() == int.class) {
json += &\&& + field.getName() + &\&:& + field.getInt(obj);
// boolean类型
else if (field.getType() == boolean.class) {
json += &\&& + field.getName() + &\&:&
+ field.getBoolean(obj);
// Object类型(WeiboObject类型)
Object fieldObject = field.get(obj);
if (fieldObject instanceof WeiboObject) {
// 如果对象中含有对象类型的变量
// 递归生成JSON字符串
json += &\&& + field.getName() + &\&:&
+ convertSingleObjectToJson(fieldObject);
if (i & fields.length - 1) {
json += &,&;
} catch (Exception e) {
json += &}&;
* 将obj转换为JSON字符串,该字符串必须是一个对象 其中obj必须是一个List,而且JSON字符串必须包含一个propertyName
* 制定的属性,属性值是JSON数组,该数组与obj指定的List对应 类似于hometimeline.json返回的JSON字符串的逆过程
* @param obj
* @param propertyName
public static String covertObjectToJson(Object obj, String propertyName) {
String json =
if (obj == null) {
if (obj instanceof List) {
List list = (List)
if (propertyName != null) {
// 包含一个属性的对象,这个属性是对象数组
json = &{\&& + propertyName + &\&:[&;
// 对象数组
json = &[&;
for (int i = 0; i & list.size(); i++) {
Object item = list.get(i);
json += convertSingleObjectToJson(item);
if (i & list.size() - 1)
json += &,&;
if (propertyName != null) {
json += &]}&;
json = &]&;
* 将json字符串转换为List
* @param c
* @param json
* @param propertyName
这个参数用来制定属性的对象,而且这个属性值必须是一个数组
public static List convert(Class c, String json, String propertyName) {
List objs =
if (c == null || json == null)
// 只使用public类型字段
Field[] fields = c.getFields();
if (fields != null) {
String jsonStr =
if (propertyName != null) {
JSONObject jsonObject = new JSONObject(json);
jsonStr = jsonObject.get(propertyName).toString();
JSONArray jsonArray = new JSONArray(jsonStr);
objs = new ArrayList();
for (int i = 0; i & jsonArray.length(); i++) {
Object obj = c.newInstance();
objs.add(obj);
convertSingleObject(obj, jsonArray.getString(i));
} catch (Exception e) {
Log.d(&convert&, e.getMessage());
* 使用该方法需要先创建一个object,传入第一个参数 将JSON格式的数据转换为一个对象 json参数的值必须是一个JSON格式的对象,不能是数组
* @param obj
* @param json
public static Object convertSingleObject(Object obj, String json) {
if (obj == null || json == null)
// 只使用public类型字段
Field[] fields = obj.getClass().getFields();
if (fields != null) {
JSONObject jsonObject = new JSONObject(json);
for (Field field : fields) {
Object objValue = jsonObject.get(field.getName());
// 字符串类型
if (field.getType() == String.class) {
field.set(obj, String.valueOf(objValue));
// long类型
else if (field.getType() == long.class) {
field.set(obj,
Long.valueOf(String.valueOf(objValue)));
} // int类型
else if (field.getType() == int.class) {
field.set(obj,
Integer.valueOf(String.valueOf(objValue)));
// boolean类型
else if (field.getType() == boolean.class) {
field.set(obj, Boolean.getBoolean(String
.valueOf(objValue)));
// Object类型(WeiboObject类型)
Object fieldObject = field.getType().newInstance();
if (fieldObject instanceof WeiboObject) {
convertSingleObject(fieldObject,
String.valueOf(objValue));
field.set(obj, fieldObject);
} catch (Exception e) {
} catch (Exception e) {
到这里基本上把核心的代码贴完了,不过这里还有有一个类确实比较重要的,Utility这个类涉及到的都是Http通信,我们直接拿来用就可以的,不需要我们自己去写。要我说能完全自主开发出新浪微博客户端那确实很牛叉了,光是Http通信这一块,如果对http不熟悉,根本就不知道怎么来搞。
以上的代码并不是全部,但这些代码已经很有用了,对自己理解微博客户端的实现有了很大的启发。可能有些地方没能面面俱到,请见谅。下一篇博客可能会是关于发布一条微博的实现,敬请期待吧。
版权声明:本文为博主原创文章,未经博主允许不得转载。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1721247次
积分:23419
积分:23419
排名:第127名
原创:576篇
转载:81篇
评论:1736条
难度:初级
类型:实战教学
阅读:47253
阅读:26323
文章:14篇
阅读:77520
文章:11篇
阅读:74057
文章:10篇
阅读:44841
文章:13篇
阅读:20717
文章:13篇
阅读:181269
移动开发者狂热群:注明入群理由,里面有一群热爱分享的开发者
(3)(2)(3)(4)(12)(1)(5)(5)(6)(7)(2)(13)(11)(11)(8)(14)(10)(16)(8)(15)(23)(13)(12)(12)(11)(17)(28)(18)(20)(8)(11)(20)(13)(14)(10)(23)(18)(15)(36)(27)(47)(16)(3)(28)(33)(14)(13)
从入门到成长到成熟再到优秀,大多数程序员走了前面一段相似的道路,而有些人却走得更远一些!!!!

我要回帖

更多关于 腾讯微博手机客户端 的文章

 

随机推荐