You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

362 lines
15 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.example.doitnow;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.MenuItem;
import android.view.View;
import android.webkit.CookieManager;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import com.example.doitnow.Adapter.kebiaoManager;
public class MainActivity extends AppCompatActivity implements DialogCloseListener {
private FloatingActionButton fab,fab4;
private BottomNavigationView bottomNavigationView;
private Fragment currentFragment;
public static List<Lesson> kebiaodata=new ArrayList<>();
private kebiaoManager km;
private boolean FinishGetting;
public static String getWeekdayFromSunday(String sundayStr, int weekdayNumber) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d");
// 將字串轉成 Date
Date sundayDate = sdf.parse(sundayStr);
// 設定 Calendar 為這個週日
Calendar calendar = Calendar.getInstance();
calendar.setTime(sundayDate);
// 計算需要加幾天1 = 星期一, ..., 7 = 星期日)
int daysToAdd = weekdayNumber % 7; // 若是 7 (星期日),則加 0 天
calendar.add(Calendar.DATE, daysToAdd);
// 回傳結果
return sdf.format(calendar.getTime());
}
public List<String> getSundaysInRange(String startDate) {
List<String> sundays = new ArrayList<>();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-M-d"); // 修改为无前导零的格式
try {
// 将日期字符串转换为 Date 对象
Date start = dateFormat.parse(startDate);
Calendar calendar = Calendar.getInstance();
calendar.setTime(start);
// 如果开始日期不是周日,找到下一个周日
if (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
calendar.add(Calendar.DAY_OF_MONTH, Calendar.SUNDAY - calendar.get(Calendar.DAY_OF_WEEK));
}
// 逐个添加每个周日到列表中
for (int i=0;i<16;i++){
sundays.add(dateFormat.format(calendar.getTime()));
km.insertweek(i+1,dateFormat.format(calendar.getTime()));
calendar.add(Calendar.WEEK_OF_YEAR, 1); // 每次递增一周
}
} catch (Exception e) {
e.printStackTrace();
}
return sundays;
}
private void getCookies(String url) throws IOException, ParseException {
CookieManager cookieManager = CookieManager.getInstance();
String cookies = cookieManager.getCookie(url);
Map<String, String> cookiesMap = new HashMap<>();
for (String cookie : cookies.split(";")) {
String[] parts = cookie.trim().split("=", 2);
if (parts.length == 2) {
cookiesMap.put(parts[0], parts[1]);
}
}
List<String> order = Arrays.asList(
"JSESSIONID", "iPlanetDirectoryPro", "SF_cookie_2",
"RouTe_WAF_E1268C", "PORTAL-TOKEN", "SF_cookie_1",
"web_m_site", "route"
);
Map<String, String> sortedCookies = new LinkedHashMap<>();
for (String key : order) {
if (cookiesMap.containsKey(key)) {
sortedCookies.put(key, cookiesMap.get(key));
}
}
StringBuilder sortedCookieHeader = new StringBuilder();
for (Map.Entry<String, String> entry : sortedCookies.entrySet()) {
sortedCookieHeader.append(entry.getKey()).append("=").append(entry.getValue()).append("; ");
}
List<String> sundays=getSundaysInRange("2025-2-16");
km.deleteLesson();
String nodateUrl = "https://zhlj.whu.edu.cn/mobile/homepageapi/getCurriculumData?date=";
for(String sunday : sundays) {
OkHttpClient client = new OkHttpClient();
String apiUrl=nodateUrl+sunday;
Request request = new Request.Builder()
.url(apiUrl)
.addHeader("Cookie", sortedCookieHeader.toString()) // 设置 Cookie
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
runOnUiThread(() ->
Toast.makeText(MainActivity.this, "請求失敗: " + e.getMessage(), Toast.LENGTH_SHORT).show()
);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful() && response.body() != null) {
String responseData = response.body().string();
displayCurriculumData(responseData,sunday);
} else {
runOnUiThread(() ->
Toast.makeText(MainActivity.this, "請求失敗,狀態碼: " + response.code(), Toast.LENGTH_SHORT).show()
);
}
}
});
}
}
public void displayCurriculumData(String responseData,String date) {
try {
JSONObject response = new JSONObject(responseData);
if (response.getInt("code") == 200) {
JSONArray data = response.getJSONArray("data");
for (int i = 0; i < data.length(); i++) {
JSONObject dayData = data.getJSONObject(i);
int day = dayData.getInt("day");
JSONArray curriculumList = dayData.getJSONArray("curriculumList");
for (int j = 0; j < curriculumList.length(); j++) {
JSONObject curriculum = curriculumList.getJSONObject(j);
// 只有當有有效數據時才顯示
if (curriculum.has("name") && curriculum.getString("name")!="null") {
Lesson temp = new Lesson();
String today = getWeekdayFromSunday(date, day);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d");
Date d = sdf.parse(today);
temp.name = curriculum.getString("name");
temp.teacher = curriculum.getString("teacher");
temp.classroom = curriculum.getString("classroom");
temp.fromClass = curriculum.getInt("fromClass");
temp.endClass = curriculum.getInt("endClass");
temp.day = day;
temp.date = d;
km.insertLesson(temp);
}
}
}
}
} catch (JSONException e) {
e.printStackTrace();
} catch (ParseException e) {
throw new RuntimeException(e);
}
FinishGetting=true;
}
public void takekebiaoClick(View view)
{
FinishGetting=false;
WebView webView = findViewById(R.id.webview);
webView.setVisibility(View.VISIBLE); // 確保 WebView 是可見的
webView.bringToFront();
webView.clearCache(true); // 🔥 關鍵
webView.clearHistory(); // 🔥 關鍵
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); // 🔥 關鍵
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true); // ⬅️ 確保能開 modern JS 服務
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return false; // 让 WebView 继续加载
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (url.equals("https://zhlj.whu.edu.cn/mobile/apppage/h5page")) { // 登录成功后访问的页面
try {
// 等待 Cookie 更新完成
new Handler(Looper.getMainLooper()).postDelayed(() -> {
try {
getCookies(url);// 获取 cookies
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ParseException e) {
throw new RuntimeException(e);
}
webView.setVisibility(View.INVISIBLE);
}, 1000); // 延迟 1 秒获取 cookie确保 Cookie 已经更新
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
});
String loginUrl = "https://cas.whu.edu.cn/authserver/login?service=https%3A%2F%2Fzhlj.whu.edu.cn%2FcasLogin";
webView.loadUrl(loginUrl);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fab = findViewById(R.id.fab);
bottomNavigationView = findViewById(R.id.bottom_navigation);
fab4=findViewById(R.id.fab4);
km=new kebiaoManager(this);
ViewCompat.setOnApplyWindowInsetsListener(findViewById(android.R.id.content), (v, insets) -> {
WindowInsetsCompat systemBars = insets;
v.setPadding(systemBars.getInsets(WindowInsetsCompat.Type.systemBars()).left,
systemBars.getInsets(WindowInsetsCompat.Type.systemBars()).top,
systemBars.getInsets(WindowInsetsCompat.Type.systemBars()).right,
systemBars.getInsets(WindowInsetsCompat.Type.systemBars()).bottom);
return insets;
});
fab.setOnClickListener(v ->
AddNewTask.newInstance().show(getSupportFragmentManager(), AddNewTask.TAG)
);
fab4.setOnClickListener(this::takekebiaoClick);
bottomNavigationView.setOnItemSelectedListener(new BottomNavigationView.OnItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment newFragment = null;
String tag = "";
int id = item.getItemId();
if (id == R.id.nav_calendar) {
tag = "calendar";
} else if (id == R.id.nav_alltodo) {
tag = "alltodo";
} else if (id == R.id.nav_schedule) {
tag = "schedule";
} else if (id == R.id.nav_plant) {
tag = "plant";
} else if (id==R.id.nav_ai) {
tag="ai";
}
newFragment = getSupportFragmentManager().findFragmentByTag(tag);
if (newFragment == null) {
switch (tag) {
case "calendar":
newFragment = new CalendarFragment();
break;
case "alltodo":
newFragment = new AllTodoFragment();
break;
case "schedule":
newFragment = new ScheduleFragment();
break;
case "plant":
newFragment = new PlantFragment();
break;
case "ai":
newFragment = new AIFragment();
break;
}
transaction.add(R.id.fragment_container, newFragment, tag);
}
if (currentFragment != null && currentFragment != newFragment) {
transaction.hide(currentFragment);
}
transaction.show(newFragment);
transaction.commit();
currentFragment = newFragment;
if ("schedule".equals(tag)){
fab.setVisibility(View.GONE);
fab4.setVisibility(View.VISIBLE);
} else if ("alltodo".equals(tag)||("calendar".equals(tag))) {
fab4.setVisibility(View.GONE);
fab.setVisibility(View.VISIBLE);
}
else {
fab.setVisibility(View.GONE);
fab4.setVisibility(View.GONE);
}
return true;
}
});
// 預設打開 AllTodoFragment
if (savedInstanceState == null) {
currentFragment = new AllTodoFragment();
getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragment_container, currentFragment, "alltodo")
.commit();
}
bottomNavigationView.setSelectedItemId(R.id.nav_alltodo);
getSupportFragmentManager().setFragmentResultListener(
"taskAdded", this, (key, bundle) -> {
boolean added = bundle.getBoolean("taskAdded", false);
if (added) {
updateTaskList(); // 下面我會幫你補這個方法
}
});
}
@Override
public void handleDialogClose(DialogInterface dialog) {
if (currentFragment instanceof AllTodoFragment) {
((AllTodoFragment) currentFragment).refreshData();
}
}
private void updateTaskList() {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (fragment instanceof AllTodoFragment) {
((AllTodoFragment) fragment).refreshTaskList();
}
}
}