首页 > 代码库 > Android 编程之第三方开发 MaoZhuaWeiBo微博开发示例-1

Android 编程之第三方开发 MaoZhuaWeiBo微博开发示例-1

在大学期间我做过很多类似这样的APP,这个是我们小组之前做的,我后期加入很多新元素,完善了这个应用,因为为了加强

专业技术嘛,也是经常熬夜写些小东西,嘿嘿,不过还算不错,起码技术长进了不少嘛,还是很欣慰的,今天给大家说说腾讯

微博第三方拓展客户端开发,说白了就是调用第三方接口的开放平台进行二次开发,跟微信有些类似吧,好了,不扯了,马上

进入正题吧

开发前准备:

① 腾讯QQ号(相信大家都有)     ②腾讯微博 App key (申请地址:http://dev.t.qq.com/)  ③API地址:http://wiki.open.t.qq.com/index.php/API%E6%96%87%E6%A1%A3

可能有些人会问,为什么不用新浪微博开发呢? 我就这么说吧,新浪的审核超慢。。。等审核下来,估计咱们早就写完了


然后就开始着手我们的微博撰写了,把主要的架子搭好,我个人感觉先功能在UI比较好,因为UI后写的话,可以相对减少工作量,因为主要核心还是在功能,而UI是给用户不同的视觉体验吧


创建好Project之后,先给咱们的清单文件xml加载权限代码:

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

接下来就是应用程序启动Activity,LoginActivity

package com.neweriweibo.activity;
/**
 * 登录
 * @author Engineer-Jsp
 * @date 2014.10.29*/
import java.util.ArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import com.neweriweibo.MainActivity;
import com.neweriweibo.R;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

public class LoginActivity extends Activity {

	private int[] mimageIds;
	private String[] titles;
	private ArrayList<ImageView> mimage;
	private ViewPager mvp;
	private MyAdapter madapter;
	private TextView mtitle;
	private ArrayList<View> mdots;
	private int oldPosition = 0; // 记录上一次点的位置	private int currentItem; // 当前页面

	@Override
	protected void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		setContentView(R.layout.fristpager);

		
		getActionBar().hide();
		// 图片
		mimageIds = new int[] { R.drawable.aa, R.drawable.bb, R.drawable.cc,
				R.drawable.dd, };
		// 图标标题
		titles = new String[] { "随时随地分享你的信息", "不要一个人说话!", "不要默默的去快乐",
				"让世界聆听你的心声" };

		mimage = new ArrayList<ImageView>();
		for (int i = 0; i < mimageIds.length; i++) {
			ImageView imageview = new ImageView(this);
			imageview.setBackgroundResource(mimageIds[i]);

			mimage.add(imageview);
		}

		mdots = new ArrayList<View>();

		mdots.add(findViewById(R.id.dot_0));
		mdots.add(findViewById(R.id.dot_1));
		mdots.add(findViewById(R.id.dot_2));
		mdots.add(findViewById(R.id.dot_3));

		mtitle = (TextView) findViewById(R.id.title);

		mtitle.setText(titles[0]);

		mvp = (ViewPager) findViewById(R.id.vp);

		madapter = new MyAdapter();
		mvp.setAdapter(madapter);

		mvp.setOnPageChangeListener(new OnPageChangeListener() {

			@Override
			public void onPageSelected(int position) {

				mtitle.setText(titles[position]);

				mdots.get(oldPosition).setBackgroundResource(
						R.drawable.dot_normarl);
				mdots.get(position).setBackgroundResource(
						R.drawable.dot_focused);
				oldPosition = position;
				// 记录下当前界面的位置:(线程的使用)
				currentItem = position;
			}

			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {

			}

			@Override
			public void onPageScrollStateChanged(int arg0) {

			}
		});
	}

	class MyAdapter extends PagerAdapter {

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

		/* 判断是否是同一张图片 */
		@Override
		public boolean isViewFromObject(View arg0, Object arg1) {

			return arg0 == arg1;
		}

		@Override
		public Object instantiateItem(ViewGroup view, int position) {

			view.addView(mimage.get(position));
			return mimage.get(position);

		}

		@Override
		public void destroyItem(ViewGroup view, int position, Object object) {

			// super.destroyItem(container, position, object);
			view.removeView(mimage.get(position));
			// view.removeViewAt(position);
		}
	}

	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		super.onStart();
		// 线程池
		ScheduledExecutorService sched = Executors
				.newSingleThreadScheduledExecutor();
		sched.scheduleWithFixedDelay(new ViewPagerTask(), 3, 3,
				TimeUnit.SECONDS);
	}

	/* 任务切换图片 */
	private class ViewPagerTask implements Runnable {

		@Override
		public void run() {

			currentItem = (currentItem + 1) % mimageIds.length;
			// 更新界面
			handler.obtainMessage().sendToTarget();
		}

	}

	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			mvp.setCurrentItem(currentItem);
		};
	};

	@Override
	protected void onStop() {

		super.onStop();
	}
	
	/*
	 * 进入微博主页或者验证授权
	 */
	 public void login(View v){
		 //首选项抓凭证
		 String access_token = PreferenceManager.getDefaultSharedPreferences(this).getString("access_token", null) ;
		 
		 if(null!=access_token){
			 // 不为空intent至主页
			 startActivity(new Intent(LoginActivity.this,MainActivity.class));
		 }else{
			 // 空至授权界面
			 startActivity(new Intent(LoginActivity.this,OAuthActivity.class));
		 }
	 }

	
	

}

