为应用添加分享到新浪微博

原创
2012/03/02 11:16
阅读数 2.1W

现在很多平台都开放了,并且提供了相应的接口。在过往你浏览论坛或者博客的时候,一个论坛/博客都需要自己的帐号,但是现在你会发现都有一个“用新浪微博登陆”,“用QQ帐号登录”等的字样。这样你经过授权以后就可以用新浪或这腾讯的帐号登录到论坛或者博客了,这确实是挺方便的事情,可以直接为你的社区带来用户流量。

最近开发的应用有涉及到分享的功能,android系统有内置的分享功能,但是内置的分享只要你有安装该应用的时候才会被显示在列表中,下面的是android系统内置的分享:如图:
 

在图上的分享选项中,你有看到“新浪微博”,这个是我自己添加的。意思就是说:如果你有安装“新浪微博”移动端,就用系统自己的分享;如果没有安装该应用则需自行添加分享到“新浪微博”的功能。我们先看看这个列表是怎么加载出来的:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
ShareAdapter mAdapter = new ShareAdapter(mContext, intent);
//对话框的适配器
public class ShareAdapter extends BaseAdapter {
	private final static String PACKAGENAME = "com.sina.weibo";

	private Context mContext;
	private PackageManager mPackageManager;
	private Intent mIntent;
	private LayoutInflater mInflater;

	private List<ResolveInfo> mList;
	private List<DisplayResolveInfo> mDisplayResolveInfoList;

	public ShareAdapter(Context context, Intent intent) {
		mContext = context;
		mPackageManager = mContext.getPackageManager();
		mIntent = new Intent(intent);
		mInflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

		mList = mContext.getPackageManager().queryIntentActivities(intent,
				PackageManager.MATCH_DEFAULT_ONLY);
		// 排序
		ResolveInfo.DisplayNameComparator comparator = new ResolveInfo.DisplayNameComparator(
				mPackageManager);
		Collections.sort(mList, comparator);

		mDisplayResolveInfoList = new ArrayList<DisplayResolveInfo>();
		if (mList == null || mList.isEmpty()) {
			mList = new ArrayList<ResolveInfo>();
		}

		final int N = mList.size();
		for (int i = 0; i < N; i++) {
			ResolveInfo ri = mList.get(i);
			CharSequence label = ri.loadLabel(mPackageManager);
			DisplayResolveInfo d = new DisplayResolveInfo(ri, null, null, label, null);
			mDisplayResolveInfoList.add(d);
		}
		//考虑是否已安装新浪微博,如果没有则自行添加
		if(!isInstallApplication(mContext, PACKAGENAME)){
			Intent i = new Intent(mContext, ShareActivity.class);
			Drawable d = mContext.getResources().getDrawable(R.drawable.sina);
			CharSequence label = mContext.getString(R.string.about_sina_weibo);
			DisplayResolveInfo dr = new DisplayResolveInfo(null, i, null, label, d);
			mDisplayResolveInfoList.add(0, dr);
		}
	}

	@Override
	public int getCount() {
		return mDisplayResolveInfoList.size();
	}

	@Override
	public Object getItem(int position) {
		return mDisplayResolveInfoList.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		View item;
		if(convertView == null) {
			item = mInflater.inflate(R.layout.share_item, null);
		} else {
			item = convertView;
		}
		DisplayResolveInfo info = mDisplayResolveInfoList.get(position);
		
		ImageView i = (ImageView) item.findViewById(R.id.share_item_icon);
		if(info.mDrawable == null){
			i.setImageDrawable(info.mResoleInfo.loadIcon(mPackageManager));
		}else{
			i.setImageDrawable(info.mDrawable);
		}
		
		TextView t = (TextView) item.findViewById(R.id.share_item_text);
		t.setText(info.mLabel);
		return item;
	}
	
	public ResolveInfo getResolveInfo(int index){
		if(mDisplayResolveInfoList == null){
			return null;
		}
		DisplayResolveInfo d = mDisplayResolveInfoList.get(index);
		if(d.mResoleInfo == null){
			return null;
		}
		return d.mResoleInfo;
	}
	
