也學微博開發(四)-----保存認證信息、菜單欄和微博首頁


      前言

      好些天沒更新博客,這些天一直忙着研究教程和然后被一些知識點困住了,今天總算繼歡迎界面,認證登錄之后實現了,底部菜單欄和微博首頁簡單效果,並且保存認證后的accesstoken信息,避免每次都重復認證。

個人覺得要完成這節的內容,以下知識點學認真學習一下: 

  1.菜單欄用哪種方式,tabhost是怎么回事?

  2.layout布局,包括組件擺放和使用xml實現“切換效果”如單擊“按鈕”前后的樣式變化等

  3.sina SDK的版本,使用那個直接影響那些文件需要自己新建,各種對象的使用。

  4.理解微博里面的一些對象,如weibo,user,status,accesstoken,等等,

  5.listview和Adapter問題

  6.理清思路和流程,包括何時認證登錄、在哪里保存信息,對象是創建還是獲得實例引用。

先看效果圖:

 

  實現操作

     在研究和網上眾多版本的新浪微博和svn得來的源碼后,把自己的微博開發都搞昏了,一度不知道下一步到底怎么弄,實踐告訴我,沒有事先理清楚框架是多么可怕的事情。

雖然現在簡單實現了一些功能,但是結構不是很好,很多地方可以在此優化;

     一、初次認證后保存AccessToken

     關於保存認證信息很簡單,我用的是SharedPreferences把認證得到的AccessToken對象里的token和secret保存起來,下面的getAccessTokenFirst() 方法是我自定義的,用來產生AccessToken(取得requesttoken在前面已經實現,不再此函數)並且保存起來:

private void getAccessTokenFirst() throws Throwable
{
Uri uri = this.getIntent().getData();
String oauth_verifier = uri.getQueryParameter("oauth_verifier");
MainService.mWeibo.addOauthverifier(oauth_verifier);
// 得到AccessToken的同時在generateAccessToken()函數內部已經賦值給weibo了
MainService.mWeibo.generateAccessToken(this, null);

SharedPreferences preferences = getSharedPreferences("UserAuthInfor", Context.MODE_PRIVATE);
Editor editor = preferences.edit();
// 通過Editor 的方法向參數文件寫入內容
editor.putString("access_token_token", MainService.mWeibo.getAccessToken().getToken());
editor.putString("access_token_secret", MainService.mWeibo.getAccessToken().getSecret());
// 插入后一定要提交,才能完成保存

editor.commit();
}

 

既然第一次認證了,以后使用客戶端就可以免登錄(有效期內免登錄),可以在之前取得requesttoken時先判斷有無必要,具體思路是,從本地取出SharedPreferences保存的內容,如果已經認證過,那么一定可以取到不為空的token和secret,否者說明第一次使用,就去認證:

    if (CheckAccessToken() != null)
{
Log.i(TAG, "---------CheckAccessToken() != null");
MainService.mWeibo.setAccessToken(CheckAccessToken());
Log.i(TAG, "token:" + MainService.mWeibo.getAccessToken().getToken() + "-------secret:"
+ MainService.mWeibo.getAccessToken().getSecret());
Intent it = new Intent(AuthorizeActivity.this, MainActivity.class);
startActivity(it);
finish();

} else
{
Log.i(TAG, "---------AuthorizeNow()");
setContentView(R.layout.main);
AuthorizeNow();

}


這段代碼里面CheckAccessToken() 就是檢查有無認證信息的,返回值是AccessToken或null:

     // 檢查SharedPreferences里是否有授權信息
public AccessToken CheckAccessToken()
{
AccessToken accessToken = null;
SharedPreferences preferences = getSharedPreferences("UserAuthInfor", Context.MODE_PRIVATE);
String token = preferences.getString("access_token_token", null);
String secret = preferences.getString("access_token_secret", null);
if (token == null || secret == null)
{
accessToken = null;
} else
{
accessToken = new AccessToken(token, secret);
}
return accessToken;
}

 

