zoukankan      html  css  js  c++  java
  • 也学微博开发(四)保存认证信息、菜单栏和微博首页

          前言

          好些天没更新博客,这些天一直忙着研究教程和然后被一些知识点困住了,今天总算继欢迎界面,认证登录之后实现了,底部菜单栏和微博首页简单效果,并且保存认证后的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微博客户端的模子已经出来啦,剩下的是完善其他页面,以及图片显示,代码优化了。文章里面又不对的地方还请各位园友指出,不吝赐教,欢迎交流。

  • 相关阅读:
    bzoj1015星球大战(并查集+离线)
    bzoj1085骑士精神(搜索)
    bzoj1051受欢迎的牛(Tarjan)
    左偏树学习
    hdu1512 Monkey King(并查集,左偏堆)
    左偏树(模板)
    PAT (Basic Level) Practice (中文) 1079 延迟的回文数 (20分) (大数加法)
    PAT (Basic Level) Practice (中文) 1078 字符串压缩与解压 (20分) (字符转数字——栈存放)
    PAT (Basic Level) Practice (中文) 1077 互评成绩计算 (20分) (四舍五入保留整数)
    PAT (Basic Level) Practice (中文) 1076 Wifi密码 (15分)
  • 原文地址:https://www.cnblogs.com/avenwu/p/2337588.html
Copyright © 2011-2022 走看看