因为我的IU写得太渣。。。布局文件就。。。,有兴趣的话还是看源码吧,讲完这个APP之后将会贴上来

下面说说凭证抓取的各自结果截图,代码:

抓取成功:

package com.neweriweibo;
/**
 * 主活动
 * @author Engineer-Jsp
 * @date 2014.10.28
 * */
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import com.neweriweibo.activity.SendMessageActivity;
import com.neweriweibo.adapter.MessageAdapter;
import com.neweriweibo.model.User;
import com.neweriweibo.model.UserWeiBiInfo;
import com.neweriweibo.service.UserService;
import com.squareup.picasso.Picasso;
import android.app.ActionBar;
import android.app.ActionBar.OnNavigationListener;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SpinnerAdapter;
import android.widget.TextView;

public class MainActivity extends Activity  implements OnClickListener,OnNavigationListener{


	public static String [] data;
	private ShouYeFragment shouyeFragment ;
	private MessageFragment messageFragment ;
	private UserFragment userFragment ;
	private SeacherFragment seacherFragment ;
	
    private View mfristLayout ;
	private View mmessageLayout ;
	private View muserLayout ;
	private View msousuoLayout ;
	
	private ImageView shouyeImage ; 
	private ImageView messageImage ;
	private ImageView userImage ;
	private ImageView sousuoImage ;
	private FragmentManager mfragmentManager ;
	
