当前位置:  编程技术>移动开发
本页文章导读:
    ▪曾经的脚印——对CAN驱动中的NAPI机制的理解        曾经的足迹——对CAN驱动中的NAPI机制的理解 NAPI 是 Linux 上采用的一种提高网络处理效率的技术,它的核心概念就是不采用中断的方式读取数据,而代之以首先采用中断唤醒数据接收的服.........
    ▪ 身份证号检测是不是正确(实战)        身份证号检测是否正确(实战)网上找到的,备份一份 package com.example.bank; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Ha.........
    ▪ 新浪微博SSO受权以及分享(实战)       新浪微博SSO授权以及分享(实战)很多人不会使用第三方应用,特写此篇使用下第三方应用:代码具体如下: 【ConstantS.java】 public interface ConstantS { // 应用的key 请到官方申请正式的appkey替.........

[1]曾经的脚印——对CAN驱动中的NAPI机制的理解
    来源: 互联网  发布时间: 2014-02-18
曾经的足迹——对CAN驱动中的NAPI机制的理解

NAPI 是 Linux 上采用的一种提高网络处理效率的技术,它的核心概念就是不采用中断的方式读取数据,而代之以首先采用中断唤醒数据接收的服务程序,然后 通过poll的方法来轮询数据。采用NAPI技术可以大大改善短长度数据包接收的效率,减少中断触发的时间。

可以这样理解,在NAPI机制没有出现时,由于网络设备接收数据是采用中断方式的,假设每次数据包很小,小到只有几个字节。而刚好在1秒内有5000个这样的数据包。那么系统就是在1秒内产生5000个中断,这无疑给会占据CPU的大部分资源。NAPI的出现就是要解决这样的问题。

概念的东西就不多提了。下面开始源码之旅啦!

首先在分配CAN设备时,采用netif_napi_add函数注册轮询函数d_can_poll()。

struct net_device *alloc_d_can_dev(int num_objs)

{

struct net_device *dev;

struct d_can_priv *priv;

 

dev = alloc_candev(sizeof(struct d_can_priv), num_objs/2);

if (!dev)

return NULL;

 

priv = netdev_priv(dev);

netif_napi_add(dev, &priv->napi, d_can_poll, num_objs/2);

 

priv->dev = dev;

priv->can.bittiming_const = &d_can_bittiming_const;

priv->can.do_set_mode = d_can_set_mode;

priv->can.do_get_berr_counter = d_can_get_berr_counter;

priv->can.ctrlmode_supported = (CAN_CTRLMODE_LOOPBACK |

CAN_CTRLMODE_LISTENONLY |

CAN_CTRLMODE_BERR_REPORTING |

CAN_CTRLMODE_3_SAMPLES);

 

return dev;

}

netif_napi_add()函数原型如下:

void netif_napi_add(struct net_device *dev, struct napi_struct *napi,

    int (*poll)(struct napi_struct *, int), int weight)

{

INIT_LIST_HEAD(&napi->poll_list);

napi->gro_count = 0;

napi->gro_list = NULL;

napi->skb = NULL;

napi->poll = poll;

napi->weight = weight;

list_add(&napi->dev_list, &dev->napi_list);

napi->dev = dev;

#ifdef CONFIG_NETPOLL

spin_lock_init(&napi->poll_lock);

napi->poll_owner = -1;

#endif

set_bit(NAPI_STATE_SCHED, &napi->state);

}

 

轮询函数d_can_poll()如下:

static int d_can_poll(struct napi_struct *napi, int quota)

{

int lec_type = 0;

int work_done = 0;

struct net_device *dev = napi->dev;

struct d_can_priv *priv = netdev_priv(dev);

 

if (!priv->irqstatus)

goto end;

 

/* status events have the highest priority */

if (priv->irqstatus == STATUS_INTERRUPT) {

priv->current_status = d_can_read(priv, D_CAN_ES);

 

/* handle Tx/Rx events */

if (priv->current_status & D_CAN_ES_TXOK)

d_can_write(priv, D_CAN_ES,

priv->current_status & ~D_CAN_ES_TXOK);

 

if (priv->current_status & D_CAN_ES_RXOK)

d_can_write(priv, D_CAN_ES,

priv->current_status & ~D_CAN_ES_RXOK);

 

/* handle state changes */

if ((priv->current_status & D_CAN_ES_EWARN) &&

(!(priv->last_status & D_CAN_ES_EWARN))) {

netdev_dbg(dev, "entered error warning state\n");

work_done += d_can_handle_state_change(dev,

D_CAN_ERROR_WARNING);

}

if ((priv->current_status & D_CAN_ES_EPASS) &&

(!(priv->last_status & D_CAN_ES_EPASS))) {

netdev_dbg(dev, "entered error passive state\n");

work_done += d_can_handle_state_change(dev,

D_CAN_ERROR_PASSIVE);

}

if ((priv->current_status & D_CAN_ES_BOFF) &&

(!(priv->last_status & D_CAN_ES_BOFF))) {

netdev_dbg(dev, "entered bus off state\n");

work_done += d_can_handle_state_change(dev,

D_CAN_BUS_OFF);

}

 

/* handle bus recovery events */

if ((!(priv->current_status & D_CAN_ES_BOFF)) &&

(priv->last_status & D_CAN_ES_BOFF)) {

netdev_dbg(dev, "left bus off state\n");

priv->can.state = CAN_STATE_ERROR_ACTIVE;

}

if ((!(priv->current_status & D_CAN_ES_EPASS)) &&

(priv->last_status & D_CAN_ES_EPASS)) {

netdev_dbg(dev, "left error passive state\n");

priv->can.state = CAN_STATE_ERROR_ACTIVE;

}

 

priv->last_status = priv->current_status;

 

/* handle lec errors on the bus */

lec_type = d_can_has_handle_berr(priv);

if (lec_type)

work_done += d_can_handle_bus_err(dev, lec_type);

} else if ((priv->irqstatus >= D_CAN_MSG_OBJ_RX_FIRST) &&

(priv->irqstatus <= D_CAN_MSG_OBJ_RX_LAST)) {

/* handle events corresponding to receive message objects */

work_done += d_can_do_rx_poll(dev, (quota - work_done));

} else if ((priv->irqstatus >= D_CAN_MSG_OBJ_TX_FIRST) &&

(priv->irqstatus <= D_CAN_MSG_OBJ_TX_LAST)) {

/* handle events corresponding to transmit message objects */

d_can_do_tx(dev);

}

 

end:

if (work_done < quota) {

napi_complete(napi);

/* enable all IRQs */

d_can_interrupts(priv, ENABLE_ALL_INTERRUPTS);

}

 

return work_done;

}

 

在中断处理函数中,先禁止接收中断,且告诉网络子系统,将以轮询方式快速收包,其中禁止接收中断完全由硬件功能决定,而告诉内核将以轮询方式处理包则是使用函数napi_schedule()。

static irqreturn_t d_can_isr(int irq, void *dev_id)

{

struct net_device *dev = (struct net_device *)dev_id;

struct d_can_priv *priv = netdev_priv(dev);

priv->irqstatus = d_can_read(priv, D_CAN_INT);

if (!priv->irqstatus)

return IRQ_NONE;

 

/* disable all interrupts and schedule the NAPI */

d_can_interrupts(priv, DISABLE_ALL_INTERRUPTS);

napi_schedule(&priv->napi);

 

return IRQ_HANDLED;

}

 

其中的napi_schedule_prep()函数是为了判定现在是否已经进入了轮询模式。

static inline void napi_schedule(struct napi_struct *n)

{

if (napi_schedule_prep(n))

__napi_schedule(n);

}

 

轮询功能的关闭则需要使用:

if (work_done < quota) {

napi_complete(napi);

/* enable all IRQs */

d_can_interrupts(priv, ENABLE_ALL_INTERRUPTS);

}

 

因为可能存在多个napi_struct的实例,要求每个实例能够独立的使能或者禁止。因此,需要驱动开发人员保证在网卡接口关闭时,禁止所有的napi_struct的实例。在d_can_open()函数中使用napi_enable(),在d_can_close()函数中使用napi_disable()。

napi_enable(&priv->napi);

napi_disable(&priv->napi);

 


    
[2] 身份证号检测是不是正确(实战)
    来源: 互联网  发布时间: 2014-02-18
身份证号检测是否正确(实战)

网上找到的,备份一份

package com.example.bank;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CheckPCard {
	/*********************************** 身份证验证开始 ****************************************/
	/**
	 * 身份证号码验证 1、号码的结构 公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,
	 * 八位数字出生日期码,三位数字顺序码和一位数字校验码。 2、地址码(前六位数)
	 * 表示编码对象常住户口所在县(市、旗、区)的行政区划代码,按GB/T2260的规定执行。 3、出生日期码(第七位至十四位)
	 * 表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。 4、顺序码(第十五位至十七位)
	 * 表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号, 顺序码的奇数分配给男性,偶数分配给女性。 5、校验码(第十八位数)
	 * (1)十七位数字本体码加权求和公式 S = Sum(Ai * Wi), i = 0, ... , 16 ,先对前17位数字的权求和
	 * Ai:表示第i位置上的身份证号码数字值 Wi:表示第i位置上的加权因子 Wi: 7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4
	 * 2 (2)计算模 Y = mod(S, 11) (3)通过模得到对应的校验码 Y: 0 1 2 3 4 5 6 7 8 9 10 校验码: 1 0
	 * X 9 8 7 6 5 4 3 2
	 */

	/**
	 * 功能:身份证的有效验证
	 * 
	 * @param IDStr
	 *            身份证号
	 * @return 有效:返回"" 无效:返回String信息
	 * @throws ParseException
	 */
	@SuppressWarnings("unchecked")
	public static String IDCardValidate(String IDStr) throws ParseException {
		String errorInfo = "";// 记录错误信息
		String[] ValCodeArr = { "1", "0", "x", "9", "8", "7", "6", "5", "4",
				"3", "2" };
		String[] Wi = { "7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7",
				"9", "10", "5", "8", "4", "2" };
		String Ai = "";
		// ================ 号码的长度 15位或18位 ================
		if (IDStr.length() != 15 && IDStr.length() != 18) {
			errorInfo = "身份证号码长度应该为15位或18位。";
			return errorInfo;
		}
		// =======================(end)========================

		// ================ 数字 除最后以为都为数字 ================
		if (IDStr.length() == 18) {
			Ai = IDStr.substring(0, 17);
		} else if (IDStr.length() == 15) {
			Ai = IDStr.substring(0, 6) + "19" + IDStr.substring(6, 15);
		}
		if (isNumeric(Ai) == false) {
			errorInfo = "身份证15位号码都应为数字 ; 18位号码除最后一位外,都应为数字。";
			return errorInfo;
		}
		// =======================(end)========================

		// ================ 出生年月是否有效 ================
		String strYear = Ai.substring(6, 10);// 年份
		String strMonth = Ai.substring(10, 12);// 月份
		String strDay = Ai.substring(12, 14);// 月份
		if (isDate(strYear + "-" + strMonth + "-" + strDay) == false) {
			errorInfo = "身份证生日无效。";
			return errorInfo;
		}
		GregorianCalendar gc = new GregorianCalendar();
		SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
		if ((gc.get(Calendar.YEAR) - Integer.parseInt(strYear)) > 150
				|| (gc.getTime().getTime() - s.parse(
						strYear + "-" + strMonth + "-" + strDay).getTime()) < 0) {
			errorInfo = "身份证生日不在有效范围。";
			return errorInfo;
		}
		if (Integer.parseInt(strMonth) > 12 || Integer.parseInt(strMonth) == 0) {
			errorInfo = "身份证月份无效";
			return errorInfo;
		}
		if (Integer.parseInt(strDay) > 31 || Integer.parseInt(strDay) == 0) {
			errorInfo = "身份证日期无效";
			return errorInfo;
		}
		// =====================(end)=====================

		// ================ 地区码时候有效 ================
		Hashtable h = GetAreaCode();
		if (h.get(Ai.substring(0, 2)) == null) {
			errorInfo = "身份证地区编码错误。";
			return errorInfo;
		}
		// ==============================================

		// ================ 判断最后一位的值 ================
		int TotalmulAiWi = 0;
		for (int i = 0; i < 17; i++) {
			TotalmulAiWi = TotalmulAiWi
					+ Integer.parseInt(String.valueOf(Ai.charAt(i)))
					* Integer.parseInt(Wi[i]);
		}
		int modValue = TotalmulAiWi % 11;
		String strVerifyCode = ValCodeArr[modValue];
		Ai = Ai + strVerifyCode;

		if (IDStr.length() == 18) {
			if (Ai.equals(IDStr) == false) {
				errorInfo = "身份证无效,不是合法的身份证号码";
				return errorInfo;
			}
		} else {
			return "";
		}
		// =====================(end)=====================
		return "";
	}

	/**
	 * 功能:设置地区编码
	 * 
	 * @return Hashtable 对象
	 */
	@SuppressWarnings("unchecked")
	private static Hashtable GetAreaCode() {
		Hashtable hashtable = new Hashtable();
		hashtable.put("11", "北京");
		hashtable.put("12", "天津");
		hashtable.put("13", "河北");
		hashtable.put("14", "山西");
		hashtable.put("15", "内蒙古");
		hashtable.put("21", "辽宁");
		hashtable.put("22", "吉林");
		hashtable.put("23", "黑龙江");
		hashtable.put("31", "上海");
		hashtable.put("32", "江苏");
		hashtable.put("33", "浙江");
		hashtable.put("34", "安徽");
		hashtable.put("35", "福建");
		hashtable.put("36", "江西");
		hashtable.put("37", "山东");
		hashtable.put("41", "河南");
		hashtable.put("42", "湖北");
		hashtable.put("43", "湖南");
		hashtable.put("44", "广东");
		hashtable.put("45", "广西");
		hashtable.put("46", "海南");
		hashtable.put("50", "重庆");
		hashtable.put("51", "四川");
		hashtable.put("52", "贵州");
		hashtable.put("53", "云南");
		hashtable.put("54", "西藏");
		hashtable.put("61", "陕西");
		hashtable.put("62", "甘肃");
		hashtable.put("63", "青海");
		hashtable.put("64", "宁夏");
		hashtable.put("65", "新疆");
		hashtable.put("71", "台湾");
		hashtable.put("81", "香港");
		hashtable.put("82", "澳门");
		hashtable.put("91", "国外");
		return hashtable;
	}

	/**
	 * 功能:判断字符串是否为数字
	 * 
	 * @param str
	 * @return
	 */
	private static boolean isNumeric(String str) {
		Pattern pattern = Pattern.compile("[0-9]*");
		Matcher isNum = pattern.matcher(str);
		if (isNum.matches()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 功能:判断字符串是否为日期格式
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isDate(String strDate) {
		Pattern pattern = Pattern
				.compile("^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1-2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$");
		Matcher m = pattern.matcher(strDate);
		if (m.matches()) {
			return true;
		} else {
			return false;
		}
	}

	/*********************************** 身份证验证结束 ****************************************/

}



    
[3] 新浪微博SSO受权以及分享(实战)
    来源: 互联网  发布时间: 2014-02-18
新浪微博SSO授权以及分享(实战)

很多人不会使用第三方应用,特写此篇使用下第三方应用:代码具体如下:

【ConstantS.java】

public interface ConstantS {

	// 应用的key 请到官方申请正式的appkey替换APP_KEY
	public static final String APP_KEY = "2045436852";

	// 替换为开发者REDIRECT_URL
	public static final String REDIRECT_URL = "http://www.sina.com";

	// 新支持scope:支持传入多个scope权限,用逗号分隔
	public static final String SCOPE = "email,direct_messages_read,direct_messages_write,"
			+ "friendships_groups_read,friendships_groups_write,statuses_to_me_read,"
			+ "follow_app_official_microblog," + "invitation_write";

	public static final String CLIENT_ID = "client_id";
	public static final String RESPONSE_TYPE = "response_type";
	public static final String USER_REDIRECT_URL = "redirect_uri";
	public static final String DISPLAY = "display";
	public static final String USER_SCOPE = "scope";
	public static final String PACKAGE_NAME = "packagename";
	public static final String KEY_HASH = "key_hash";
}

【MainActivity.java】

import java.text.SimpleDateFormat;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;

import com.weibo.sdk.android.Oauth2AccessToken;
import com.weibo.sdk.android.Weibo;
import com.weibo.sdk.android.WeiboAuthListener;
import com.weibo.sdk.android.WeiboDialogError;
import com.weibo.sdk.android.WeiboException;
import com.weibo.sdk.android.sso.SsoHandler;
import com.weibo.sdk.android.util.AccessTokenKeeper;

public class MainActivity extends Activity {

	/** 显示认证后的信息,如AccessToken */
	private TextView mText;

	/** 微博API接口类,提供登陆等功能 */
	private Weibo mWeibo;

	/** 封装了 "access_token","expires_in","refresh_token",并提供了他们的管理功能 */
	private Oauth2AccessToken mAccessToken;

	/** 注意:SsoHandler 仅当sdk支持sso时有效 */
	private SsoHandler mSsoHandler;
	private Intent intent;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		mText = (TextView) findViewById(R.id.show);

		mWeibo = Weibo.getInstance(ConstantS.APP_KEY, ConstantS.REDIRECT_URL,
				ConstantS.SCOPE);
		// 触发sso测试button
		findViewById(R.id.share).setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(getApplicationContext(),
						ShareActivity.class);
				intent.putExtra("id", R.id.share);
				startActivity(intent);
			}
		});
		// 触发sso测试button
		findViewById(R.id.sso).setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				mSsoHandler = new SsoHandler(MainActivity.this, mWeibo);
				mSsoHandler.authorize(new AuthDialogListener(), null);
			}
		});

		// 从 SharedPreferences 中读取上次已保存好 AccessToken 等信息,
		// 第一次启动本应用,AccessToken 不可用
		mAccessToken = AccessTokenKeeper.readAccessToken(this);
		if (mAccessToken.isSessionValid()) {
			String date = new java.text.SimpleDateFormat("yyyy/MM/dd hh:mm:ss")
					.format(new java.util.Date(mAccessToken.getExpiresTime()));
			mText.setText("access_token 仍在有效期内,无需再次登录: \naccess_token:"
					+ mAccessToken.getToken() + "\n有效期:" + date);

		} else {
			mText.setText("使用SSO登录前,请检查手机上是否已经安装新浪微博客户端,"
					+ "目前仅3.0.0及以上微博客户端版本支持SSO;如果未安装,将自动转为Oauth2.0进行认证");
		}
	}

	/**
	 * 微博认证授权回调类。 1. SSO登陆时,需要在{@link #onActivityResult}
	 * 中调用mSsoHandler.authorizeCallBack后, 该回调才会被执行。 2. 非SSO登陆时,当授权后,就会被执行。
	 * 当授权成功后,请保存该access_token、expires_in等信息到SharedPreferences中。
	 */
	class AuthDialogListener implements WeiboAuthListener {

		@Override
		public void onComplete(Bundle values) {

			String token = values.getString("access_token");
			String expires_in = values.getString("expires_in");
			mAccessToken = new Oauth2AccessToken(token, expires_in);
			if (mAccessToken.isSessionValid()) {
				String date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
						.format(new java.util.Date(mAccessToken
								.getExpiresTime()));
				mText.setText("认证成功: \r\n access_token: " + token + "\r\n"
						+ "expires_in: " + expires_in + "\r\n有效期:" + date);

				AccessTokenKeeper.keepAccessToken(MainActivity.this,
						mAccessToken);
				Toast.makeText(MainActivity.this, "认证成功", Toast.LENGTH_SHORT)
						.show();
			}
		}

		@Override
		public void onError(WeiboDialogError e) {
			Toast.makeText(getApplicationContext(),
					"Auth error : " + e.getMessage(), Toast.LENGTH_LONG).show();
		}

		@Override
		public void onCancel() {
			Toast.makeText(getApplicationContext(), "Auth cancel",
					Toast.LENGTH_LONG).show();
		}

		@Override
		public void onWeiboException(WeiboException e) {
			Toast.makeText(getApplicationContext(),
					"Auth exception : " + e.getMessage(), Toast.LENGTH_LONG)
					.show();
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

		// SSO 授权回调
		// 重要:发起 SSO 登陆的Activity必须重写onActivityResult
		if (mSsoHandler != null) {
			mSsoHandler.authorizeCallBack(requestCode, resultCode, data);
		}
	}

}