	//返回跳转intent
	public Intent getIntentForPosition(int index) {
		if(mDisplayResolveInfoList == null){
			return null;
		}
		DisplayResolveInfo d = mDisplayResolveInfoList.get(index);
		Intent i = new Intent(d.mIntent == null ? mIntent : d.mIntent);
		i.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
		if(d.mResoleInfo != null){
			ActivityInfo a = d.mResoleInfo.activityInfo;
			i.setComponent(new ComponentName(a.applicationInfo.packageName, a.name));
		}
		return i;
	}
	
	//检查是否安装该app
	boolean isInstallApplication(Context context, String packageName){
		try {
			mPackageManager
					.getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
			return true;
		} catch (NameNotFoundException e) {
			return false;
		}
		
	}

	/**
	 * 打包数据 vo
	 * @author Administrator
	 */
	class DisplayResolveInfo {
		private Intent mIntent;
		private ResolveInfo mResoleInfo;
		private CharSequence mLabel;
		private Drawable mDrawable;
	
		DisplayResolveInfo(ResolveInfo resolveInfo, Intent intent,
				CharSequence info, CharSequence label, Drawable d) {
			this.mIntent = intent;
			this.mResoleInfo = resolveInfo;
			this.mLabel = label;
			this.mDrawable = d;
		}
	}
}

以上就加载弹出框的数据适配器,如果系统有安装则直接读取系统的分享,没有则添加。当你点击分享微博的时候,就需要一列的验证和授权了,这边采用的机制是先获取requestToken,然后通过requestToken获取AccessToken,然后才可以分享分享微博,开始的时候自己也是从新浪官方的现在的sdk不知道是1.0还是2.0,但是始终都不能发送微博,诡异的是用官方的sdk可以认证完成,并能够获取微博内容,但是死活发不了微博,郁闷好几天!但是看到它的官方论坛里面有那么多的受害者,我表示沉默,一个诺大的公司提供一个接口居然成这样。现在自己用的这个sdk版本里面的Weibo.java有很多其他的方法,如获取用户信息,收藏微博等,大家可以自己看看。
接下来是在你点击“分享到微博”的时候进行认证用户了,说先说明一下这边的认证是读取新浪提供的页面,显示的界面如第二章图片,下面是部分代码:

Weibo weibo = new Weibo();
RequestToken requestToken = weibo.getOAuthRequestToken("yunmai://ShareActivity");//与配置中对应 Log.i(TAG, "token:" + requestToken.getToken() + ",tokenSecret:" + requestToken.getTokenSecret());
OAuthConstant.getInstance().setRequestToken(requestToken);
Uri uri = Uri.parse(requestToken.getAuthenticationURL() + "&display=mobile");
url = uri.toString();
上面的地址url就是你请求新浪提供的登录界面的地址了,这边会涉及到webview的使用,在android里面webview其实就是一个小型浏览器,功能很强大,强大到可以执行脚本。有了地址可以通过webview.loadurl(url)请求登录界面。也有很多网友可能会想自己设计一个登录界面,但是新浪官方有说明通过getXauthAccessToken方式认证是可以自行设计登录界面的,其他认证方式是不能够自行设计的。在你点击“授权”按钮是需要跳转到我们自己的activity这里的配置是需要在androidmanifest.xml中配置,比如我这边跳转的是shareactivity.java

<activity
            android:name="cn.yunmai.cclauncher.ShareActivity"
            android:screenOrientation="portrait" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:host="ShareActivity" android:scheme="yunmai" />
            </intent-filter>
        </activity>

需要注意的是<data>标签里面的内容需要和你显示授权窗口的中weibo.getOAuthRequestToken("yunmai://ShareActivity")相对应。你授权完成之后就会跳转到你定义的activity,授权完成之后就发微博了跳转之后的activity就比较清楚明白了吧,简单点就可以放一个发送按钮,一个editText就可以了。在你点击发送按钮的时候,你要获取你刚才授权成功的RequestToken然后再获取accessToken最后发送微博,需要注意的是RequestToken只需获取一次,然后保存你的accessToekn这个才你每次都需要使用的口令,这里就可以优化一下体验了。点击发送按钮的操作是:

