随时随地阅读更多技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666)
操作步骤:
1、在share官网注册应用生成AppKey并下载SDK 网址:http://www.shareSDK.cn
2、在新浪微博平台注册应用生成AppId和AppKey 网址:新浪微博开放平台-首页
3、导入SDK包。只实现新浪微博授权登录分享的话只需要导入ShareSDK-Core.jar(核心包)、ShareSDK-SinaWeibo.jar(新浪微博)、cn.sharesdk.onekeyshare.jar(快捷分享)
4、配置:需要配置AndroidManifest.xml和assets里面的ShareSDKDevInfor.xml和(后面有示例介绍)
5、添加代码实现登录、获取信息、分享等功能(见下面示例)。
ShareSDKDevInfor.xml:
<?xml version="1.0" encoding="utf-8"?>
<DevInfor>
<!--
说明:
1、表格中的第一项
<ShareSDK AppKey="api20" />
是必须的,其中的AppKey是你在Share SDK上注册的开发者帐号的AppKey
2、所有集成到你项目的平台都应该为其在表格中填写相对应的开发者信息,以新浪微博为例:
<SinaWeibo
SortId="此平台在分享列表中的位置,由开发者自行定义,可以是任何整型数字,数值越大越靠后"
AppKey="填写你在新浪微博上注册的AppKey"
AppSecret="填写你在新浪微博上注册到的AppKey"
Id="自定义字段,整形,用于你项目中对此平台的识别符"
RedirectUrl="填写你在新浪微博上注册的RedirectUrl" />
各个平台注册应用信息的地址如下:
新浪微博:http://open.weibo.com
腾讯微博:http://dev.t.qq.com
QQ空间:http://connect.qq.com/intro/login/
网易微博:http://open.t.163.com
搜狐微博:http://open.t.sohu.com
豆瓣:http://developers.douban.com
人人网:http://dev.renren.com
开心网:http://open.kaixin001.com
Instapaper:http://www.instapaper.com/main/request_oauth_consumer_token
有道云笔记:http://note.youdao.com/open/developguide.html#app
facebook:https://developers.facebook.com
twitter:https://dev.twitter.com
搜狐随身看:https://open.sohu.com
QQ好友分享:http://mobile.qq.com/api/
微信:http://open.weixin.qq.com
-->
<ShareSDK AppKey="123d2e98bef8" />
<!-- AppKey="104972cdd48" "23a9371d3a8" -->
<SinaWeibo
AppKey="3201194191"
AppSecret="0334252914651e8f76bad63337b3b78f"
Id="1"
RedirectUrl="http://appgo.cn"
SortId="1" />
</DevInfor>
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.home.sinamicroblog"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.home.sinamicroblog.LoginActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.home.sinamicroblog.MainActivity" />
<activity android:name="com.home.sinamicroblog.ShowInfoActivity" />
<!-- share SDK 里面的组件 -->
<activity
android:name="cn.sharesdk.framework.AuthorizeActivity"
android:configChanges="keyboardHidden|orientation"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:windowSoftInputMode="stateHidden|adjustResize" >
</activity>
<activity
android:name="cn.sharesdk.onekeyshare.ShareAllGird"
android:configChanges="keyboardHidden|orientation"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:windowSoftInputMode="adjustPan|stateHidden" />
<activity
android:name="cn.sharesdk.onekeyshare.SharePage"
android:configChanges="keyboardHidden|orientation"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden|adjustResize" />
</application>
</manifest>
登录LoginActivity:
package com.home.sinamicroblog;
import java.util.HashMap;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import cn.sharesdk.framework.AbstractWeibo;
import cn.sharesdk.framework.WeiboActionListener;
import cn.sharesdk.sina.weibo.SinaWeibo;
public class LoginActivity extends Activity implements WeiboActionListener,
Callback {
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
AbstractWeibo.initSDK(this);
handler = new Handler(this);
Button logionBtn = (Button) findViewById(R.id.login_btn);
logionBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
AbstractWeibo weibo = AbstractWeibo.getWeibo(
LoginActivity.this, SinaWeibo.NAME);
weibo.setWeiboActionListener(LoginActivity.this);
weibo.showUser(null);
}
});
}
@Override
public void onCancel(AbstractWeibo weibo, int arg1) {
Message msg = new Message();
msg.arg1 = 3;
msg.obj = weibo;
handler.sendMessage(msg);
}
@Override
public void onComplete(AbstractWeibo weibo, int arg1,
HashMap<String, Object> arg2) {
Message msg = new Message();
msg.arg1 = 1;
msg.obj = weibo;
handler.sendMessage(msg);
}
@Override
public void onError(AbstractWeibo weibo, int arg1, Throwable t) {
t.printStackTrace();
Message msg = new Message();
msg.arg1 = 2;
msg.obj = weibo;
handler.sendMessage(msg);
}
/**
* 处理从授权页面返回的结果:异常则给出提示,正常则跳转页面
*
*/
@Override
public boolean handleMessage(Message msg) {
AbstractWeibo weibo = (AbstractWeibo) msg.obj;
switch (msg.arg1) {
case 1: { // 成功
Toast.makeText(this, weibo.getName() + "授权成功", Toast.LENGTH_SHORT)
.show();
}
break;
case 2: { // 失败
Toast.makeText(this, weibo.getName() + "授权失败", Toast.LENGTH_SHORT)
.show();
return false;
}
case 3: { // 取消
Toast.makeText(this, weibo.getName() + "授权取消", Toast.LENGTH_SHORT)
.show();
return false;
}
}
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
return false;
}
@Override
protected void onDestroy() {
// 结束ShareSDK的统计功能并释放资源
AbstractWeibo.stopSDK(this);
super.onDestroy();
}
}
主界面MainActivity:
package com.home.sinamicroblog;
import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import cn.sharesdk.framework.AbstractWeibo;
import cn.sharesdk.framework.WeiboActionListener;
import cn.sharesdk.onekeyshare.ShareAllGird;
import cn.sharesdk.sina.weibo.SinaWeibo;
public class MainActivity extends Activity implements OnClickListener,
Callback, WeiboActionListener {
private Button getInfoBtn;
private Button noUIShareBtn;
private Button hasUIShareBtn;
private Button logoutBtn;
private Handler handler;
// 定义图片存放的地址
public static String TEST_IMAGE;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
AbstractWeibo.initSDK(this);
initWidget();
initImage();
}
/**
* 初始化UI相关组件
*/
private void initWidget() {
getInfoBtn = (Button) findViewById(R.id.main_get_userinfo);
noUIShareBtn = (Button) findViewById(R.id.main_share_noUI);
hasUIShareBtn = (Button) findViewById(R.id.main_share_hasUI);
logoutBtn = (Button) findViewById(R.id.main_btn_logout);
getInfoBtn.setOnClickListener(this);
noUIShareBtn.setOnClickListener(this);
hasUIShareBtn.setOnClickListener(this);
logoutBtn.setOnClickListener(this);
handler = new Handler(this);
}
@Override
public void onClick(View v) {
if (v == getInfoBtn) {
AbstractWeibo weibo = AbstractWeibo.getWeibo(this, SinaWeibo.NAME);
weibo.setWeiboActionListener(this);
weibo.showUser(null);
} else if (v == noUIShareBtn) {
showGrid(true);
} else if (v == hasUIShareBtn) {
showGrid(false);
} else if (v == logoutBtn) {// 注销
AbstractWeibo weibo = AbstractWeibo.getWeibo(this, SinaWeibo.NAME);
if (weibo.isValid()) {
weibo.removeAccount();
finish();
}
}
}
/** 处理操作结果 */
public boolean handleMessage(Message msg) {
switch (msg.arg1) {
case 1: { // 成功
Intent intent = new Intent(MainActivity.this,
ShowInfoActivity.class);
intent.putExtra("data", String.valueOf(msg.obj));
startActivity(intent);
}
break;
case 2: {// 失败
AbstractWeibo weibo = (AbstractWeibo) msg.obj;
Toast.makeText(this, weibo.getName() + "授权失败", Toast.LENGTH_SHORT)
.show();
}
break;
case 3: {// 取消
AbstractWeibo weibo = (AbstractWeibo) msg.obj;
Toast.makeText(this, weibo.getName() + "授权取消", Toast.LENGTH_SHORT)
.show();
}
break;
}
return false;
}
/**
* 初始化分享的本地图片
*/
private void initImage() {
try {// 判断SD卡中是否存在此文件夹
if (Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState())
&& Environment.getExternalStorageDirectory().exists()) {
File baseFile = new File(
Environment.getExternalStorageDirectory(), "share");
if (!baseFile.exists()) {
baseFile.mkdir();
}
TEST_IMAGE = baseFile.getAbsolutePath() + "/picture.png";
} else {
TEST_IMAGE = getApplication().getFilesDir().getAbsolutePath()
+ "/picture.png";
}
File file = new File(TEST_IMAGE);
// 判断图片是否存此文件夹中
if (!file.exists()) {
file.createNewFile();
Bitmap pic = BitmapFactory.decodeResource(getResources(),
R.drawable.picture);
FileOutputStream fos = new FileOutputStream(file);
pic.compress(CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
}
} catch (Throwable t) {
t.printStackTrace();
TEST_IMAGE = null;
}
}
@Override
public void onCancel(AbstractWeibo weibo, int arg1) {
Message msg = new Message();
msg.arg1 = 3;
msg.obj = weibo;
handler.sendMessage(msg);
}
@Override
public void onComplete(AbstractWeibo arg0, int arg1,
HashMap<String, Object> res) {
Message msg = new Message();
msg.arg1 = 1;
JsonUtils ju = new JsonUtils();
String json = ju.fromHashMap(res);
msg.obj = ju.format(json);
handler.sendMessage(msg);
}
@Override
public void onError(AbstractWeibo weibo, int arg1, Throwable arg2) {
Message msg = new Message();
msg.arg1 = 2;
msg.obj = weibo;
handler.sendMessage(msg);
}
/**
* 使用快捷分享完成图文分享
*
* @param silent
* 是否直接分享
*/
private void showGrid(boolean silent) {
Intent i = new Intent(this, ShareAllGird.class);
// 分享时Notification的图标
i.putExtra("notif_icon", R.drawable.ic_launcher);
// 分享时Notification的标题
i.putExtra("notif_title", this.getString(R.string.app_name));
// title标题,在印象笔记、邮箱、信息、微信(包括好友和朋友圈)、人人网和QQ空间使用,否则可以不提供
i.putExtra("title", this.getString(R.string.share));
// titleUrl是标题的网络链接,仅在人人网和QQ空间使用,否则可以不提供
i.putExtra("titleUrl", "http://sharesdk.cn");
// text是分享文本,所有平台都需要这个字段
i.putExtra("text", this.getString(R.string.share_content));
// imagePath是本地的图片路径,所有平台都支持这个字段,不提供,则表示不分享图片
i.putExtra("imagePath", MainActivity.TEST_IMAGE);
// url仅在微信(包括好友和朋友圈)中使用,否则可以不提供
i.putExtra("url", "http://sharesdk.cn");
// thumbPath是缩略图的本地路径,仅在微信(包括好友和朋友圈)中使用,否则可以不提供
i.putExtra("thumbPath", MainActivity.TEST_IMAGE);
// appPath是待分享应用程序的本地路劲,仅在微信(包括好友和朋友圈)中使用,否则可以不提供
i.putExtra("appPath", MainActivity.TEST_IMAGE);
// comment是我对这条分享的评论,仅在人人网和QQ空间使用,否则可以不提供
i.putExtra("comment", this.getString(R.string.share));
// site是分享此内容的网站名称,仅在QQ空间使用,否则可以不提供
i.putExtra("site", this.getString(R.string.app_name));
// siteUrl是分享此内容的网站地址,仅在QQ空间使用,否则可以不提供
i.putExtra("siteUrl", "http://sharesdk.cn");
// 是否直接分享
i.putExtra("silent", silent);
this.startActivity(i);
}
@Override
protected void onResume() {
super.onResume();
AbstractWeibo.initSDK(this);
}
}
显示信息ShowInfoActivity:
package com.home.sinamicroblog;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class ShowInfoActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.show_info);
TextView show = (TextView) findViewById(R.id.show_info_tv);
show.setText(getIntent().getStringExtra("data"));
}
}
工具类JsonUtils:
package com.home.sinamicroblog;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class JsonUtils {
/**
* 将指定的json数据转成 HashMap<String, Object>对象
*/
public HashMap<String, Object> fromJson(String jsonStr) {
try {
if (jsonStr.startsWith("[") && jsonStr.endsWith("]")) {
jsonStr = "{\"fakelist\":" + jsonStr + "}";
}
JSONObject json = new JSONObject(jsonStr);
return fromJson(json);
} catch (Throwable t) {
t.printStackTrace();
}
return new HashMap<String, Object>();
}
private HashMap<String, Object> fromJson(JSONObject json)
throws JSONException {
HashMap<String, Object> map = new HashMap<String, Object>();
@SuppressWarnings("unchecked")
Iterator<String> iKey = json.keys();
while (iKey.hasNext()) {
String key = iKey.next();
Object value = json.opt(key);
if (JSONObject.NULL.equals(value)) {
value = null;
}
if (value != null) {
if (value instanceof JSONObject) {
value = fromJson((JSONObject) value);
} else if (value instanceof JSONArray) {
value = fromJson((JSONArray) value);
}
map.put(key, value);
}
}
return map;
}
private ArrayList<Object> fromJson(JSONArray array) throws JSONException {
ArrayList<Object> list = new ArrayList<Object>();
for (int i = 0, size = array.length(); i < size; i++) {
Object value = array.opt(i);
if (value instanceof JSONObject) {
value = fromJson((JSONObject) value);
} else if (value instanceof JSONArray) {
value = fromJson((JSONArray) value);
}
list.add(value);
}
return list;
}
/**
* 将指定的HashMap<String, Object>对象转成json数据
*/
public String fromHashMap(HashMap<String, Object> map) {
try {
return getJSONObject(map).toString();
} catch (Throwable t) {
t.printStackTrace();
}
return "";
}
@SuppressWarnings("unchecked")
private JSONObject getJSONObject(HashMap<String, Object> map)
throws JSONException {
JSONObject json = new JSONObject();
for (Entry<String, Object> entry : map.entrySet()) {
Object value = entry.getValue();
if (value instanceof HashMap<?, ?>) {
value = getJSONObject((HashMap<String, Object>) value);
} else if (value instanceof ArrayList<?>) {
value = getJSONArray((ArrayList<Object>) value);
}
json.put(entry.getKey(), value);
}
return json;
}
@SuppressWarnings("unchecked")
private JSONArray getJSONArray(ArrayList<Object> list) throws JSONException {
JSONArray array = new JSONArray();
for (Object value : list) {
if (value instanceof HashMap<?, ?>) {
value = getJSONObject((HashMap<String, Object>) value);
} else if (value instanceof ArrayList<?>) {
value = getJSONArray((ArrayList<Object>) value);
}
array.put(value);
}
return array;
}
/**
* 格式化一个json串
*/
public String format(String jsonStr) {
try {
return format("", fromJson(jsonStr));
} catch (Throwable t) {
t.printStackTrace();
}
return "";
}
@SuppressWarnings("unchecked")
private String format(String sepStr, HashMap<String, Object> map) {
StringBuffer sb = new StringBuffer();
sb.append("{\n");
String mySepStr = sepStr + "\t";
int i = 0;
for (Entry<String, Object> entry : map.entrySet()) {
if (i > 0) {
sb.append(",\n");
}
sb.append(mySepStr).append('\"').append(entry.getKey())
.append("\":");
Object value = entry.getValue();
if (value instanceof HashMap<?, ?>) {
sb.append(format(mySepStr, (HashMap<String, Object>) value));
} else if (value instanceof ArrayList<?>) {
sb.append(format(mySepStr, (ArrayList<Object>) value));
} else if (value instanceof String) {
sb.append('\"').append(value).append('\"');
} else {
sb.append(value);
}
i++;
}
sb.append('\n').append(sepStr).append('}');
return sb.toString();
}
@SuppressWarnings("unchecked")
private String format(String sepStr, ArrayList<Object> list) {
StringBuffer sb = new StringBuffer();
sb.append("[\n");
String mySepStr = sepStr + "\t";
int i = 0;
for (Object value : list) {
if (i > 0) {
sb.append(",\n");
}
sb.append(mySepStr);
if (value instanceof HashMap<?, ?>) {
sb.append(format(mySepStr, (HashMap<String, Object>) value));
} else if (value instanceof ArrayList<?>) {
sb.append(format(mySepStr, (ArrayList<Object>) value));
} else if (value instanceof String) {
sb.append('\"').append(value).append('\"');
} else {
sb.append(value);
}
i++;
}
sb.append('\n').append(sepStr).append(']');
return sb.toString();
}
}
login.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical" >
<Button
android:id="@+id/login_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="新浪微博授权登录" />
</LinearLayout>
main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/main_get_userinfo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="获取用户信息" />
<Button
android:id="@+id/main_share_noUI"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="分享(无界面)" />
<Button
android:id="@+id/main_share_hasUI"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="分享(有界面)" />
<Button
android:id="@+id/main_btn_logout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="注销登录" />
</LinearLayout>
show_info.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" >
<TextView
android:id="@+id/show_info_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:autoLink="all"
android:textColor="#ff000000" />
</ScrollView>
</RelativeLayout>
strings:
<string name="share_content">测试使用shareSDK进行分享,感觉还不错,使用方便,功能强大!</string>
<string name="share">分享</string>