Java tutorial
/* * Copyright (C) 2016 AdvancingPainters (https://github.com/AdvancingPainters). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.ap.github.ui.activitys; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.graphics.Bitmap; import android.os.Bundle; import android.support.v4.widget.SwipeRefreshLayout; import android.text.TextUtils; import android.view.View; import android.webkit.WebResourceError; import android.webkit.WebResourceRequest; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import com.ap.github.BuildConfig; import com.ap.github.R; import com.ap.github.base.BaseActivity; import com.ap.github.net.Api; import com.ap.github.ui.fragments.MainFragment; import com.ap.github.utils.AccessTokenUtils; import com.ap.github.utils.Constants; import com.ap.github.utils.SchedulersCompat; import com.ap.github.utils.StringUtils; import com.ap.github.utils.ToastUtils; import com.ap.github.utils.UserUtils; import java.lang.ref.WeakReference; import java.net.HttpURLConnection; import java.net.URL; import java.util.Map; import butterknife.Bind; import rx.Observable; import rx.Subscriber; /** * login activity * Created by Spencer on 5/18/16. */ public class LoginActivity extends BaseActivity implements SwipeRefreshLayout.OnRefreshListener { @Bind(R.id.loginWebView) WebView mLoginWebView; @Override protected boolean needRegisterEventBus() { return false; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (judgmentUserIsLogin()) { jumpToMain(); return; } setContentView(R.layout.activity_login); initView(); initLoginWebView(); loadLoginUrl(); } private boolean judgmentUserIsLogin() { return UserUtils.getInstance().getUserLoginStatus(); } public void jumpToMain() { MainFragment.startActivity(mContext); finish(); } private void initView() { setRefreshListener(this); } @SuppressLint("SetJavaScriptEnabled") private void initLoginWebView() { mLoginWebView.setVerticalScrollBarEnabled(false); mLoginWebView.setHorizontalScrollBarEnabled(false); mLoginWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); mLoginWebView.getSettings().setJavaScriptEnabled(true); mLoginWebView.setWebViewClient(new LoginWebViewClient(this)); WebSettings webSettings = mLoginWebView.getSettings(); webSettings.setUseWideViewPort(true); webSettings.setSupportZoom(false); webSettings.setBuiltInZoomControls(false); webSettings.setAllowFileAccess(true); webSettings.setJavaScriptCanOpenWindowsAutomatically(true); webSettings.setLoadsImagesAutomatically(true); } private void loadLoginUrl() { mLoginWebView.loadUrl(Constants.GitHubLogin.LOGIN_AUTH_URL); } private void getAccessTokenAndUserInfo(String code) { Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { try { URL url = new URL(Constants.GitHubLogin.LOGIN_TOKEN_URL(code)); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestMethod("GET"); urlConnection.setDoInput(true); urlConnection.setDoOutput(true); urlConnection.connect(); String response = StringUtils.inputStreamToString(urlConnection.getInputStream()); if (!StringUtils.containsParam(response, Constants.GitHubLogin.ACCESS_TOKEN)) { throw new IllegalArgumentException("response not contains access_token param"); } Map<String, String> params = StringUtils.getParamsOnUrl(response); String accessToken = params.get(Constants.GitHubLogin.ACCESS_TOKEN); if (TextUtils.isEmpty(accessToken)) { throw new NullPointerException("access token is null"); } subscriber.onNext(accessToken); } catch (Exception e) { subscriber.onError(e); } finally { subscriber.onCompleted(); } } }).flatMap(accessToken -> { AccessTokenUtils.initAccessToken(accessToken); return Api.USER_SERVICE.getCurrentUser(); }).compose(SchedulersCompat.applyIoSchedulers()).compose(bindToLifecycle()) .doOnSubscribe(this::showProgressBar).doOnTerminate(this::hideProgressBar) .doAfterTerminate(this::jumpToMain).subscribe(user -> { UserUtils.getInstance().saveUserInfo(user); }, throwable -> { ToastUtils.showToast(throwable.getMessage()); }); } @Override public void onRefresh() { loadLoginUrl(); } @Override protected void onDestroy() { super.onDestroy(); if (mLoginWebView != null) { mLoginWebView.destroy(); mLoginWebView = null; } } private static class LoginWebViewClient extends WebViewClient { private WeakReference<LoginActivity> loginActivityWeakReference; public LoginWebViewClient(LoginActivity loginActivity) { this.loginActivityWeakReference = new WeakReference<>(loginActivity); } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (!url.startsWith(BuildConfig.GITHUB_CALLBACK_URL)) { return false; } if (!StringUtils.containsParam(url, Constants.GitHubLogin.CODE)) { return false; } String code = StringUtils.getParamsOnUrl(url).get(Constants.GitHubLogin.CODE); if (TextUtils.isEmpty(code)) { return false; } final LoginActivity loginActivity = loginActivityWeakReference.get(); if (loginActivity != null) { loginActivity.getAccessTokenAndUserInfo(code); view.loadUrl(Constants.Common.SUCCESS_PAGE_URL); return true; } return super.shouldOverrideUrlLoading(view, url); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { final LoginActivity loginActivity = loginActivityWeakReference.get(); if (loginActivity != null) { loginActivity.showProgressBar(); } } @Override public void onPageFinished(WebView view, String url) { final LoginActivity loginActivity = loginActivityWeakReference.get(); if (loginActivity != null) { loginActivity.hideProgressBar(); } } @TargetApi(android.os.Build.VERSION_CODES.M) @Override public void onReceivedError(WebView view, WebResourceRequest req, WebResourceError rerr) { onReceivedError(view, rerr.getErrorCode(), rerr.getDescription().toString(), req.getUrl().toString()); } @SuppressWarnings("deprecation") @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { final LoginActivity loginActivity = loginActivityWeakReference.get(); if (loginActivity != null) { loginActivity.hideProgressBar(); } view.loadUrl(Constants.Common.ERROR_PAGE_URL); } } }