Android 中实现分享和第三方登陆---以新浪微博为例
第三方登陆和分享功能在目前大部分APP中都有,分享功能可以将自己觉得有意义的东西分享给身边的朋友,而第三方登陆可以借助已经有巨大用户基础的平台(如QQ和新浪微博)的账号,让用户在使用自己APP的时候不用注册,直接使用第三方账号登陆,从而避免了注册的过程(其实是服务器端帮你注册),这对于吸引更多的用户非常有意义。下面我们就以新浪微博为例,讲解如何实现分享功能和第三方登陆。首先你需要到新浪微博开放平台创建一个应用:
新浪微博开放平台:http://open.weibo.com/
首先我们来介绍分享功能,分享功能就是将一些信息分享到一些社交app中,如比较热门的就是新浪微博,腾讯微博,人人网,开心网,微信,朋友圈,易信等等,在Android中 实现分享功能通常有四种方式:
方式一:使用Android自带的分享功能,通过Intent找出手机中所有的社交app
这种方式的优点就是实现比较简单,不需要引入第三方sdk,缺点就是需要安装社交app之后才能分享,其实我觉得这个也是合理的,试想如果一个人的手机中没有安装新浪微博,那么意味着他肯定不玩微博,所以不能分享也无所谓
//分享文本
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, 我用手机测试分享内容);
sendIntent.setType(text/plain);
startActivity(Intent.createChooser(sendIntent, 我是弹出框的标题));
弹出界面如下:
不同人手机这个节目肯定是不一样的,因为有些人喜欢玩微博,只装了微博,没有微信。如果一个人不玩社交app,那么这个Dialog里面至少有一个是短信和蓝牙之类的,因为这些每个手机都有。
例子:
安卓系统本身可以很简便的实现分享功能,因为我们只需向startActivity传递一个ACTION_SEND
的Intent,系统就为我们弹出一个应用程序列表,如果我们再指定intent为chooser的方式,那么这个列表就就会有个指定的标题,如下:
这就是分享界面。
其实凡是以隐式intent调用activity,如果能处理该intent的应用有多个的话,都会出现一个选择应用的对话框,这种对话框除了列出应用列表,还为你提供是永久选择,还是只是这次选择。比如我们发送了这样一个浏览网页的intent:
- String url = "http://www.example.com";
- Intent i = new Intent(Intent.ACTION_VIEW);
- i.setData(Uri.parse(url));
- startActivity(i);
那么系统会为我们列出能接收这个intent的应用(一般浏览器都会实现,相当于一种约定),界面如下:
注意上面的对话框只是单纯列出了应用,而且比分享对话框还多了两个选择方式的按钮,所以仅仅这样还不符合分享功能的需求。
分享的需求有两点:
每次都列出所有应用;
不再提示只是一次选择还是永久选择;
为此,我们需要通过Intent来创建chooser:
- Intent chooserIntent = Intent.createChooser(intent, "Select app to share");
intent的createChooser
方法调用后,上面提到的两个不符合需求的问题就不存在了,其实这就是分享功能的本质,他只不过是利用了Intent的机制而已。
利用系统的api实现分享的代码如下:
- Intent intent = new Intent(Intent.ACTION_SEND);
- intent.setType("text/plain");
- intent.putExtra(Intent.EXTRA_TITLE, title);
- intent.putExtra(Intent.EXTRA_SUBJECT, subject);
- intent.putExtra(Intent.EXTRA_TEXT, content);
- Intent chooserIntent = Intent.createChooser(intent, "Select app to share");
- if (chooserIntent == null) {
- return;
- }
- try {
- startActivity(chooserIntent);
- } catch (android.content.ActivityNotFoundException ex) {
- Toast.makeText(this, "Can't find share component to share", Toast.LENGTH_SHORT).show();
- }
一般,通过上面的代码,提供的分享方式有各种应用:邮件,信息,蓝牙,微博,Twitter,二维码扫描器等。
但是,第一:我想过滤掉蓝牙,
其次:我想对邮件分享详细的内容,对信息和微博等分享较简短的内容,对二维码扫描器只分享URL。
解决的办法是得到所有能处理ACTION_SEND
的应用程序包名,然后根据名字来过滤或者特殊处理。主要用到getPackageManager().queryIntentActivities
方法。
- String contentDetails = "";
- String contentBrief = "";
- String shareUrl = "";
- Intent it = new Intent(Intent.ACTION_SEND);
- it.setType("text/plain");
- List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(it, 0);
- if (!resInfo.isEmpty()) {
- List<Intent> targetedShareIntents = new ArrayList<Intent>();
- for (ResolveInfo info : resInfo) {
- Intent targeted = new Intent(Intent.ACTION_SEND);
- targeted.setType("text/plain");
- ActivityInfo activityInfo = info.activityInfo;
- // judgments : activityInfo.packageName, activityInfo.name, etc.
- if (activityInfo.packageName.contains("bluetooth") || activityInfo.name.contains("bluetooth")) {
- continue;
- }
- if (activityInfo.packageName.contains("gm") || activityInfo.name.contains("mail")) {
- targeted.putExtra(Intent.EXTRA_TEXT, contentDetails);
- } else if (activityInfo.packageName.contains("zxing")) {
- targeted.putExtra(Intent.EXTRA_TEXT, shareUrl);
- } else {
- targeted.putExtra(Intent.EXTRA_TEXT, contentBrief);
- }
- targeted.setPackage(activityInfo.packageName);
- targetedShareIntents.add(targeted);
- }
- Intent chooserIntent = Intent.createChooser(targetedShareIntents.remove(0), "Select app to share");
- if (chooserIntent == null) {
- return;
- }
- // A Parcelable[] of Intent or LabeledIntent objects as set with
- // putExtra(String, Parcelable[]) of additional activities to place
- // a the front of the list of choices, when shown to the user with a
- // ACTION_CHOOSER.
- chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedShareIntents.toArray(new Parcelable[] {}));
- try {
- startActivity(chooserIntent);
- } catch (android.content.ActivityNotFoundException ex) {
- Toast.makeText(this, "Can't find share component to share", Toast.LENGTH_SHORT).show();
- }
- }
如果我们想指定一个应用来分享,那么可以将上面的代码做些修改:
- private void initShareIntent(String type) {
- boolean found = false;
- Intent share = new Intent(android.content.Intent.ACTION_SEND);
- share.setType("image/jpeg");
- // gets the list of intents that can be loaded.
- List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(share, 0);
- if (!resInfo.isEmpty()){
- for (ResolveInfo info : resInfo) {
- if (info.activityInfo.packageName.toLowerCase().contains(type) ||
- info.activityInfo.name.toLowerCase().contains(type) ) {
- share.putExtra(Intent.EXTRA_SUBJECT, "subject");
- share.putExtra(Intent.EXTRA_TEXT, "your text");
- share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(myPath)) ); // Optional, just if you wanna share an image.
- share.setPackage(info.activityInfo.packageName);
- found = true;
- break;
- }
- }
- if (!found)
- return;
- startActivity(Intent.createChooser(share, "Select"));
- }
- }
然后在需要分享的地方加上:
- initShareIntent("twi");
其实这种方法的前提是你必须知道某个应用的包名大致是什么样,比如qq的微信和微博的包名其实没有qq
initShareIntent(
"qq"
);是没有用的,你可以先将他们打印出来看长什么样子,然后在调用。以下是我总结的一些常用应用包名:
- case ID_QQWEIBO:
- initShareIntent("com.tencent.wblog");
- break;
- case ID_WEIXIN:
- initShareIntent("com.tencent.mm");
- break;
- case ID_EVERNOTE:
- initShareIntent("evernote");
- break;
- case ID_SINAWEIBO:
- initShareIntent("com.sina.weibo");
- break;
- case ID_RENREN:
- initShareIntent("renren");
- break;
- case ID_QQ:
- initShareIntent("tencent.mobileqq");
- break;
方式二:使用ShareSDK实现,ShareSDK是一款功能非常强大的第三方提供的专门用于分享等功能的sdk,使用也很简单,但是需要引入一些sdk,这里我就不举例了,研究一些ShareSDK提供的demo就可以实现,优点是简单,功能强大,并且不需要安装社交app
方式三:使用社交开放平台提供的sdk,有点事简单,但是需要安装社交app
方式四:使用社交平台提供的api接口,通过调用这些api接口实现分享和登陆,使用这种不需要安装社交app
本文着重介绍第四种方式,并以新浪微博为例:
1、创建微博授权所需参数的持久化类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
/** * 该类定义了微博授权时所需要的参数。 * * @author SINA * @since 2013-10-07 */ public class AccessTokenKeeper { private static final String PREFERENCES_NAME = com_weibo_sdk_android; private static final String KEY_UID = uid; private static final String KEY_ACCESS_TOKEN = access_token; private static final String KEY_EXPIRES_IN = expires_in; /** * 保存 Token 对象到 SharedPreferences。 * * @param context 应用程序上下文环境 * @param token Token 对象 */ public static void writeAccessToken(Context context, Oauth2AccessToken token) { if ( null == context || null == token) { return ; } SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND); Editor editor = pref.edit(); editor.putString(KEY_UID, token.getUid()); editor.putString(KEY_ACCESS_TOKEN, token.getToken()); editor.putLong(KEY_EXPIRES_IN, token.getExpiresTime()); editor.commit(); } /** * 从 SharedPreferences 读取 Token 信息。 * * @param context 应用程序上下文环境 * * @return 返回 Token 对象 */ public static Oauth2AccessToken readAccessToken(Context context) { if ( null == context) { return null ; } Oauth2AccessToken token = new Oauth2AccessToken(); SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND); token.setUid(pref.getString(KEY_UID, )); token.setToken(pref.getString(KEY_ACCESS_TOKEN, )); token.setExpiresTime(pref.getLong(KEY_EXPIRES_IN, 0 )); return token; } /** * 清空 SharedPreferences 中 Token信息。 * * @param context 应用程序上下文环境 */ public static void clear(Context context) { if ( null == context) { return ; } SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND); Editor editor = pref.edit(); editor.clear(); editor.commit(); } } |
2、创建一个类,用来实分享和登陆功能,当然你需要引入新浪微博的sdk:weibosdkcore.jar,这个jar包在新浪微博开放平台下提供下载。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
/** * 新浪微博API,可以根据自己的需要添加API * * @author cstdingran@gmail.com * */ public class SinaWeiboAPI { /** * 访问微博服务接口的地址 */ public static final String API_SERVER = https: //api.weibo.com/2; private static final String URL_USERS = API_SERVER + /users; private static final String URL_STATUSES = API_SERVER + /statuses; private static final String URL_ACCOUNT = API_SERVER + /account; /** * post请求方式 */ public static final String HTTPMETHOD_POST = POST; /** * get请求方式 */ public static final String HTTPMETHOD_GET = GET; private Oauth2AccessToken oAuth2accessToken; private String accessToken; /** * 构造函数,使用各个API接口提供的服务前必须先获取Oauth2AccessToken * * @param accesssToken * Oauth2AccessToken */ public SinaWeiboAPI(Oauth2AccessToken oauth2AccessToken) { this .oAuth2accessToken = oauth2AccessToken; if (oAuth2accessToken != null ) { accessToken = oAuth2accessToken.getToken(); } } /** * 执行请求 * * @param url * @param params * @param httpMethod * @param listener */ private void request( final String url, final WeiboParameters params, final String httpMethod, RequestListener listener) { params.put(access_token, accessToken); AsyncWeiboRunner.requestAsync(url, params, httpMethod, listener); } /** * 根据用户ID获取用户信息 * * @param uid * 需要查询的用户ID。 * @param listener */ public void show( long uid, RequestListener listener) { WeiboParameters params = new WeiboParameters(); params.put(uid, uid); request(URL_USERS + /show.json, params, HTTPMETHOD_GET, listener); } /** * 发布一条新微博(连续两次发布的微博不可以重复) * * @param content * 要发布的微博文本内容,内容不超过140个汉字。 * @param lat * 纬度,有效范围:-90.0到+90.0,+表示北纬,默认为0.0。 * @param lon * 经度,有效范围:-180.0到+180.0,+表示东经,默认为0.0。 * @param listener */ public void update(String content, String lat, String lon, RequestListener listener) { WeiboParameters params = new WeiboParameters(); params.put(status, content); if (!TextUtils.isEmpty(lon)) { params.put( long , lon); } if (!TextUtils.isEmpty(lat)) { params.put(lat, lat); } request(URL_STATUSES + /update.json, params, HTTPMETHOD_POST, listener); } /** * 上传图片并发布一条新微博,此方法会处理urlencode * * @param content * 要发布的微博文本内容,内容不超过140个汉字 * @param file * 要上传的图片,仅支持JPEG、GIF、PNG格式,图片大小小于5M。 * @param lat * 纬度,有效范围:-90.0到+90.0,+表示北纬,默认为0.0。 * @param lon * 经度,有效范围:-180.0到+180.0,+表示东经,默认为0.0。 * @param listener */ public void upload(String content, String file, String lat, String lon, RequestListener listener) { WeiboParameters params = new WeiboParameters(); params.put(status, content); params.put(pic, file); if (!TextUtils.isEmpty(lon)) { params.put( long , lon); } if (!TextUtils.isEmpty(lat)) { params.put(lat, lat); } request(URL_STATUSES + /upload.json, params, HTTPMETHOD_POST, listener); } //分享一张带网络图片的微博 public void updateImgWithURL(String content, String url,RequestListener listener) { WeiboParameters params = new WeiboParameters(); params.put(status, content); params.put(url, url); request(URL_STATUSES + /upload_url_text.json, params, HTTPMETHOD_POST, listener); } /** * 退出登录 * * @param listener */ public void endSession(RequestListener listener) { WeiboParameters params = new WeiboParameters(); request(URL_ACCOUNT + /end_session.json, params, HTTPMETHOD_POST, listener); } } |
3、分享微博
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
//从本地读取token,检查是否失效或者是否认证 mAccessToken=AccessTokenKeeper.readAccessToken( this ); if (mAccessToken!= null && mAccessToken.isSessionValid()) { mSinaWeiboApi= new SinaWeiboAPI(mAccessToken); mSinaWeiboApi.update(视频 康熙来了:http: //www.iqiyi.com/v_19rrmo4v0o.html, null, null, listener); } else { //如果失效或者没有认证,那么需要重新认证, mWeiboAuth.anthorize( new WeiboAuthListener() { @Override public void onWeiboException(WeiboException arg0) { } @Override public void onComplete(Bundle bundle) { //认证成功,保存到本地 mAccessToken = Oauth2AccessToken.parseAccessToken(bundle); if (mAccessToken.isSessionValid()) { AccessTokenKeeper.writeAccessToken(ShareActivity. this , mAccessToken); mSinaWeiboApi= new SinaWeiboAPI(mAccessToken); //然后分享 mSinaWeiboApi.update(视频 康熙来了:http: //www.iqiyi.com/v_19rrmo4v0o.html, null, null, listener); } } @Override public void onCancel() { } }); } |
那么分享到这里就完成了,至于第三方登陆,首先也是要认证,认证成功后AccessToken里面有一个Uid,我们通过这个uid拿到用户信息然后帮助用户在后台注册就实现了第三方登陆了,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
WeiboMessage weiboMessage = new WeiboMessage(); weiboMessage.mediaObject = getVideoObj(); SendMessageToWeiboRequest request = new SendMessageToWeiboRequest(); // 用transaction唯一标识一个请求 request.transaction = String.valueOf(System.currentTimeMillis()); request.message = weiboMessage; // 3. 发送请求消息到微博,唤起微博分享界面 mWeiboShareAPI.sendRequest(request); } else if (view.getId()==R.id.btn_login) { mAccessToken=AccessTokenKeeper.readAccessToken( this ); //已经认证 if (mAccessToken!= null &&mAccessToken.isSessionValid()) { mSinaWeiboApi= new SinaWeiboAPI(mAccessToken); mSinaWeiboApi.show(Long.parseLong(mAccessToken.getUid()),listener); } else { //没有认证或者认证过期 mWeiboAuth.anthorize( new WeiboAuthListener() { @Override public void onWeiboException(WeiboException arg0) { } @Override public void onComplete(Bundle bundle) { mAccessToken = Oauth2AccessToken.parseAccessToken(bundle); AccessTokenKeeper.writeAccessToken(ShareActivity. this , mAccessToken); mSinaWeiboApi= new SinaWeiboAPI(mAccessToken); mSinaWeiboApi.show(Long.parseLong(mAccessToken.getUid()),listener); } @Override public void onCancel() { } }); } |
思路其实和分享是一样的,就是调用的接口不一样。
好了,先写到这里,其实如果你学会了分享和登陆,那么其实你完全可以自己去写一个新浪微博,因为这个jar包里面提供了新浪微博所有操作的api,如获取某人发的所有微博,获取粉丝,自己关注的人等等,其实网上很多新浪微博开发的例子都是通过这个方法实现的
Android 中实现分享和第三方登陆---以新浪微博为例的更多相关文章
- Android第三方登陆之新浪微博Weibo篇(原生登陆授权)
前言 Android第三方登录可以说是非常的常见,今天主要先说一下新浪微博第三方登陆授权. SDK版本支持 SDK v3.0已经发布了支持iPhone和Android的版本. 须将你的应用的包名签名信 ...
- android中接入twitter进行第三方登录
在应用中接入Twitter进行第三方登录时,开发人员遇到了一点问题,主要是概念有点混乱,这里把经验记录一下,帮助遇到同样问题的朋友. 一.注册应用并配置登录权限 这一步比较简单,就不多说了,直接去官网 ...
- Android应用接入第三方登陆之新浪微博
众所周知,移动互联网在这几年经历了蓬勃发展,到目前为止,移动互联网发展仍然很强劲.其中移动设备系统以android占据主导地位,之前是加拿大的黑莓系统占据主导,但后来随着android系统的问世,黑莓 ...
- 分享QQ第三方登陆SDK
主要是考虑到QQ的PHP SDK写的真是太烂了,纯属是普及API知识,而不是到手就可以部署的类库..反正自己都写了一个了,就拿出来分享下.. 什么也不多说,直接上代码. Qq_sdk.php < ...
- 如何在Android中的Activity启动第三方应用程序?
如何在点击某个按键后,执行启动第三方应用程序界面? /** * <功能描述> 启动应用程序 * * @return void [返回类型说明] */ private void startU ...
- 使用overtrue/socialite实现第三方登陆
composer下载包 将申请的配置内容放在.ENV文件中 在services.php文件中引用 控制器 其他第三方登陆同理,拿到client_id,client_secret 和redirect_u ...
- Android实现QQ分享及注意事项
一.获取APPID和帮助文档 在前面我介绍了关于Android中微信分享的文章< Android实现微信分享及注意事项>这一篇文章来看看关于QQ分享. 可以参看新手引导和接入说明:http ...
- Android自定义系统分享面板
在Android中实现分享有一种比较方便的方式,调用系统的分享面板来分享我们的应用.最基本的实现如下: public Intent getShareIntent(){ Intent intent = ...
- Java时间间隔问题在Android中的使用
转载请注明出处:http://www.cnblogs.com/cnwutianhao/p/6606720.html 假设我们在做项目的时候,获取到了一段音频,也知道音频长度,那么我们想对音频做一些处理 ...
随机推荐
- Fast Scatter-Gather I/O
Some applications may need to read or write data to multiple buffers, which are separated in memory. ...
- Djianggo 在windows中安装出现报错的解决方案
Djianggo 在win7下 安装会报错 Traceback (most recent call last):File "setup.py", line 4, in <mo ...
- C#.Net使用正则表达式抓取百度百家文章列表
工作之余,学习了一下正则表达式,鉴于实践是检验真理的唯一标准,于是便写了一个利用正则表达式抓取百度百家文章的例子,具体过程请看下面源码: 一:获取百度百家网页内容 public List<str ...
- C#与数据库访问技术总结(三)之 Connection对象的常用方法
说明:前面(一)(二)总结了数据库连接的概念以及连接数据库的字符串中的各个参数的含义.这篇随笔介绍connection对象的常用方法. Connection对象的常用方法 Connection类型的对 ...
- 基于C#局域网语音聊天
基于C#局域网语音聊天室,可实现文本消息的发送.接收及语音聊天,是一个很不错的,适合初学者的软件开发 ...
- c语言 参数传值和传地址
static void TestCharP(char **p) { char *q = "ssssss"; *p=q; } static void TestCharP1(char ...
- 【C#】 创建、部署和调用WebService的简单示例
C# 创建.部署和调用WebService的简单示例 <div class="postBody"> <div id="cnblogs_post_body ...
- .NET 开源GIS解决方案一 概述
写在前面 最近开始研究开源GIS,国内开源GIS的资料很少,而基于.net的又是少之又少.所以决定把自己研究的资料进行总结整理,技术在于分享,本系列(计划是写一个系列,如果我可以坚持下来的话)部分是自 ...
- CHUI类
自定义控件程序运行流程 setNeedsLayOut和setNeedsDisplay区别 masonry使用技巧 1.普通展示 UILabel UIView UI控件的位置 U ...
- 第一个spring MVC
1.导包 Spring所有包 2.web.xml配置 <?xml version="1.0" encoding="UTF-8"?> <web- ...