zoukankan      html  css  js  c++  java
  • [置顶] Android仿人人客户端(v5.7.1)——人人授权访问界面

    转载请标明出处:http://blog.csdn.net/android_ls/article/details/8725422
     声明:仿人人项目,所用所有图片资源都来源于官方人人android客户端,编写本应用的目的在于学习交流,如涉及侵权请告知,我会及时换掉用到的相关图片。

              以前在公司做Android应用(后面简称App)时的疑惑: 我只想实现用户可以用人人账号能登录我们的App,可以将自己在我们App中看到的,某些喜欢的内容分享给自己在人人上的朋友、同事和同学等。但是我又不想使用人人官方提供的SDK。理由:太大,有人可能要说,可以去掉没用到的类文件,我想说的是太费事了(我当时就这件事花了一天多时间);授权界面的Dialog觉得不美观,我自己得改。当时我就在想人人如果能提供一个小点的SDK只有我说的那两个功能就好了,欣赏大多数应用,里面用到人人提供的功能的就是我说的这两个。鉴于此,这次我不想使用人人提供的SDK(当然肯定会参考),所有功能自己编码实现,这对我来说是一个挑战,不过我喜欢这种有挑战的事。好了开始正题,这篇是在前面Android仿人人客户端(v5.7.1)——欢迎和导引界面的类图的基础上进行的,不明白可以查看下。

    一、类图如下:

    二、编码实现:

           1、布局文件:

                 a. 主布局文件(auth.xml)

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
        <com.everyone.android.widget.TopNavbar
            android:id="@+id/rl_top_navbar"
            android:layout_width="fill_parent"
            android:layout_height="50dip" />
    
        <WebView
            android:id="@+id/wv_auth"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />
    
    </LinearLayout>

                 b. 顶部工具栏(或者菜单栏)的布局文件(top_navbar.xml)

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        style="@style/top_navbar" >
    
        <LinearLayout
            android:id="@+id/ll_back"
            android:layout_width="60dip"
            android:layout_height="fill_parent"
            android:background="@drawable/v5_0_1_flipper_head_title_wrapper_background"
            android:gravity="center_vertical" >
    
            <ImageView
                android:id="@+id/iv_back"
                android:layout_width="25dip"
                android:layout_height="25dip"
                android:layout_marginLeft="15dip"
                android:src="@drawable/v5_0_1_flipper_head_back" />
        </LinearLayout>
    
        <ImageView
            android:id="@+id/iv_line_separator"
            android:layout_width="1dip"
            android:layout_height="25dip"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@+id/ll_back"
            android:background="@drawable/v5_0_1_flipper_head_separator" />
    
        <TextView
            android:id="@+id/tv_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="15dip"
            android:layout_toRightOf="@+id/iv_line_separator"
            android:text="人人授权访问"
            android:textColor="#FFFFFF"
            android:textSize="17dip"
            android:textStyle="bold" />
    
    </RelativeLayout>

           2、应用授权界面的具体实现:

                a. 初始组件:

      @Override
        protected void setupView() {
            mTopNavbar = (TopNavbar) findViewById(R.id.rl_top_navbar);
            mWebView = (WebView) findViewById(R.id.wv_auth);
            mWebView.setVerticalScrollBarEnabled(false);
            mWebView.setHorizontalScrollBarEnabled(false);
            mWebView.getSettings().setJavaScriptEnabled(true);
        }

                b. 组拼请求参数

        StringBuilder authorizeUrl = new StringBuilder(Constant.AUTHORIZE_URL);
            authorizeUrl.append("?");
            authorizeUrl.append("client_id=").append(Constant.API_KEY);
            authorizeUrl.append("&redirect_uri=").append(Constant.DEFAULT_REDIRECT_URI);
            authorizeUrl.append("&response_type=").append("token");
            authorizeUrl.append("&display=").append("touch");
            String scope = TextUtils.join(" ", Constant.HAVE_PERMISSIONS);
            authorizeUrl.append("&scope=").append(scope);
            Log.i(TAG, "authorizeUrl = " + authorizeUrl.toString());

               c. 使用WebView组件加载授权界面  

     mWebView.loadUrl(authorizeUrl.toString());
            
            // 以POST方式请求
            // mWebView.postUrl(Constant.AUTHORIZE_URL, EncodingUtils.getBytes(sb.toString(), "BASE64"));
            mWebView.setWebViewClient(new WebViewClient() {
    
                public boolean shouldOverrideUrlLoading(WebView webView, String url) {
                    Log.i(TAG, "shouldOverrideUrlLoading() Redirect URL = " + url);
    
                    if (url.startsWith(Constant.DEFAULT_REDIRECT_URI + "#error=login_denied")) {
                        AuthActivity.this.onBackPressed();
                    } else if(url.startsWith("http://graph.renren.com/oauth/login_success.html#access_token")) {
                        String accessToken = url.substring(url.indexOf("="), url.indexOf("&"));
                        Log.i(TAG, "accessToken = " + accessToken);
                        
                        AuthActivity.this.onBackPressed();
                        return false;
                    }
                    
                    webView.loadUrl(url);
                    return true;
                }
    
                public void onReceivedSslError(WebView view, SslErrorHandler handler, android.net.http.SslError errorCode) {
                    // 在默认情况下,通过loadUrl(String url)方法,可以顺利load。
                    // 但是,当load有ssl层的https页面时,如果这个网站的安全证书在Android无法得到认证,WebView就会变成一个空白页,
                    // 而并不会像PC浏览器中那样跳出一个风险提示框。因此,我们必须针对这种情况进行处理。(这个证书限于2.1版本以上的Android 系统才可以)
                    
                    // 默认的处理方式,WebView变成空白页
                    // handler.cancel(); 
                    
                    // 接受证书   
                    handler.proceed();
                }
    
                @Override
                public void onReceivedError(WebView view, int errorCode,
                        String description, String failingUrl) {
                    super.onReceivedError(view, errorCode, description, failingUrl);
                    AuthActivity.this.onBackPressed();
                }
    
                public void onPageStarted(WebView view, String url, Bitmap favicon) {
                    Log.i(TAG, "Webview loading URL: " + url);
                    super.onPageStarted(view, url, favicon);
                }
    
                public void onPageFinished(WebView view, String url) {
                    Log.i(TAG, "onPageFinished() url = " + url);
                    super.onPageFinished(view, url);
                }
            });

                     d. Back键事件处理

     @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                if (mWebView != null) {
                    mWebView.stopLoading();
                }
            }
            return super.onKeyDown(keyCode, event);
        }

            应用授权界面,完整代码:

    package com.everyone.android.ui;
    
    import android.graphics.Bitmap;
    import android.os.Bundle;
    import android.text.TextUtils;
    import android.util.Log;
    import android.view.KeyEvent;
    import android.view.View;
    import android.webkit.SslErrorHandler;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;
    
    import com.everyone.android.AppBaseActivity;
    import com.everyone.android.R;
    import com.everyone.android.utils.Constant;
    import com.everyone.android.widget.TopNavbar;
    
    /**
     * 功能描述:应用授权界面
     * @author android_ls
     */
    public class AuthActivity extends AppBaseActivity {
    
        /**
         * 打印Log的标签
         */
        private static final String TAG = "AuthActivity";
    
        private WebView mWebView;
    
        private TopNavbar mTopNavbar;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            // 顶部返回按钮事件处理
            mTopNavbar.llBack.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    onBackPressed();
                }
            });
            
        }
    
        @Override
        protected void setupView() {
            mTopNavbar = (TopNavbar) findViewById(R.id.rl_top_navbar);
            mWebView = (WebView) findViewById(R.id.wv_auth);
            mWebView.setVerticalScrollBarEnabled(false);
            mWebView.setHorizontalScrollBarEnabled(false);
            mWebView.getSettings().setJavaScriptEnabled(true);
        }
    
        @Override
        protected int getLayoutId() {
            return R.layout.auth;
        }
        
        @Override
        protected void initializedData() {
            // 组拼请求参数
            StringBuilder authorizeUrl = new StringBuilder(Constant.AUTHORIZE_URL);
            authorizeUrl.append("?");
            authorizeUrl.append("client_id=").append(Constant.API_KEY);
            authorizeUrl.append("&redirect_uri=").append(Constant.DEFAULT_REDIRECT_URI);
            authorizeUrl.append("&response_type=").append("token");
            authorizeUrl.append("&display=").append("touch");
            String scope = TextUtils.join(" ", Constant.HAVE_PERMISSIONS);
            authorizeUrl.append("&scope=").append(scope);
            Log.i(TAG, "authorizeUrl = " + authorizeUrl.toString());
            
            mWebView.loadUrl(authorizeUrl.toString());
            
            // 以POST方式请求
            // mWebView.postUrl(Constant.AUTHORIZE_URL, EncodingUtils.getBytes(sb.toString(), "BASE64"));
            mWebView.setWebViewClient(new WebViewClient() {
    
                public boolean shouldOverrideUrlLoading(WebView webView, String url) {
                    Log.i(TAG, "shouldOverrideUrlLoading() Redirect URL = " + url);
    
                    if (url.startsWith(Constant.DEFAULT_REDIRECT_URI + "#error=login_denied")) {
                        AuthActivity.this.onBackPressed();
                    } else if(url.startsWith("http://graph.renren.com/oauth/login_success.html#access_token")) {
                        String accessToken = url.substring(url.indexOf("="), url.indexOf("&"));
                        Log.i(TAG, "accessToken = " + accessToken);
                        
                        AuthActivity.this.onBackPressed();
                        return false;
                    }
                    
                    webView.loadUrl(url);
                    return true;
                }
    
                public void onReceivedSslError(WebView view, SslErrorHandler handler, android.net.http.SslError errorCode) {
                    // 在默认情况下,通过loadUrl(String url)方法,可以顺利load。
                    // 但是,当load有ssl层的https页面时,如果这个网站的安全证书在Android无法得到认证,WebView就会变成一个空白页,
                    // 而并不会像PC浏览器中那样跳出一个风险提示框。因此,我们必须针对这种情况进行处理。(这个证书限于2.1版本以上的Android 系统才可以)
                    
                    // 默认的处理方式,WebView变成空白页
                    // handler.cancel(); 
                    
                    // 接受证书   
                    handler.proceed();
                }
    
                @Override
                public void onReceivedError(WebView view, int errorCode,
                        String description, String failingUrl) {
                    super.onReceivedError(view, errorCode, description, failingUrl);
                    AuthActivity.this.onBackPressed();
                }
    
                public void onPageStarted(WebView view, String url, Bitmap favicon) {
                    Log.i(TAG, "Webview loading URL: " + url);
                    super.onPageStarted(view, url, favicon);
                }
    
                public void onPageFinished(WebView view, String url) {
                    Log.i(TAG, "onPageFinished() url = " + url);
                    super.onPageFinished(view, url);
                }
            });
        }
        
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                if (mWebView != null) {
                    mWebView.stopLoading();
                }
            }
            return super.onKeyDown(keyCode, event);
        }
        
    }

    TopNavbar类:

    package com.everyone.android.widget;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.widget.FrameLayout;
    import android.widget.LinearLayout;
    import android.widget.RelativeLayout;
    import android.widget.TextView;
    
    import com.everyone.android.R;
    
    /**
     * 功能描述:自定义顶部工具栏
     * @author android_ls
     * 创建日期:2013-03-26
     */
    public class TopNavbar extends FrameLayout {
    
        public TextView tvTitle;
    
        public LinearLayout llBack;
    
        public TopNavbar(Context context) {
            super(context);
            setupViews();
        }
    
        public TopNavbar(Context context, AttributeSet attrs) {
            super(context, attrs);
            setupViews();
        }
    
        private void setupViews() {
            final LayoutInflater mLayoutInflater = LayoutInflater.from(getContext());
            RelativeLayout rlTopNavbar = (RelativeLayout) mLayoutInflater.inflate(R.layout.top_navbar, null);
            addView(rlTopNavbar);
    
            llBack = (LinearLayout) rlTopNavbar.findViewById(R.id.ll_back);
            tvTitle = (TextView) rlTopNavbar.findViewById(R.id.tv_title);
        }
    
    }

    常量类:

    package com.everyone.android.utils;
    
    /**
     * 功能描述:常量类
     * @author android_ls
     */
    public class Constant {
    
        /**
         * 人人登录和授权的地址
         */
        public static final String AUTHORIZE_URL = "https://graph.renren.com/oauth/authorize";
    
        /**
         * 默认重定向URL
         */
        public static final String DEFAULT_REDIRECT_URI = "http://graph.renren.com/oauth/login_success.html";
        
        /**
         * 第三方应用所拥有的权限
         */
        public static final String[] HAVE_PERMISSIONS = { "publish_feed", "create_album", "photo_upload", "read_user_album", "status_update",
                "read_user_blog", "read_user_checkin", "read_user_feed", "read_user_guestbook", "read_user_invitation", "read_user_like_history",
                "read_user_message", "read_user_notification", "read_user_photo", "read_user_status", "read_user_comment", "read_user_share",
                "read_user_request", "publish_blog", "publish_checkin", "publish_feed", "publish_share", "write_guestbook", "send_invitation", 
                "send_request", "send_message", "send_notification", "photo_upload", "create_album", "publish_comment", "operate_like", "admin_page" };
        
        /**
         * API_KEY
         */
        public static final String API_KEY = "661ea1ba2d6b49859be197d77fe361f1";
    
        /**
         * Secret Key
         */
        public static final String SECRET_KEY = "a088d31cd5d341819bfc75ac0208b5e1";
    
        /**
         * 应用ID
         */
        public static final String APP_ID = "195789";
        
    }
    


    三、运行效果图:

  • 相关阅读:
    FreeCAD二次开发-makeChamfer创建倒角
    FreeCAD二次开发-makeFillet创建倒圆
    FreeCAD二次开发-Gui.Selection.getSelectionEx() 遍历选中的对象
    FreeCAD二次开发-Part.Ellipse创建椭圆
    FreeCAD二次开发-Part.makePolygon创建多边形
    FreeCAD二次开发-face.extrude创建拉伸
    FreeCAD二次开发-Part.Face创建面
    FreeCAD二次开发-Part.Shape合并几何元素,生成拓扑形状
    FreeCAD二次开发-Part.LineSegment创建直线
    FreeCAD二次开发-Part.Arc创建圆弧
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/2985476.html
Copyright © 2011-2022 走看看