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 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 getSundaysInRange(String startDate) { List 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 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 order = Arrays.asList( "JSESSIONID", "iPlanetDirectoryPro", "SF_cookie_2", "RouTe_WAF_E1268C", "PORTAL-TOKEN", "SF_cookie_1", "web_m_site", "route" ); Map sortedCookies = new LinkedHashMap<>(); for (String key : order) { if (cookiesMap.containsKey(key)) { sortedCookies.put(key, cookiesMap.get(key)); } } StringBuilder sortedCookieHeader = new StringBuilder(); for (Map.Entry entry : sortedCookies.entrySet()) { sortedCookieHeader.append(entry.getKey()).append("=").append(entry.getValue()).append("; "); } List 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(); } } }