Uri uri = this.getIntent().getData();
RequestToken requestToken = OAuthConstant.getInstance().getRequestToken();
AccessToken accessToken = requestToken.getAccessToken(uri.getQueryParameter("oauth_verifier"));
saveAccessToken(accessToken);//保存accessToken
Log.i(TAG, "oauth_verifier:" + uri.getQueryParameter("oauth_verifier") + 
             	 	   ",Token" + accessToken.getToken() + ",TokenSecret:" + accessToken.getTokenSecret());
OAuthConstant.getInstance().setAccessToken(accessToken);

这边所执行的操作是获取授权的之后的accessToken,然后就发送微博:

Weibo weibo = OAuthConstant.getInstance().getWeibo();
weibo.setToken(OAuthConstant.getInstance().getToken(), OAuthConstant.getInstance().getTokenSecret());
Status s = weibo.updateStatus(mEdit.getText().toString());

status返回了一些详细的信息,有发送时间,用户ID等。这就样就完成了分享的功能了。

最后分享一些关于新浪分享的地址:
新浪官方论坛(建议不要寄予太大希望,会完整的回答你的问题):

http://forum.open.weibo.com/

新浪官方接口以及错误说明:
http://open.weibo.com/development

 自己使用的sdk代码和jar包:

 http://www.oschina.net/code/snippet_127095_9003
sdk下载完成后第一件事情就是把jar加载到项目,接着就是把weibo中的两个属性CONSUMER_KEY/CONSUMER_SECRET分别换成你自己申请appkey和secret

有不明白的可以留言!

 

 

展开阅读全文
打赏
1
33 收藏
分享
加载中
好想知道怎么推广微博哦
2014/12/03 18:25
回复
举报
DisplayResolveInfo类是从哪里来的???
2014/06/30 09:37
回复
举报
你好,
我在做第三方分享到新浪微博,请问发布一条微博时
请求参数 必选   类型 及范围   说明
source  false   string  采用OAuth授权方式不需要此参数,其他授权方式为必填参数,数值为应用的AppKey。
access_token  false  string  采用OAuth授权方式为必填参数,其他授权方式不需要此参数,OAuth授权后获得。
status  true  string  要发布的微博文本内容,必须做URLencode,内容不超过140个汉字。
visible  false  int  微博的可见性,0:所有人能看,1:仅自己可见,2:密友可见,3:指定分组可见,默认为0。
list_id  false  string  微博的保护投递指定分组ID,只有当visible参数为3时生效且必选。
lat  false  float  纬度,有效范围:-90.0到+90.0,+表示北纬,默认为0.0。
long  false  float  经度,有效范围:-180.0到+180.0,+表示东经,默认为0.0。
annotations  false  string  元数据,主要是为了方便第三方应用记录一些适合于自己使用的信息,每条微博可以包含一个或者多个元数据,必须以json字串的形式提交,字串长度不超过512个字符,具体内容可以自定。
rip  false  string  开发者上报的操作用户真实IP,形如:211.156.0.1。

这些请求参数中的annotations 是做什么的,看文档的介绍看不明白。如果把他设置成webpage:
webpage
属性  对应值的描述
title  标题
image  图片
url  元数据对应的url地址



能实现这样LinkCard的分享链接的效果吗?
2014/05/13 15:55
回复
举报
你好,请问这个yunmai://ShareActivity是什么意思
2013/10/18 11:15
回复
举报
能把demo发一下不 360319481@qq.com
2013/04/28 11:09
回复
举报
你好!新浪OAuth2 javaSDK怎么实现上传图片哈
2012/11/13 22:05
回复
举报
我希冀着博主

引用来自“yufengzun”的评论

大哥,你的这个是oauth1.0 认证还是oauth2.0 认证??

oauth1.0
2012/07/16 19:08
回复
举报
大哥,你的这个是oauth1.0 认证还是oauth2.0 认证??
2012/07/16 18:34
回复
举报
我希冀着博主

引用来自“zhangxiaoyu”的评论

sorry,明白了shareAdapter

没关系,大家一起学习
2012/07/14 22:26
回复
举报
sorry,明白了shareAdapter
2012/07/14 21:12
回复
举报
更多评论
打赏
31 评论
33 收藏
1
分享
返回顶部
顶部