【ShareActivity.java】

import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.sina.weibo.sdk.WeiboSDK;
import com.sina.weibo.sdk.api.BaseResponse;
import com.sina.weibo.sdk.api.IWeiboAPI;
import com.sina.weibo.sdk.api.IWeiboHandler;
import com.sina.weibo.sdk.api.ImageObject;
import com.sina.weibo.sdk.api.SendMessageToWeiboRequest;
import com.sina.weibo.sdk.api.SendMultiMessageToWeiboRequest;
import com.sina.weibo.sdk.api.TextObject;
import com.sina.weibo.sdk.api.WeiboMessage;
import com.sina.weibo.sdk.api.WeiboMultiMessage;

/**
 * 该Activity演示了第三方应用如何发送请求消息给微博客户端。发送的内容包括文字、图片、视频、音乐等。 执行流程: 从本应用->微博->本应用
 */
public class ShareActivity extends Activity implements OnClickListener,
		IWeiboHandler.Response {

	/** 微博OpenAPI访问入口 */
	IWeiboAPI mWeiboAPI = null;

	// UI元素列表
	/** 分享文本 */
	private TextView mTitle;

	/** 分享图片 */
	private ImageView mImage;

	/** 分享按钮 */
	private Button mSharedBtn;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.share);
		initViews();

		// 创建微博对外接口实例
		mWeiboAPI = WeiboSDK.createWeiboAPI(this, ConstantS.APP_KEY);
		mWeiboAPI.responseListener(getIntent(), this);
	}

	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		mWeiboAPI.responseListener(intent, this);
	}

	/**
	 * 从本应用->微博->本应用 接收响应数据,该方法被调用。 注意:确保{@link #onCreate(Bundle)} 与
	 * {@link #onNewIntent(Intent)}中, 调用 mWeiboAPI.responseListener(intent,
	 * this)
	 */
	@Override
	public void onResponse(BaseResponse baseResp) {
		switch (baseResp.errCode) {
		case com.sina.weibo.sdk.constant.Constants.ErrorCode.ERR_OK:
			Toast.makeText(this, "成功!!", Toast.LENGTH_LONG).show();
			break;
		case com.sina.weibo.sdk.constant.Constants.ErrorCode.ERR_CANCEL:
			Toast.makeText(this, "用户取消!!", Toast.LENGTH_LONG).show();
			break;
		case com.sina.weibo.sdk.constant.Constants.ErrorCode.ERR_FAIL:
			Toast.makeText(this, baseResp.errMsg + ":失败!!", Toast.LENGTH_LONG)
					.show();
			break;
		}
	}

	/**
	 * 用户点击分享按钮,唤起微博客户端进行分享。
	 */
	@Override
	public void onClick(View v) {
		if (R.id.sharedBtn == v.getId()) {
			mWeiboAPI.registerApp();
			reqMsg(true, true, false, false, false, false);
		}
	}

	private void initViews() {

		mSharedBtn = (Button) findViewById(R.id.sharedBtn);
		mSharedBtn.setOnClickListener(this);

		mTitle = (TextView) findViewById(R.id.titleText);
		mImage = (ImageView) findViewById(R.id.image);

	}

	private void reqMsg(boolean hasText, boolean hasImage, boolean hasWebpage,
			boolean hasMusic, boolean hasVedio, boolean hasVoice) {

		if (mWeiboAPI.isWeiboAppSupportAPI()) {
			Toast.makeText(this, "当前微博版本支持SDK分享", Toast.LENGTH_SHORT).show();

			int supportApi = mWeiboAPI.getWeiboAppSupportAPI();
			if (supportApi >= 10351) {
				Toast.makeText(this, "当前微博版本支持多条消息,Voice消息分享",
						Toast.LENGTH_SHORT).show();
				reqMultiMsg(hasText, hasImage, hasWebpage, hasMusic, hasVedio,
						hasVoice);
			} else {
				Toast.makeText(this, "当前微博版本只支持单条消息分享", Toast.LENGTH_SHORT)
						.show();
				reqSingleMsg(hasText, hasImage, hasWebpage, hasMusic, hasVedio/*
																			 * ,
																			 * hasVoice
																			 */);
			}
		} else {
			Toast.makeText(this, "当前微博版本不支持SDK分享", Toast.LENGTH_SHORT).show();
		}
	}

	/**
	 * 第三方应用发送请求消息到微博,唤起微博分享界面。 注意:当isWeiboAppSupportAPI() >= 10351
	 * 时,支持同时分享多条消息, 同时可以分享文本、图片以及其它媒体资源(网页、音乐、视频、声音中的一种), 并且支持Voice消息。
	 * 
	 * @param hasText
	 *            分享的内容是否有文本
	 * @param hasImage
	 *            分享的内容是否有图片
	 * @param hasWebpage
	 *            分享的内容是否有网页
	 * @param hasMusic
	 *            分享的内容是否有音乐
	 * @param hasVideo
	 *            分享的内容是否有视频
	 * @param hasVoice
	 *            分享的内容是否有声音
	 */
	private void reqMultiMsg(boolean hasText, boolean hasImage,
			boolean hasWebpage, boolean hasMusic, boolean hasVideo,
			boolean hasVoice) {

		// 1. 初始化微博的分享消息
		WeiboMultiMessage weiboMessage = new WeiboMultiMessage();
		if (hasText) {
			weiboMessage.textObject = getTextObj();
		}

		if (hasImage) {
			weiboMessage.imageObject = getImageObj();
		}

		// 2. 初始化从第三方到微博的消息请求
		SendMultiMessageToWeiboRequest req = new SendMultiMessageToWeiboRequest();
		// 用transaction唯一标识一个请求
		req.transaction = String.valueOf(System.currentTimeMillis());
		req.multiMessage = weiboMessage;

		// 3. 发送请求消息到微博,唤起微博分享界面
		mWeiboAPI.sendRequest(this, req);
	}

	/**
	 * 第三方应用发送请求消息到微博,唤起微博分享界面。 当isWeiboAppSupportAPI() < 10351 只支持分享单条消息,即
	 * 文本、图片、网页、音乐、视频中的一种,不支持Voice消息。
	 * 
	 * @param hasText
	 *            分享的内容是否有文本
	 * @param hasImage
	 *            分享的内容是否有图片
	 * @param hasWebpage
	 *            分享的内容是否有网页
	 * @param hasMusic
	 *            分享的内容是否有音乐
	 * @param hasVideo
	 *            分享的内容是否有视频
	 */
	private void reqSingleMsg(boolean hasText, boolean hasImage,
			boolean hasWebpage, boolean hasMusic, boolean hasVideo/*
																 * , boolean
																 * hasVoice
																 */) {

		// 1. 初始化微博的分享消息
		// 用户可以分享文本、图片、网页、音乐、视频中的一种
		WeiboMessage weiboMessage = new WeiboMessage();
		if (hasText) {
			weiboMessage.mediaObject = getTextObj();
		}
		if (hasImage) {
			weiboMessage.mediaObject = getImageObj();
		}

		// 2. 初始化从第三方到微博的消息请求
		SendMessageToWeiboRequest req = new SendMessageToWeiboRequest();
		// 用transaction唯一标识一个请求
		req.transaction = String.valueOf(System.currentTimeMillis());
		req.message = weiboMessage;

		// 3. 发送请求消息到微博,唤起微博分享界面
		mWeiboAPI.sendRequest(this, req);
	}

	/**
	 * 文本消息构造方法。
	 * 
	 * @return 文本消息对象。
	 */
	private TextObject getTextObj() {
		TextObject textObject = new TextObject();
		textObject.text = mTitle.getText().toString();
		return textObject;
	}

	/**
	 * 图片消息构造方法。
	 * 
	 * @return 图片消息对象。
	 */
	private ImageObject getImageObj() {
		ImageObject imageObject = new ImageObject();
		BitmapDrawable bitmapDrawable = (BitmapDrawable) mImage.getDrawable();
		imageObject.setImageObject(bitmapDrawable.getBitmap());
		return imageObject;
	}

}

完整代码下载===》》》 weibo.sdk.android.demo.zip


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
数据库 iis7站长之家
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3