AuthorizeNow()當然就是去認證了,跳轉到sina的認證頁面共用戶輸入密碼和用戶名:

    public void AuthorizeNow()
{
this.oauthNote = (TextView) this.findViewById(R.id.tvToken);
this.oauthBtn = (Button) this.findViewById(R.id.loginButton);
this.oauthBtn.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
if (v == oauthBtn)
{
MainService.mWeibo = Weibo.getInstance();
MainService.mWeibo.setupConsumerConfig(CONSUMER_KEY, CONSUMER_SECRET);
try
{
RequestToken requestToken = MainService.mWeibo.getRequestToken(
AuthorizeActivity.this, Weibo.APP_KEY, Weibo.APP_SECRET,
AuthorizeActivity.URL_ACTIVITY_CALLBACK);
oauthNote.setText(requestToken.getToken());
Uri uri = Uri.parse(Weibo.URL_AUTHENTICATION
+ "?display=wap2.0&oauth_token=" + requestToken.getToken()
+ "&from=" + AuthorizeActivity.FROM);
Log.i(TAG, "---------jump to browser for AUTHENTICATION");
startActivity(new Intent(Intent.ACTION_VIEW, uri));
finish();
} catch (WeiboException e)
{
e.printStackTrace();
}
}
}
});
}

 

     二、實現菜單欄

      這個還是比較繁復的,本人也叫不清楚,最好先看看api文檔里的TabHost那些內容,它自帶的案例比較清楚,我這的實現就是從那改過來的。先上代碼:

        Resources res = getResources();
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent;
// 主頁
intent = new Intent().setClass(this, HomePageActivity.class);
spec = tabHost.newTabSpec("homepage")
.setIndicator("主頁", res.getDrawable(R.drawable.icon_1)).setContent(intent);
tabHost.addTab(spec);
// 信息
intent = new Intent().setClass(this, MSGActivity.class);
spec = tabHost.newTabSpec("msg").setIndicator("信息", res.getDrawable(R.drawable.icon_2))
.setContent(intent);
tabHost.addTab(spec);
// 我的資料
intent = new Intent().setClass(this, UserInfoActivity.class);
spec = tabHost.newTabSpec("2").setIndicator("我的資料", res.getDrawable(R.drawable.icon_3))
.setContent(intent);
tabHost.addTab(spec);
// 搜索
intent = new Intent().setClass(this, SearchActivity.class);
spec = tabHost.newTabSpec("3").setIndicator("搜索", res.getDrawable(R.drawable.icon_4))
.setContent(intent);
tabHost.addTab(spec);

// 更多
intent = new Intent().setClass(this, MoreItemsActivity.class);
spec = tabHost.newTabSpec("3").setIndicator("更多", res.getDrawable(R.drawable.icon_5))
.setContent(intent);
tabHost.addTab(spec);
// 顯示主頁
tabHost.setCurrentTab(0);


 

上面簡單的就是為菜單的每個條目都設置了一個Activity,他們需要新建出來,比如第一個HomePageActivity就是我的微博主頁Activity,這里Activity的跳轉沒有使用button。需要布局文件就不提了,官方案例直接拿來用修改一下。

     三、首頁顯示好友說說

      頭像功能還沒完善,現在只簡單顯示關注對象的“昵稱”+“內容”。這里是在首頁HomePageActivity里的代碼,用到了listview綁定adapter。

public ListView allStatus;

//MyAdapter 是自定義的adapter繼承父類BaseAdapter

MyAdapter ma = new MyAdapter(this, status);
Log.i(TAG, "---------new MyAdapter(this, status);");
allStatus.setAdapter(ma);
Log.i(TAG, "---------allStatus.setAdapter(ma);");


 

關鍵不再與這里的綁定,MyAdapter 類的實現才是重點,本人代碼出錯調試基本上都是這里的問題,重寫一下getView()方法,在里面綁定用作listview每個item的樣式文件。

 

      
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View statusView = null;
if ((convertView != null) && (convertView.findViewById(R.id.ivItemPortrait) != null))
{
Log.d("listview", "do getView " + position + " getOldTextView");
// 獲取原來內存中保存的條目信息
statusView = convertView;
} else
{
Log.d("listview", "do getView " + position + " newTextView");
statusView = LayoutInflater.from(context).inflate(R.layout.itemview, null);
Log.d("listview", "after do getView " + position + " newTextView");
}

// 設定這個條目顯示的內容
ViewHolder holder = null;
holder = new ViewHolder();
// holder.ivItemPortrait = (ImageView)
// statusView.findViewById(R.id.ivItemPortrait);
holder.tvItemName = (TextView) statusView.findViewById(R.id.tvItemName);
holder.tvItemContent = (TextView) statusView.findViewById(R.id.tvItemContent);
// 設定昵稱
holder.tvItemName.setText(alls.get(position).getUser().getName());
// 設定內容
com.aven.util.TextAutoLink.addURLSpan(alls.get(position).getText(),
holder.tvItemContent);
// 更新頭像

return statusView;
}

 

     四、注意點

     我的代碼主要框架呢大概就是這樣,這里面關於設定昵稱要注意,從服務器獲得json數據后解析出來,封裝到status對相集合里面,這個status有的SDK里面已經定義好了比如weibo4j和weibo4jAndroid,但是weibo_sdk_source_code_0713卻沒有,甚至連很多基本的類都沒有,所以說選SDk也是很重要的(對於沒什么經驗的初學者而言),本人就是開始的時候用了weibo_sdk_source_code_0713,現在搞的很麻煩,因為教程啊,資料啊都不是這個版本的。

還有就是關於菜單欄丟失的問題,在切換不同Activity時,有時候下面的菜單會不見了,這個經過百度,在兩個地方有可以參考,一個是sina博客里面,有個人總結兩種方法,我是看了她博文才解決的,還有就是博客園的“農民伯伯”這位大牛的文章有園友問過,我看了下有點類似,也向他請教了,但是不知道現在回復了沒有。

    小結

   做到這sina微博客戶端的模子已經出來啦,剩下的是完善其他頁面,以及圖片顯示,代碼優化了。文章里面又不對的地方還請各位園友指出,不吝賜教,歡迎交流。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM