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微博客户端的模子已经出来啦,剩下的是完善其他页面,以及图片显示,代码优化了。文章里面又不对的地方还请各位园友指出,不吝赐教,欢迎交流。

  • 相关阅读:
    【Java】说明变量作用域的示例程序
    【Java】编写Java GUI应用程序,完成从键盘输入矩形的长和宽,求矩形的周长和面积并输出结果的功能
    【Java】编写Java应用程序,完成从键盘输入圆的半径,求圆的周长和面积并输出结果的功能
    【Java】编写Java程序,完成从键盘输入两个运算数据,计算两数之和并输出结果
    【Java】我的第一个 JAVA 程序:Hello,world!
    【Python爬虫】Scrapy爬虫框架
    【Python爬虫】存储格式化数据
    【Python爬虫】一个简单的网络爬虫
    【Python爬虫】用CSS 选择器提取网页数据
    git使用-克隆仓库
  • 原文地址:https://www.cnblogs.com/avenwu/p/2337588.html
Copyright © 2011-2022 走看看