	private SpinnerAdapter spinnerAdapter;
	private List<String> dropData = http://www.mamicode.com/null ;>
结果图,个人信息界面,网络抓取,解析,没有网络时,保存了最后一次动态的数据在本地:



数据都是来自腾讯服务器的,不是本地的,首页界面:



这个GridView我还没有做任何拓展,不过我前面说到的的天气预报和文件管理器可以嵌入进来,可以解决掉一半,有兴趣的可以继续写下去,还有附近功能,我有时间会把它写了,贴出来,供大家学习


凭证抓取失败的结果,跳转至授权界面,授权成功,信息保存至首选项:

package com.neweriweibo.activity;
/**
 * 授权
 * @author Engineer-Jsp
 * @date 2014.10.28
 * */
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;

import com.neweriweibo.R;
import com.neweriweibo.MainActivity;
import com.neweriweibo.R.id;
import com.neweriweibo.R.layout;
import com.neweriweibo.utils.TencentAPI;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class OAuthActivity extends Activity {
	
	private static final String TAG = "float" ;
	private WebView webView;

	@SuppressLint("SetJavaScriptEnabled")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		setContentView(R.layout.login_load);
		webView = (WebView) findViewById(R.id.webview);  
		WebSettings webSetting = webView.getSettings() ;   //获取设置对象
		webSetting.setJavaScriptEnabled(true);      //设置WebView 支持JavaScript
	
		webView.setWebViewClient(mClient);
		
		/**
		 * BasicNameValuePair实现了NameValuePair接口  :
		 *     String getName();
         *     String getValue();
		 */
		List<BasicNameValuePair> _list  = new ArrayList<BasicNameValuePair>() ;
		
		_list.add(new BasicNameValuePair("client_id",TencentAPI.client_id)) ;
		_list.add(new BasicNameValuePair("redirect_uri",TencentAPI.redirectUri)) ;
		_list.add(new BasicNameValuePair("response_type",TencentAPI.response_type)) ;
		
		String param = URLEncodedUtils.format(_list, "utf-8") ;
		
		webView.loadUrl(TencentAPI.url + "?" +param) ;          //加载授权登入界面
		Log.d("授权地址:", TencentAPI.url+"?"+param);
		
	}
	//:主要实现:获取access_token :access_token=789a7d5284d0c3e608f8e384c993d04b (授权码)
	private WebViewClient mClient = new WebViewClient(){
		
		public void onPageStarted(WebView view, String url, android.graphics.Bitmap favicon) {
			Log.i("打印授权地址:", url) ;
			
			/*
			 *  http://www.newer.com/#access_token=789a7d5284d0c3e608f8e384c993d04b&expires_in=8035200&openid=0027BC08DB5B45D7461E9A0F16F527E7&openkey=60A1DF40C01EE30537AF7739504DFDB0&refresh_token=5c768f8850ae5af2193ce79f3f0a1351&state=&name=cfloat656805&nick=Cfloat
			 *  完成之后会在你该应用的网址上返回授权服务器重定向浏览器到第三方应用的回调url(redirect_uri),
			 *  并附上code,openid和openkey等参数
			 *  http://www.newer.com/
			 *  #access_token=789a7d5284d0c3e608f8e384c993d04b
			 *  &expires_in=8035200
			 *  &openid=0027BC08DB5B45D7461E9A0F16F527E7
			 *  &openkey=60A1DF40C01EE30537AF7739504DFDB0
			 *  &refresh_token=5c768f8850ae5af2193ce79f3f0a1351
			 *  &state=
			 *  &name=cfloat656805
			 *  &nick=Cfloat
			 */
			if(url.startsWith(TencentAPI.redirectUri)){             //判断回调的Url前缀是否是你授权时给的url地址
				
				
				/*截取:access_token=789a7d5284d0c3e608f8e384c993d04b
				 *     &expires_in=8035200
				 *     &openid=0027BC08DB5B45D7461E9A0F16F527E7
				 *     &openkey=60A1DF40C01EE30537AF7739504DFDB0
				 *     &refresh_token=5c768f8850ae5af2193ce79f3f0a1351
				 *     &state=
				 *     &name=cfloat656805
				 *     &nick=Cfloat
				 */
				String text = url.substring(url.indexOf("#")+1) ;  
				String[] params = text.split("&") ;
				
				SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit() ;
				
				for(String str : params){
					Log.i("遍历正则取到的参数:", str+" ") ;
					
				   String[] KeyValue = http://www.mamicode.com/str.split("=") ;  //分割>
OK,前期的工作已经KO了,下面说说access_token凭证,他的有效时间是30天,如果出现key与凭证不匹配的情况下,可以卸载应用,或者将凭证刷新,即可解决失效与不匹配的问题了,好了,第一篇就到这吧!谢谢~~

Android 编程之第三方开发 MaoZhuaWeiBo微博开发示例-1