public class NetWorkCache extends RealmObject {
	public String sectionalexamscore1;
	public String sectionalexamscore2;
	public String timeTable;
	public String record;
	public String prize;
	public String histroyScore11;
	public String histroyScore12;
	public String histroyScore21;
	public String histroyScore22;
	public String histroyScore31;
	public String histroyScore32;
	public String calc;
	public String qanda;
	public String relatedlink;
} public class NotiSetting extends RealmObject {
	public String fcm_token;
	public boolean is_noti;
} public class Setting extends RealmObject {
	public boolean logined;
	public String token;
	public String nick;
	public String name;
	public String email;
	public String password;
	public String usr_group;
	public String classX;
	public String locale;
} public class DialogUtils {
	/**
	 * 得到自定义的progressDialog
	 * @param context
	 * @return
	 */
	public static Dialog createLoadingDialog(Context context) {
		LayoutInflater inflater = LayoutInflater.from(context);
		View v = inflater.inflate(R.layout.loading_dialog, null);        // 得到加载view
		ImageView spaceshipImage = (ImageView) v.findViewById(R.id.img);
		Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(context,R.anim.loading_animation); // 加载动画
		hyperspaceJumpAnimation.setInterpolator(new LinearInterpolator());
		spaceshipImage.startAnimation(hyperspaceJumpAnimation);             // 使用ImageView显示动画
		Dialog loadingDialog = new Dialog(context, R.style.loading_dialog); // 创建自定义样式dialog

		loadingDialog.setCancelable(false);// 不可以用"返回键"取消
		loadingDialog.setContentView(v);
		loadingDialog.setTitle("");

		Window dialogWindow = loadingDialog.getWindow();
		WindowManager.LayoutParams lp = dialogWindow.getAttributes();
		dialogWindow.setGravity(Gravity.CENTER);
		lp.width = (int)UnitConvert.Dp2Pixel(100,context); // 宽度
		lp.height = (int)UnitConvert.Dp2Pixel(100,context); // 高度
		dialogWindow.setAttributes(lp);
		return loadingDialog;
	}
} public abstract class MyCallBack<t> implements Callback<t> {

	private Context context;

	protected MyCallBack(Context mContext){
		context=mContext.getApplicationContext();
	}


	private void onError(Call<t> call,Response<t> response){
		Error error = ErrorUtils.parseError(response,context);
		ErrorUtils.logError(error);

		switch (error.code){
			case 103:
				break;
			case 500:
				break;
			case 501:
				break;
			case 100:
				break;
			case 102:
				break;
			default:
				ToastUtils.makeTextAndShow(context,error.message,Toast.LENGTH_LONG,Gravity.CENTER);
				break;
		}

		onErr(error,call);

	}



	@Override
	public void onResponse(Call<t> call, Response<t> response) {
		if(response.isSuccessful()){
			Log.d("OkHttp",response.raw().toString());
			onSuccess(response);
		}else{
			onError(call,response);
		}
	}

	@Override
	public void onFailure(Call<t> call, Throwable t) {
		Log.e("network error",t.getMessage());
		ToastUtils.makeTextAndShow(context,"網路錯誤或無網路",Toast.LENGTH_SHORT, Gravity.CENTER);
	}

	public abstract void onSuccess(Response<t> response);

	public abstract void onErr(Error error, Call<t> call);
} public class NetworkingClient {

    private AccountApi accountApi;
    private InforApi inforApi;
    private NewsApi newsApi;
	private MenuApi menuApi;


    public NetworkingClient(Context context) {
	    Retrofit retrofit = RetrofitClient.getInstance(context.getApplicationContext());

        accountApi = retrofit.create(AccountApi.class);
        inforApi = retrofit.create(InforApi.class);
        newsApi = retrofit.create(NewsApi.class);
	    menuApi = retrofit.create(MenuApi.class);
    }

    // Account System

	/*
        Author: IU(yoyo930021)
        Description:
            This function's purpose is to communicate with login api
        Usage:
            parameter:
                Login usr: login information
                Callback<Token> callback: Callback
     */
	public void login(Login login,Callback<Token> callback) {

		Call<Token> call = accountApi.login(login);
		call.enqueue(callback);
	}

    /*
        Author: Charles Lien( lienching),IU(yoyo930021)
        Description:
            This function's purpose is to communicate with login api
        Usage:
            parameter:
                Login usr: login information
                Callback<Token> callback: Callback
     */
    public void login() {
	    Realm realm = Realm.getDefaultInstance();
	    Setting setting = realm.where(Setting.class).findFirst();
	    Login usr = new Login();
	    usr.usr_account = setting.email;
	    usr.usr_password = setting.password;
        Call<Token> call = accountApi.login(usr);
	    String token = "";
	    try {
		    token = call.execute().body().token;
	    }catch (Exception e){}

	    realm.beginTransaction();
	    setting.token = token;
		realm.commitTransaction();
	    realm.close();
    }

    /*
        Author: Charles Lien( lienching),IU(yoyo930021)
        Description:
            This function's purpose is to communicate with register api
        Usage:
            parameter:
                Register register: register information
	            Callback<Token> callback: Callback

     */
    public void register(Register register,Callback<Token> callback) {
        Call<Token> call = accountApi.create(register);
        call.enqueue(callback);
    }

	/*
        Author: IU(yoyo930021)
        Description:
            This function's purpose is to communicate with checkAccount api
        Usage:
            parameter:


     */
	public void checkAccount(CheckRegist checkAccount, Callback<StatusResponse> callback) {
		Call<StatusResponse> call = accountApi.checkAccount(checkAccount);
		call.enqueue(callback);
	}

	/*
        Author: IU(yoyo930021)
        Description:
            This function's purpose is to communicate with checkNick api
        Usage:
            parameter:


     */
	public void checkNick(CheckRegist checkNick, Callback<StatusResponse> callback) {
		Call<StatusResponse> call = accountApi.checkNick(checkNick);
		call.enqueue(callback);
	}

	/*
        Author: IU(yoyo930021)
        Description:
            This function's purpose is to communicate with checkNick api
        Usage:
            parameter:


     */
	public void checkSchool(CheckRegist checkSchool, Callback<StatusResponse> callback) {
		Call<StatusResponse> call = accountApi.checkSchool(checkSchool);
		call.enqueue(callback);
	}

    /*
        Author: Charles Lien( lienching),IU(yoyo930021)
        Description:
            This function's purpose is to communicate with update api
        Usage:
            parameter:
                Update usr: update information
	            Callback<Object> callback: Callback
     */
    public void update(Update usr,Callback<StatusResponse> callback) {
	    Call<StatusResponse> call = accountApi.update(usr);
	    call.enqueue(callback);
    }

	/*
        Author: IU(yoyo930021)
        Description:
            This function's purpose is to communicate with get user's information api
        Usage:
            parameter:


     */
	public void getUserInfo(Callback<UserInfoResponse> callback) {
		Call<UserInfoResponse> call = accountApi.getUserInfo();
		call.enqueue(callback);
	}

	/*
        Author: IU(yoyo930021)
        Description:
            This function's purpose is to communicate with set noti info api
        Usage:
            parameter:


     */
	public void setNoti(String fcm_token,boolean is_noti,Callback<StatusResponse> callback) {
		Call<StatusResponse> call = accountApi.setNoti(fcm_token,is_noti);
		call.enqueue(callback);
	}



    // Infor System

	/*
        Author: IU(yoyo930021)
        Description:
            This function's purpose is to communicate with  api
        Usage:
            parameter:


     */
	public void queryTimeTable(Callback<TimeTableResponse> callback) {
		Call<TimeTableResponse> call = inforApi.getTimeTable();
		call.enqueue(callback);
	}

	/*
        Author: IU(yoyo930021)
        Description:
            This function's purpose is to communicate with  api
        Usage:
            parameter:


     */
	public void getABS(Callback<List<AbsentstateResponse>> callback) {
		Call<List<AbsentstateResponse>> call = inforApi.getABS();
		call.enqueue(callback);
	}


    /*
        Author: Charles Lien( lienching),IU(yoyo930021)
        Description:
            This function's purpose is to communicate with history score query api
        Usage:
            parameter:
                HistoryScore score : Query Information:
	            Callback<SectionalExamResponse> callback: Callback
     */
    public void queryHScore(int grade,int semester,Callback<List<HistoryScoreResponse>> callback) {
	    Call<List<HistoryScoreResponse>> call = inforApi.queryHScore(grade,semester);
        call.enqueue(callback);
    }


    /*
        Author: Charles Lien(lienching),IU(yoyo930021)
        Description:
            This function's purpose is to communicate with sectional exam score query api
        Usage:
            parameter:
                SectionalExamScore score : Query Information:
                Callback<SectionalExamResponse> callback: Callback
     */
    public void querySEScore(int semester,Callback<List<SectionalExamResponse>> callback) {
        Call<List<SectionalExamResponse>> call = inforApi.querySEScore(semester);
        call.enqueue(callback);
    }

    /*
       Author: Charles Lien(lienching),IU(yoyo930021)
       Description:
           This function's purpose is to communicate with attitude status query api
       Usage:
           parameter:
               SectionalExamScore score : Query Information:
	           Callback<List<AttitudeStatusResponse>> callback: Callback
    */
    public void getATS(Callback<AttitudeStatusResponse> callback) {
        Call<AttitudeStatusResponse> call = inforApi.getATS();
        call.enqueue(callback);
    }

    // Calender

    /*
      Author: Charles Lien(lienching),IU(yoyo930021)
      Description:
          This function's purpose is to communicate with calender query api
      Usage:
          parameter:
	          Callback<List<CalenderResponse>> callback: Callback
    */
    public void getCalender(Callback<List<CalenderResponse>> callback) {
        Call<List<CalenderResponse>> call = newsApi.getCalender();
        call.enqueue(callback);
    }

	/*
      Author: IU(yoyo930021)
      Description:
          This function's purpose is to communicate with Announce query api
      Usage:
          parameter:
              String sort : Query Information:
	          Callback<List<AnnounceResponse>> callback: Callback
    */
	public void getAnnounce(String sort,Callback<List<AnnounceResponse>> callback) {
		Call<List<AnnounceResponse>> call = newsApi.getAnnounce(sort);
		call.enqueue(callback);
	}

	/*
      Author: IU(yoyo930021)
      Description:
          This function's purpose is to communicate with QandA query api
      Usage:
          parameter:
	          Callback<List<QandaResponse>> callback: Callback
    */
	public void getQanda(Callback<List<QandaResponse>> callback) {
		Call<List<QandaResponse>> call = newsApi.getQandA();
		call.enqueue(callback);
	}

	/*
      Author: IU(yoyo930021)
      Description:
          This function's purpose is to communicate with relatedlink query api
      Usage:
          parameter:
	          Callback<List<RelatedlinkResponse>> callback: Callback
    */
	public void getLink(Callback<List<RelatedlinkResponse>> callback) {
		Call<List<RelatedlinkResponse>> call = newsApi.getLink();
		call.enqueue(callback);
	}

	/*
      Author: IU(yoyo930021)
      Description:
          This function's purpose is to communicate with feedback api
      Usage:
	      feedClass : feed class
	      commit : feed body
	      system : mobile info
          parameter:

    */
	public void postFB(String feedClass,String commit,String system,Callback<StatusResponse> callback) {
		Call<StatusResponse> call = menuApi.postFB(feedClass,commit,system);
		call.enqueue(callback);
	}

} public class Error {

	@SerializedName("error")
	public String message;

	@SerializedName("code")
	public int code;

} public class Login {

    @SerializedName("account")
    public String usr_account;

    @SerializedName("password")
    public String usr_password;

} public class StatusResponse extends RealmObject {

	@SerializedName("success")
	public String status;

} public class Token {

    @SerializedName("token")
    public String token;

} public class UserInfoResponse {


	/**
	 * name : string
	 * nick : string
	 * class : string
	 * group : student
	 */

	@SerializedName("name")
	public String name;
	@SerializedName("nick")
	public String nick;
	@SerializedName("class")
	public String classX;
	@SerializedName("group")
	public String group;
} public class StartActivity extends BaseActivity {

	public Register register;
	public FirebaseAnalytics mFirebaseAnalytics;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// Obtain the FirebaseAnalytics instance.
		mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);

		Bundle bundle = new Bundle();
		bundle.putString(FirebaseAnalytics.Param.ITEM_ID, "App open");
		bundle.putString(FirebaseAnalytics.Param.ITEM_NAME, "App open");
		bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, "doing");
		mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.APP_OPEN, bundle);

		Realm realm=Realm.getDefaultInstance();

		RealmResults<Setting> settings = realm.where(Setting.class).findAll();
		if(settings.size()==0||!settings.first().logined){
			setContentView(R.layout.activity_login);
			Toolbar toolbar=(Toolbar)findViewById(R.id.toolbar);
			setSupportActionBar(toolbar);

			register = new Register();

			FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
			Fragment fg= new LoginFragment();
			ft.replace(R.id.fm, fg, "f_m");
			ft.commit();
		}else{
			setContentView(R.layout.activity_start);
			new NetworkingClient(getApplicationContext()).getUserInfo(new MyCallBack<UserInfoResponse>(getApplicationContext()) {
				@Override
				public void onSuccess(final Response<UserInfoResponse> response) {
					Realm realm = Realm.getDefaultInstance();

					realm.executeTransaction(new Realm.Transaction() {
						@Override
						public void execute(Realm realm) {
							Setting setting=realm.where(Setting.class).findFirst();
							setting.nick=response.body().nick;
							setting.usr_group=response.body().group;
							setting.classX=response.body().classX;
							setting.name=response.body().name;
						}
					});

					realm.close();

					toMainActivity();
				}

				@Override
				public void onErr(Error error, Call<UserInfoResponse> call) {
					toMainActivity();
				}
			});
		}

		realm.close();
	}

	public void toMainActivity(){
		Realm realm=Realm.getDefaultInstance();
		if(realm.where(NetWorkCache.class).findAll().size()==0){
			realm.executeTransaction(new Realm.Transaction() {
				@Override
				public void execute(Realm realm) {
					NetWorkCache netWorkCache = realm.createObject(NetWorkCache.class);
				}
			});
		}
		realm.close();
		Intent intent = new Intent();
		intent.setClass(StartActivity.this, MainActivity.class);
		startActivity(intent);
		StartActivity.this.finish();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
	}
}
import android.app.Dialog;
import android.os.Bundle;
import android.support.design.widget.TextInputEditText;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.widget.AppCompatButton;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.firebase.analytics.FirebaseAnalytics;
import io.realm.Realm;
import kesshou.android.daanx.R;
import kesshou.android.daanx.models.NetWorkCache;
import kesshou.android.daanx.models.NotiSetting;
import kesshou.android.daanx.models.Setting;
import kesshou.android.daanx.util.component.DialogUtils;
import kesshou.android.daanx.util.network.MyCallBack;
import kesshou.android.daanx.util.network.NetworkingClient;
import kesshou.android.daanx.util.network.api.holder.Error;
import kesshou.android.daanx.util.network.api.holder.Login;
import kesshou.android.daanx.util.network.api.holder.StatusResponse;
import kesshou.android.daanx.util.network.api.holder.Token;
import kesshou.android.daanx.util.network.api.holder.UserInfoResponse;
import kesshou.android.daanx.views.StartActivity;
import retrofit2.Call;
import retrofit2.Response;
package kesshou.android.daanx.views.regist;





/**
 * A simple {@link Fragment} subclass.
 */
public class LoginFragment extends Fragment {


	public LoginFragment() {
		// Required empty public constructor
	}


	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
	                         Bundle savedInstanceState) {
		// Inflate the layout for this fragment
		View view = inflater.inflate(R.layout.fragment_login, container, false);

		final TextInputEditText inputAccount=(TextInputEditText)view.findViewById(R.id.input_account);

		final TextInputEditText inputPassword=(TextInputEditText) view.findViewById(R.id.input_password);

		AppCompatButton LoginButton = (AppCompatButton) view.findViewById(R.id.LoginButton);
		LoginButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				final Dialog dialog = DialogUtils.createLoadingDialog(getActivity());
				dialog.show();
				Login user = new Login();
				user.usr_account = inputAccount.getText().toString();
				user.usr_password = inputPassword.getText().toString();

				final NetworkingClient networkingClient = new NetworkingClient(getActivity().getApplicationContext());