From 8d39bba4541de5039ab69ce8604e1f73116ab3c0 Mon Sep 17 00:00:00 2001 From: sitou Date: Thu, 27 Feb 2025 16:13:35 +0900 Subject: [PATCH 01/18] =?UTF-8?q?DocumentWebFragment=E3=81=A7getSession?= =?UTF-8?q?=E5=AE=8C=E4=BA=86=E5=BE=8C=E3=81=ABloadUrl=EF=BC=88=E4=BB=AE?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/documentweb/DocumentWebFragment.kt | 61 +++++++++++++++++-- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt index 9e27c645..a0c16e43 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt @@ -422,14 +422,63 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { setupWebView() hideLoadingProgressBar() setClickListeners() - updateSession(url, urlLoading) - if (urlLoading) { - webview?.let { - it.loadUrl(url!!) + val lock = java.util.concurrent.locks.ReentrantLock() + lock.withLock { + if (!sessionflg) { + sessionflg = true + + + var activity: Activity? = null + try { + activity = requireActivity() + } catch (e: Exception) { + activity = null + } + + SessionRepository.getInstance(activity).getSession() { isSuccess, response -> + if (isSuccess) { + url?.let { url -> + val uri = Uri.parse(url) + response!!.session_id?.apply { + sessionId = response!!.session_id + setCookie( + "https://${uri.host}", + "JSESSIONID=${sessionId}; Path=/${LoginRepository().loadServerContext()}; HttpOnly;Secure;SameSite=None" + ) + flush() + + // セッションID保存 + var preferences = "cookie" + ServerRepository().loadServer().toString() + AwApp.instance.applicationContext.getSharedPreferences( + preferences, + Context.MODE_PRIVATE + ) + .edit() + .putString("sessionId", sessionId) + .apply() + } + if (urlLoading) { + // 多言語対応 + response.user.displayLanguage.let { displayLanguage -> + multilingualControl.setNewLanguage(displayLanguage, webview) + } + + } + } + } + sessionflg = false + } + + if (urlLoading) { + webview?.let { + it.loadUrl(url!!) + } + } else { + webShare.presenter.updateAutoReloadState(false) + } } - } else { - webShare.presenter.updateAutoReloadState(false) } + } } -- GitLab From f09cd3f34e06cf8dbdef16e4b0c527f0a138f7ae Mon Sep 17 00:00:00 2001 From: sitou Date: Thu, 27 Feb 2025 16:38:42 +0900 Subject: [PATCH 02/18] =?UTF-8?q?loadUrl=E3=81=AE=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../view/ui/documentweb/DocumentWebFragment.kt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt index a0c16e43..b0be4a98 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt @@ -467,15 +467,16 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { } } sessionflg = false + if (urlLoading) { + webview?.let { + it.loadUrl(url!!) + } + } else { + webShare.presenter.updateAutoReloadState(false) + } } - if (urlLoading) { - webview?.let { - it.loadUrl(url!!) - } - } else { - webShare.presenter.updateAutoReloadState(false) - } + } } -- GitLab From 659988bea93df7df61df00705051dd0e227dec30 Mon Sep 17 00:00:00 2001 From: sitou Date: Tue, 18 Mar 2025 11:45:33 +0900 Subject: [PATCH 03/18] =?UTF-8?q?DocumentWebFragment=E5=86=85=E3=81=A7?= =?UTF-8?q?=E3=81=AA=E3=81=8F=E3=80=81LoginFragment=E3=81=A7getSession?= =?UTF-8?q?=E3=82=92=E8=A1=8C=E3=81=86=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/documentweb/DocumentWebFragment.kt | 62 ++----------------- .../agileworks/view/ui/login/LoginFragment.kt | 2 +- 2 files changed, 7 insertions(+), 57 deletions(-) diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt index b0be4a98..9e27c645 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt @@ -422,64 +422,14 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { setupWebView() hideLoadingProgressBar() setClickListeners() - val lock = java.util.concurrent.locks.ReentrantLock() - lock.withLock { - if (!sessionflg) { - sessionflg = true - - - var activity: Activity? = null - try { - activity = requireActivity() - } catch (e: Exception) { - activity = null - } - - SessionRepository.getInstance(activity).getSession() { isSuccess, response -> - if (isSuccess) { - url?.let { url -> - val uri = Uri.parse(url) - response!!.session_id?.apply { - sessionId = response!!.session_id - setCookie( - "https://${uri.host}", - "JSESSIONID=${sessionId}; Path=/${LoginRepository().loadServerContext()}; HttpOnly;Secure;SameSite=None" - ) - flush() - - // セッションID保存 - var preferences = "cookie" + ServerRepository().loadServer().toString() - AwApp.instance.applicationContext.getSharedPreferences( - preferences, - Context.MODE_PRIVATE - ) - .edit() - .putString("sessionId", sessionId) - .apply() - } - if (urlLoading) { - // 多言語対応 - response.user.displayLanguage.let { displayLanguage -> - multilingualControl.setNewLanguage(displayLanguage, webview) - } - - } - } - } - sessionflg = false - if (urlLoading) { - webview?.let { - it.loadUrl(url!!) - } - } else { - webShare.presenter.updateAutoReloadState(false) - } - } - - + updateSession(url, urlLoading) + if (urlLoading) { + webview?.let { + it.loadUrl(url!!) } + } else { + webShare.presenter.updateAutoReloadState(false) } - } } diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt index 35e82d77..0186fef4 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt @@ -477,7 +477,7 @@ class LoginFragment: Fragment() { if (deviceId != null) { // レスポンスが返ってきたらMainActivity起動 ServerRepository().addServerList() - whenAuthorizationSucceeds() + setCookie() } else { LoginUtil.clearAuthStateAndNotificationToken{ requireActivity().runOnUiThread { -- GitLab From 73f12977a33a14a4066bcbc5fea9b2fa53f94309 Mon Sep 17 00:00:00 2001 From: sitou Date: Wed, 19 Mar 2025 17:11:09 +0900 Subject: [PATCH 04/18] =?UTF-8?q?LoginFragment=E3=81=AEsetCookie=E3=81=AE?= =?UTF-8?q?=E5=80=A4=E3=82=92=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../atled/agileworks/view/ui/login/LoginFragment.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt index 0186fef4..30aaad5e 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt @@ -550,9 +550,16 @@ class LoginFragment: Fragment() { val response = ApiClient.instance.getSession().execute() if (response.isSuccessful) { response.body()!!.session_id?.apply { - val sessionId = response.body()!!.session_id - setCookie("https://${LoginRepository().loadServerUrl()}", "JSESSIONID=${sessionId}; Path=/${LoginRepository().loadServerContext()}; HttpOnly;Secure;SameSite=None") + val setCookieHeaders = response.headers().values("Set-Cookie") + for (header in setCookieHeaders) { + // Cookieをセット + Log.d(TAG, "setCookie header=$header") + setCookie("https://${LoginRepository().loadServerUrl()}", header) + } flush() + val sessionId = response.body()!!.session_id + //setCookie("https://${LoginRepository().loadServerUrl()}", "JSESSIONID=${sessionId}; Path=/${LoginRepository().loadServerContext()}; HttpOnly;Secure;SameSite=None") + //flush() // セッションID保存 var preferences = "cookie" + ServerRepository().loadServer().toString() AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) -- GitLab From d75444c050e59908e47e0245cb644794a8f76fff Mon Sep 17 00:00:00 2001 From: sitou Date: Mon, 24 Mar 2025 16:33:18 +0900 Subject: [PATCH 05/18] =?UTF-8?q?Logout=E6=99=82=E3=81=AE=E3=83=AA?= =?UTF-8?q?=E3=82=AF=E3=82=A8=E3=82=B9=E3=83=88cookie=E3=81=8C=E6=AD=A3?= =?UTF-8?q?=E3=81=97=E3=81=8F=E3=81=AA=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= =?UTF-8?q?=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agileworks/model/SessionRepository.kt | 6 +- .../atled/agileworks/model/api/ApiClient.kt | 4 +- .../model/api/SessionApiCallback.kt | 56 +++++++++++++++++++ .../jp/atled/agileworks/view/ui/DrawerMenu.kt | 4 +- .../ui/documentweb/DocumentWebFragment.kt | 45 +++++++++------ .../agileworks/view/ui/login/LoginFragment.kt | 8 ++- 6 files changed, 99 insertions(+), 24 deletions(-) create mode 100644 app/src/main/java/jp/atled/agileworks/model/api/SessionApiCallback.kt diff --git a/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt b/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt index 61092c17..ebb7e0da 100644 --- a/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt +++ b/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt @@ -1,13 +1,13 @@ package jp.atled.agileworks.model import android.app.Activity -import jp.atled.agileworks.model.api.ApiCallbackCommon +import jp.atled.agileworks.model.api.SessionApiCallback import jp.atled.agileworks.model.api.ApiClient class SessionRepository(private val activity: Activity?) { - fun getSession(onResult: (isSuccess: Boolean, response: SessionResponse?) -> Unit) { + fun getSession(onResult: (isSuccess: Boolean, response: SessionResponse?, headers: Map>?) -> Unit) { val instance = ApiClient.instance(null) - instance.getSession().enqueue(ApiCallbackCommon(activity, onResult)) + instance.getSession().enqueue(SessionApiCallback(activity, onResult)) } companion object { diff --git a/app/src/main/java/jp/atled/agileworks/model/api/ApiClient.kt b/app/src/main/java/jp/atled/agileworks/model/api/ApiClient.kt index 068b0081..e7247c0e 100644 --- a/app/src/main/java/jp/atled/agileworks/model/api/ApiClient.kt +++ b/app/src/main/java/jp/atled/agileworks/model/api/ApiClient.kt @@ -153,12 +153,12 @@ object ApiClient { // 保存しているセッションIDを取得 var preferences = "cookie" + ServerRepository().loadServer().toString() val cookiePref = AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) - val sessionId = cookiePref.getString("sessionId", "") ?: "" + val cookie = cookiePref.getString("cookie", "") ?: "" interceptor = Interceptor { chain -> val original = chain.request() val requestBuilder = original.newBuilder() val request = requestBuilder - .addHeader("Cookie", "JSESSIONID=$sessionId") + .addHeader("Cookie", cookie) .build() chain.proceed(request) } diff --git a/app/src/main/java/jp/atled/agileworks/model/api/SessionApiCallback.kt b/app/src/main/java/jp/atled/agileworks/model/api/SessionApiCallback.kt new file mode 100644 index 00000000..5addf4af --- /dev/null +++ b/app/src/main/java/jp/atled/agileworks/model/api/SessionApiCallback.kt @@ -0,0 +1,56 @@ +package jp.atled.agileworks.model.api + +import android.app.Activity +import android.app.AlertDialog +import android.util.Log +import jp.atled.agileworks.R +import jp.atled.agileworks.view.ui.login.LoginUtil +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response + +/** + * 多くの API 呼び出し共通のコールバック (全てではない)。 Call に対して、結果を onResult に渡す。 + * activity は、アクセストークンの更新が失敗した際、エラー表示やログアウト処理を行うために利用される。 + * activity に null が指定された場合、アクセストークンの更新失敗も他のエラーと同等に扱い、特殊な処理を行わない。 + */ +class SessionApiCallback( + private val activity: Activity?, + private val onResult: (isSuccess: Boolean, response: T?, headers: Map>?) -> Unit +) : Callback { + + companion object { + private const val TAG = "ApiCallbackCommon" + } + + override fun onResponse(call: Call, response: Response) { + try { + if (response.isSuccessful) { + val headers = response.headers().toMultimap() + onResult(true, response.body(), headers) + } else { + Log.e(TAG, "API request failed: ${response.code()}") + onResult(false, null, null) + } + } catch (e: IllegalStateException) { + // 非同期処理が画面遷移後に完了したときに発生する。握りつぶす。 + Log.w(TAG, "IllegalStateException", e) + } + } + + override fun onFailure(call: Call, t: Throwable) { + if ((activity != null) && (t is BadRefreshTokenException)) { + AlertDialog.Builder(activity) + .setTitle(R.string.refresh_token_failure_dialog_title) + .setMessage(R.string.refresh_token_failure_dialog_message) + .setIcon(android.R.drawable.ic_dialog_alert) + .setPositiveButton(R.string.refresh_token_failure_dialog_button_label) { _, _ -> + LoginUtil.reauth(activity) + } + .setCancelable(false) + .show() + } else { + onResult(false, null, null) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/DrawerMenu.kt b/app/src/main/java/jp/atled/agileworks/view/ui/DrawerMenu.kt index 60c53b5c..166955a3 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/DrawerMenu.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/DrawerMenu.kt @@ -62,7 +62,7 @@ class DrawerMenu { } private fun setupUserName(activity: Activity, drawer: NavigationView) { - SessionRepository.getInstance(activity).getSession { _, response -> + SessionRepository.getInstance(activity).getSession { _, response, _ -> val userName = response?.user?.name.orEmpty() var systemName = response?.system_name.orEmpty() val header = drawer.getHeaderView(0) @@ -75,7 +75,7 @@ class DrawerMenu { private fun showProfile(activity: AppCompatActivity) { // ログイン中に変化があるかもしれないのでメニューが呼ばれる度に取得し直す。 - SessionRepository.getInstance(activity).getSession { _, response -> + SessionRepository.getInstance(activity).getSession { _, response, _ -> val userCode = response?.user?.code.orEmpty() val userName = response?.user?.name.orEmpty() val loginId = response?.user?.loginId.orEmpty() diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt index 9e27c645..2d8d39e9 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt @@ -566,27 +566,40 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { activity = null } - SessionRepository.getInstance(activity).getSession() { isSuccess, response -> + SessionRepository.getInstance(activity).getSession() { isSuccess, response, headers -> if (isSuccess) { url?.let { url -> val uri = Uri.parse(url) response!!.session_id?.apply { sessionId = response!!.session_id - setCookie( - "https://${uri.host}", - "JSESSIONID=${sessionId}; Path=/${LoginRepository().loadServerContext()}; HttpOnly;Secure;SameSite=None" - ) - flush() - - // セッションID保存 - var preferences = "cookie" + ServerRepository().loadServer().toString() - AwApp.instance.applicationContext.getSharedPreferences( - preferences, - Context.MODE_PRIVATE - ) - .edit() - .putString("sessionId", sessionId) - .apply() + + val preferences = "cookie" + ServerRepository().loadServer().toString() + val sharedPreferences = AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) + val session = sharedPreferences.getString("sessionId", null) + if(sessionId != session) { + headers?.let { + val setcookie = it["set-cookie"] + Log.d("DocumentWebFragment", "set-cookie: $setcookie") + var cookie = "" + for (header in setcookie!!) { + // Cookieをセット + cookie += header + ";" + Log.d(TAG, "ssetCookie header=$cookie") + setCookie("https://${LoginRepository().loadServerUrl()}", header) + } + flush() + // セッションID保存 + var preferences = "cookie" + ServerRepository().loadServer().toString() + AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) + .edit() + .putString("sessionId", sessionId) + .apply() + AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) + .edit() + .putString("cookie", cookie) + .apply() + } + } } if (updateLanguage) { // 多言語対応 diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt index 30aaad5e..6c26e0db 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt @@ -551,9 +551,11 @@ class LoginFragment: Fragment() { if (response.isSuccessful) { response.body()!!.session_id?.apply { val setCookieHeaders = response.headers().values("Set-Cookie") + var cookie = "" for (header in setCookieHeaders) { // Cookieをセット - Log.d(TAG, "setCookie header=$header") + cookie += header + ";" + Log.d(TAG, "setCookie header=$cookie") setCookie("https://${LoginRepository().loadServerUrl()}", header) } flush() @@ -566,6 +568,10 @@ class LoginFragment: Fragment() { .edit() .putString("sessionId", sessionId) .apply() + AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) + .edit() + .putString("cookie", cookie) + .apply() } //トークン更新に成功するとメイン画面へ whenAuthorizationSucceeds() -- GitLab From 65cf3da5e2c17a3c66b5b9aa0180fb7d3e9d891f Mon Sep 17 00:00:00 2001 From: sitou Date: Tue, 25 Mar 2025 10:32:57 +0900 Subject: [PATCH 06/18] =?UTF-8?q?=E4=B8=8D=E8=A6=81=E3=81=AA=E6=96=87?= =?UTF-8?q?=E5=89=8A=E9=99=A4=E3=80=81=E3=82=A6=E3=82=A3=E3=82=B8=E3=82=A7?= =?UTF-8?q?=E3=83=83=E3=83=88=E3=81=8B=E3=82=89=E3=81=AE=E3=83=AD=E3=82=B0?= =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=81=B8=E3=81=AE=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../view/ui/documentweb/DocumentWebFragment.kt | 13 +++++++++---- .../atled/agileworks/view/ui/login/LoginFragment.kt | 3 +-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt index 2d8d39e9..26998e8e 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt @@ -572,20 +572,19 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { val uri = Uri.parse(url) response!!.session_id?.apply { sessionId = response!!.session_id - + //sessionIdに変化がないか確認 val preferences = "cookie" + ServerRepository().loadServer().toString() val sharedPreferences = AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) val session = sharedPreferences.getString("sessionId", null) if(sessionId != session) { headers?.let { val setcookie = it["set-cookie"] - Log.d("DocumentWebFragment", "set-cookie: $setcookie") var cookie = "" for (header in setcookie!!) { // Cookieをセット cookie += header + ";" - Log.d(TAG, "ssetCookie header=$cookie") - setCookie("https://${LoginRepository().loadServerUrl()}", header) + Log.d(TAG, "setCookie header=$cookie") + setCookie("https://${uri.host}", header) } flush() // セッションID保存 @@ -599,6 +598,12 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { .putString("cookie", cookie) .apply() } + }else { + setCookie( + "https://${uri.host}", + "JSESSIONID=${sessionId}; Path=/${LoginRepository().loadServerContext()}; HttpOnly;Secure;SameSite=None" + ) + flush() } } if (updateLanguage) { diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt index 6c26e0db..07be443f 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt @@ -559,9 +559,8 @@ class LoginFragment: Fragment() { setCookie("https://${LoginRepository().loadServerUrl()}", header) } flush() + val sessionId = response.body()!!.session_id - //setCookie("https://${LoginRepository().loadServerUrl()}", "JSESSIONID=${sessionId}; Path=/${LoginRepository().loadServerContext()}; HttpOnly;Secure;SameSite=None") - //flush() // セッションID保存 var preferences = "cookie" + ServerRepository().loadServer().toString() AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) -- GitLab From e8c67ce09e9cb084e7006b53eaab68a8d79b4b2c Mon Sep 17 00:00:00 2001 From: sitou Date: Tue, 25 Mar 2025 14:25:22 +0900 Subject: [PATCH 07/18] =?UTF-8?q?SessionApiCallback=E3=81=AEnull=E3=83=81?= =?UTF-8?q?=E3=82=A7=E3=83=83=E3=82=AF=E8=BF=BD=E8=A8=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jp/atled/agileworks/model/api/SessionApiCallback.kt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/src/main/java/jp/atled/agileworks/model/api/SessionApiCallback.kt b/app/src/main/java/jp/atled/agileworks/model/api/SessionApiCallback.kt index 5addf4af..430934b7 100644 --- a/app/src/main/java/jp/atled/agileworks/model/api/SessionApiCallback.kt +++ b/app/src/main/java/jp/atled/agileworks/model/api/SessionApiCallback.kt @@ -9,11 +9,6 @@ import retrofit2.Call import retrofit2.Callback import retrofit2.Response -/** - * 多くの API 呼び出し共通のコールバック (全てではない)。 Call に対して、結果を onResult に渡す。 - * activity は、アクセストークンの更新が失敗した際、エラー表示やログアウト処理を行うために利用される。 - * activity に null が指定された場合、アクセストークンの更新失敗も他のエラーと同等に扱い、特殊な処理を行わない。 - */ class SessionApiCallback( private val activity: Activity?, private val onResult: (isSuccess: Boolean, response: T?, headers: Map>?) -> Unit @@ -25,11 +20,10 @@ class SessionApiCallback( override fun onResponse(call: Call, response: Response) { try { - if (response.isSuccessful) { + if (response != null && response.isSuccessful) { val headers = response.headers().toMultimap() onResult(true, response.body(), headers) } else { - Log.e(TAG, "API request failed: ${response.code()}") onResult(false, null, null) } } catch (e: IllegalStateException) { -- GitLab From 315835464c9d18a5f0335ce36f46d296106af594 Mon Sep 17 00:00:00 2001 From: sitou Date: Wed, 26 Mar 2025 16:02:34 +0900 Subject: [PATCH 08/18] =?UTF-8?q?=E6=8C=87=E6=91=98=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=E3=80=81=E3=82=A6=E3=82=A3=E3=82=B8=E3=82=A7=E3=83=83=E3=83=88?= =?UTF-8?q?=E3=81=8B=E3=82=89=E9=96=8B=E3=81=84=E3=81=9F=E3=81=A8=E3=81=8D?= =?UTF-8?q?=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agileworks/model/SessionRepository.kt | 26 ++++++++++++++++ .../model/api/SessionApiCallback.kt | 2 +- .../ui/documentweb/DocumentWebFragment.kt | 29 ++--------------- .../agileworks/view/ui/login/LoginFragment.kt | 31 +++++-------------- 4 files changed, 36 insertions(+), 52 deletions(-) diff --git a/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt b/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt index ebb7e0da..277124e1 100644 --- a/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt +++ b/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt @@ -1,6 +1,9 @@ package jp.atled.agileworks.model import android.app.Activity +import android.content.Context +import android.webkit.CookieManager +import jp.atled.agileworks.AwApp import jp.atled.agileworks.model.api.SessionApiCallback import jp.atled.agileworks.model.api.ApiClient @@ -12,5 +15,28 @@ class SessionRepository(private val activity: Activity?) { companion object { fun getInstance(activity: Activity?) = SessionRepository(activity) + + fun setCookie(setCookieHeaders: List, sessionId: String, url: String){ + CookieManager.getInstance().apply { + var cookie = "" + for (header in setCookieHeaders) { + // Cookieをセット + cookie += header + ";" + setCookie(url, header) + } + flush() + + // セッションID保存 + var preferences = "cookie" + ServerRepository().loadServer().toString() + AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) + .edit() + .putString("sessionId", sessionId) + .apply() + AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) + .edit() + .putString("cookie", cookie) + .apply() + } + } } } \ No newline at end of file diff --git a/app/src/main/java/jp/atled/agileworks/model/api/SessionApiCallback.kt b/app/src/main/java/jp/atled/agileworks/model/api/SessionApiCallback.kt index 430934b7..d8a54bbf 100644 --- a/app/src/main/java/jp/atled/agileworks/model/api/SessionApiCallback.kt +++ b/app/src/main/java/jp/atled/agileworks/model/api/SessionApiCallback.kt @@ -15,7 +15,7 @@ class SessionApiCallback( ) : Callback { companion object { - private const val TAG = "ApiCallbackCommon" + private const val TAG = "SessionApiCallback" } override fun onResponse(call: Call, response: Response) { diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt index 26998e8e..2cfa86f7 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt @@ -572,38 +572,13 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { val uri = Uri.parse(url) response!!.session_id?.apply { sessionId = response!!.session_id - //sessionIdに変化がないか確認 val preferences = "cookie" + ServerRepository().loadServer().toString() val sharedPreferences = AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) val session = sharedPreferences.getString("sessionId", null) if(sessionId != session) { - headers?.let { - val setcookie = it["set-cookie"] - var cookie = "" - for (header in setcookie!!) { - // Cookieをセット - cookie += header + ";" - Log.d(TAG, "setCookie header=$cookie") - setCookie("https://${uri.host}", header) - } - flush() - // セッションID保存 - var preferences = "cookie" + ServerRepository().loadServer().toString() - AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) - .edit() - .putString("sessionId", sessionId) - .apply() - AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) - .edit() - .putString("cookie", cookie) - .apply() + headers?.get("set-cookie")?.also { setCookieHeaders -> + SessionRepository.setCookie(setCookieHeaders, sessionId!!, "https://${uri.host}") } - }else { - setCookie( - "https://${uri.host}", - "JSESSIONID=${sessionId}; Path=/${LoginRepository().loadServerContext()}; HttpOnly;Secure;SameSite=None" - ) - flush() } } if (updateLanguage) { diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt index 07be443f..e1664226 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt @@ -132,7 +132,7 @@ class LoginFragment: Fragment() { Log.d(TAG,"appBackGroundStatus == true") disableButtonFlg = true disableLogin() - setCookie() + setCookie(true) } else { // 認証済みの場合、生体/デバイス認証を実行 Log.d(TAG, "authState.isAuthorized == true") @@ -332,7 +332,7 @@ class LoginFragment: Fragment() { disableButtonFlg = true disableLogin() } - setCookie() + setCookie(true) } BiometricPrompt.Result.UnsupportedHardware -> onFailureAuthBiometricPrompt(R.string.auth_biometric_unsupported_hardware) BiometricPrompt.Result.NotHasBiometricsOnHardware -> onFailureAuthBiometricPrompt(R.string.auth_biometric_not_has_biometrics_on_hardware) @@ -477,7 +477,7 @@ class LoginFragment: Fragment() { if (deviceId != null) { // レスポンスが返ってきたらMainActivity起動 ServerRepository().addServerList() - setCookie() + setCookie(false) } else { LoginUtil.clearAuthStateAndNotificationToken{ requireActivity().runOnUiThread { @@ -537,7 +537,7 @@ class LoginFragment: Fragment() { } // Cookieにセッション情報がセットされているかを判定 - private fun setCookie() { + private fun setCookie(connected: Boolean) { val url = AwApp.Baseurl() CookieManager.getInstance().apply { // メインスレッドでHTTP通信をするとエラーになるためスレッドを分けて処理 @@ -551,27 +551,10 @@ class LoginFragment: Fragment() { if (response.isSuccessful) { response.body()!!.session_id?.apply { val setCookieHeaders = response.headers().values("Set-Cookie") - var cookie = "" - for (header in setCookieHeaders) { - // Cookieをセット - cookie += header + ";" - Log.d(TAG, "setCookie header=$cookie") - setCookie("https://${LoginRepository().loadServerUrl()}", header) - } - flush() - val sessionId = response.body()!!.session_id - // セッションID保存 - var preferences = "cookie" + ServerRepository().loadServer().toString() - AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) - .edit() - .putString("sessionId", sessionId) - .apply() - AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) - .edit() - .putString("cookie", cookie) - .apply() - } + if(!connected){ + SessionRepository.setCookie(setCookieHeaders, sessionId, "https://${LoginRepository().loadServerUrl()}") + }} //トークン更新に成功するとメイン画面へ whenAuthorizationSucceeds() } -- GitLab From f2859343eb2df46e5495521aa9c2f3a2adef6b10 Mon Sep 17 00:00:00 2001 From: sitou Date: Wed, 26 Mar 2025 17:47:50 +0900 Subject: [PATCH 09/18] =?UTF-8?q?setCookie=E5=85=B1=E9=80=9A=E9=83=A8?= =?UTF-8?q?=E5=88=86=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agileworks/model/SessionRepository.kt | 45 ++++++++++++------- .../ui/documentweb/DocumentWebFragment.kt | 7 +-- .../agileworks/view/ui/login/LoginFragment.kt | 11 +++-- 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt b/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt index 277124e1..8504e749 100644 --- a/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt +++ b/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt @@ -18,24 +18,35 @@ class SessionRepository(private val activity: Activity?) { fun setCookie(setCookieHeaders: List, sessionId: String, url: String){ CookieManager.getInstance().apply { - var cookie = "" - for (header in setCookieHeaders) { - // Cookieをセット - cookie += header + ";" - setCookie(url, header) - } - flush() + val preferences = "cookie" + ServerRepository().loadServer().toString() + val sharedPreferences = AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) + val session = sharedPreferences.getString("sessionId", null) + if(sessionId != session) { + var cookie = "" + for (header in setCookieHeaders) { + // Cookieをセット + cookie += header + ";" + setCookie(url, header) + } + flush() - // セッションID保存 - var preferences = "cookie" + ServerRepository().loadServer().toString() - AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) - .edit() - .putString("sessionId", sessionId) - .apply() - AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) - .edit() - .putString("cookie", cookie) - .apply() + // セッションID保存 + var preferences = "cookie" + ServerRepository().loadServer().toString() + AwApp.instance.applicationContext.getSharedPreferences( + preferences, + Context.MODE_PRIVATE + ) + .edit() + .putString("sessionId", sessionId) + .apply() + AwApp.instance.applicationContext.getSharedPreferences( + preferences, + Context.MODE_PRIVATE + ) + .edit() + .putString("cookie", cookie) + .apply() + } } } } diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt index 2cfa86f7..243ef9b0 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt @@ -572,14 +572,11 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { val uri = Uri.parse(url) response!!.session_id?.apply { sessionId = response!!.session_id - val preferences = "cookie" + ServerRepository().loadServer().toString() - val sharedPreferences = AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) - val session = sharedPreferences.getString("sessionId", null) - if(sessionId != session) { + headers?.get("set-cookie")?.also { setCookieHeaders -> SessionRepository.setCookie(setCookieHeaders, sessionId!!, "https://${uri.host}") } - } + } if (updateLanguage) { // 多言語対応 diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt index e1664226..13a77d7c 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt @@ -132,7 +132,7 @@ class LoginFragment: Fragment() { Log.d(TAG,"appBackGroundStatus == true") disableButtonFlg = true disableLogin() - setCookie(true) + setCookie() } else { // 認証済みの場合、生体/デバイス認証を実行 Log.d(TAG, "authState.isAuthorized == true") @@ -332,7 +332,7 @@ class LoginFragment: Fragment() { disableButtonFlg = true disableLogin() } - setCookie(true) + setCookie() } BiometricPrompt.Result.UnsupportedHardware -> onFailureAuthBiometricPrompt(R.string.auth_biometric_unsupported_hardware) BiometricPrompt.Result.NotHasBiometricsOnHardware -> onFailureAuthBiometricPrompt(R.string.auth_biometric_not_has_biometrics_on_hardware) @@ -477,7 +477,7 @@ class LoginFragment: Fragment() { if (deviceId != null) { // レスポンスが返ってきたらMainActivity起動 ServerRepository().addServerList() - setCookie(false) + setCookie() } else { LoginUtil.clearAuthStateAndNotificationToken{ requireActivity().runOnUiThread { @@ -537,7 +537,7 @@ class LoginFragment: Fragment() { } // Cookieにセッション情報がセットされているかを判定 - private fun setCookie(connected: Boolean) { + private fun setCookie() { val url = AwApp.Baseurl() CookieManager.getInstance().apply { // メインスレッドでHTTP通信をするとエラーになるためスレッドを分けて処理 @@ -552,9 +552,8 @@ class LoginFragment: Fragment() { response.body()!!.session_id?.apply { val setCookieHeaders = response.headers().values("Set-Cookie") val sessionId = response.body()!!.session_id - if(!connected){ SessionRepository.setCookie(setCookieHeaders, sessionId, "https://${LoginRepository().loadServerUrl()}") - }} + } //トークン更新に成功するとメイン画面へ whenAuthorizationSucceeds() } -- GitLab From 50fa0f208a2907b729453ce6c9f398f1ef9e6423 Mon Sep 17 00:00:00 2001 From: sitou Date: Wed, 2 Apr 2025 11:20:26 +0900 Subject: [PATCH 10/18] =?UTF-8?q?=E7=94=9F=E4=BD=93=E8=AA=8D=E8=A8=BC?= =?UTF-8?q?=E3=81=A7=E9=80=9A=E5=B8=B8=E3=83=AD=E3=82=B0=E3=82=A4=E3=83=B3?= =?UTF-8?q?=E6=99=82=E3=81=AE=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jp/atled/agileworks/model/SessionRepository.kt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt b/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt index 8504e749..2c309bc1 100644 --- a/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt +++ b/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt @@ -20,8 +20,8 @@ class SessionRepository(private val activity: Activity?) { CookieManager.getInstance().apply { val preferences = "cookie" + ServerRepository().loadServer().toString() val sharedPreferences = AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) - val session = sharedPreferences.getString("sessionId", null) - if(sessionId != session) { + val preferencesSessionId = sharedPreferences.getString("sessionId", null) + if(sessionId != preferencesSessionId) { var cookie = "" for (header in setCookieHeaders) { // Cookieをセット @@ -31,7 +31,6 @@ class SessionRepository(private val activity: Activity?) { flush() // セッションID保存 - var preferences = "cookie" + ServerRepository().loadServer().toString() AwApp.instance.applicationContext.getSharedPreferences( preferences, Context.MODE_PRIVATE @@ -46,6 +45,12 @@ class SessionRepository(private val activity: Activity?) { .edit() .putString("cookie", cookie) .apply() + }else { + setCookie( + url, + "JSESSIONID=${sessionId}; Path=/${LoginRepository().loadServerContext()}; HttpOnly;Secure;SameSite=None" + ) + flush() } } } -- GitLab From 53ea0bb121938f9add072d26770aac62c3febb2b Mon Sep 17 00:00:00 2001 From: sitou Date: Thu, 3 Apr 2025 10:33:42 +0900 Subject: [PATCH 11/18] =?UTF-8?q?=E7=94=9F=E4=BD=93=E8=AA=8D=E8=A8=BC?= =?UTF-8?q?=E6=99=82=E3=80=81=E6=96=B0=E3=81=9F=E3=81=ABcookie=E3=82=92?= =?UTF-8?q?=E3=82=BB=E3=83=83=E3=83=88=E3=81=97=E3=81=AA=E3=81=84=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jp/atled/agileworks/model/SessionRepository.kt | 11 +---------- .../view/ui/documentweb/DocumentWebFragment.kt | 9 ++++++--- .../agileworks/view/ui/login/LoginFragment.kt | 14 +++++++++----- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt b/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt index 2c309bc1..8d908d56 100644 --- a/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt +++ b/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt @@ -19,9 +19,6 @@ class SessionRepository(private val activity: Activity?) { fun setCookie(setCookieHeaders: List, sessionId: String, url: String){ CookieManager.getInstance().apply { val preferences = "cookie" + ServerRepository().loadServer().toString() - val sharedPreferences = AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE) - val preferencesSessionId = sharedPreferences.getString("sessionId", null) - if(sessionId != preferencesSessionId) { var cookie = "" for (header in setCookieHeaders) { // Cookieをセット @@ -45,13 +42,7 @@ class SessionRepository(private val activity: Activity?) { .edit() .putString("cookie", cookie) .apply() - }else { - setCookie( - url, - "JSESSIONID=${sessionId}; Path=/${LoginRepository().loadServerContext()}; HttpOnly;Secure;SameSite=None" - ) - flush() - } + } } } diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt index 243ef9b0..cdb7cca6 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt @@ -572,11 +572,14 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { val uri = Uri.parse(url) response!!.session_id?.apply { sessionId = response!!.session_id - headers?.get("set-cookie")?.also { setCookieHeaders -> - SessionRepository.setCookie(setCookieHeaders, sessionId!!, "https://${uri.host}") + val preferences = "cookie" + ServerRepository().loadServer().toString() + val preferencesSessionId = AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE).getString("sessionId", null) + Log.d(TAG, "preferencesSessionId=" + preferencesSessionId) + if(preferencesSessionId != null && sessionId != preferencesSessionId) { + SessionRepository.setCookie(setCookieHeaders, sessionId!!, "https://${uri.host}") + } } - } if (updateLanguage) { // 多言語対応 diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt index 13a77d7c..f9dcba66 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt @@ -36,6 +36,8 @@ import com.journeyapps.barcodescanner.ScanOptions import com.journeyapps.barcodescanner.ScanIntentResult import jp.atled.agileworks.model.* +import jp.atled.agileworks.view.ui.documentweb.DocumentWebFragment +import jp.atled.agileworks.view.ui.documentweb.DocumentWebFragment.Companion import jp.atled.agileworks.view.ui.login.OAuthService.handleAuthorizationResponse import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -132,7 +134,7 @@ class LoginFragment: Fragment() { Log.d(TAG,"appBackGroundStatus == true") disableButtonFlg = true disableLogin() - setCookie() + setCookie(false) } else { // 認証済みの場合、生体/デバイス認証を実行 Log.d(TAG, "authState.isAuthorized == true") @@ -332,7 +334,7 @@ class LoginFragment: Fragment() { disableButtonFlg = true disableLogin() } - setCookie() + setCookie(false) } BiometricPrompt.Result.UnsupportedHardware -> onFailureAuthBiometricPrompt(R.string.auth_biometric_unsupported_hardware) BiometricPrompt.Result.NotHasBiometricsOnHardware -> onFailureAuthBiometricPrompt(R.string.auth_biometric_not_has_biometrics_on_hardware) @@ -477,7 +479,7 @@ class LoginFragment: Fragment() { if (deviceId != null) { // レスポンスが返ってきたらMainActivity起動 ServerRepository().addServerList() - setCookie() + setCookie(true) } else { LoginUtil.clearAuthStateAndNotificationToken{ requireActivity().runOnUiThread { @@ -537,7 +539,7 @@ class LoginFragment: Fragment() { } // Cookieにセッション情報がセットされているかを判定 - private fun setCookie() { + private fun setCookie(newLogin: Boolean) { val url = AwApp.Baseurl() CookieManager.getInstance().apply { // メインスレッドでHTTP通信をするとエラーになるためスレッドを分けて処理 @@ -552,7 +554,9 @@ class LoginFragment: Fragment() { response.body()!!.session_id?.apply { val setCookieHeaders = response.headers().values("Set-Cookie") val sessionId = response.body()!!.session_id - SessionRepository.setCookie(setCookieHeaders, sessionId, "https://${LoginRepository().loadServerUrl()}") + if(newLogin) { + SessionRepository.setCookie(setCookieHeaders, sessionId, "https://${LoginRepository().loadServerUrl()}") + } } //トークン更新に成功するとメイン画面へ whenAuthorizationSucceeds() -- GitLab From 6f9cdfde0e09af573e3a67d864ed70088dbbe37c Mon Sep 17 00:00:00 2001 From: sitou Date: Thu, 3 Apr 2025 17:22:56 +0900 Subject: [PATCH 12/18] =?UTF-8?q?=E7=94=9F=E4=BD=93=E8=AA=8D=E8=A8=BC?= =?UTF-8?q?=E3=83=95=E3=83=A9=E3=82=B0=E3=81=8B=E3=82=89=E3=80=81=E3=82=BB?= =?UTF-8?q?=E3=83=83=E3=82=B7=E3=83=A7=E3=83=B3=E5=8F=96=E5=BE=97API?= =?UTF-8?q?=E3=81=AE=E3=83=98=E3=83=83=E3=83=80=E3=81=A8=E3=83=9C=E3=83=87?= =?UTF-8?q?=E3=82=A3=E3=82=92=E6=AF=94=E8=BC=83=E3=81=99=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agileworks/model/SessionRepository.kt | 40 +++++++++++++------ .../ui/documentweb/DocumentWebFragment.kt | 7 +--- .../agileworks/view/ui/login/LoginFragment.kt | 12 +++--- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt b/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt index 8d908d56..98312e7c 100644 --- a/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt +++ b/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt @@ -2,6 +2,7 @@ package jp.atled.agileworks.model import android.app.Activity import android.content.Context +import android.util.Log import android.webkit.CookieManager import jp.atled.agileworks.AwApp import jp.atled.agileworks.model.api.SessionApiCallback @@ -16,25 +17,24 @@ class SessionRepository(private val activity: Activity?) { companion object { fun getInstance(activity: Activity?) = SessionRepository(activity) - fun setCookie(setCookieHeaders: List, sessionId: String, url: String){ + fun setCookie(setCookieHeaders: List, bodySessionId: String, url: String){ CookieManager.getInstance().apply { val preferences = "cookie" + ServerRepository().loadServer().toString() - var cookie = "" + var cookie = "" + for (header in setCookieHeaders) { + cookie += header + ";" + } + // ヘッダからJSESSIONIDを取得 + val headerSessionId = extractJSessionId(cookie) + + // レスポンスヘッダとボディのJSESSIONIDが同じとき、そのユーザの最新のセッションになる + if(bodySessionId == headerSessionId) { for (header in setCookieHeaders) { // Cookieをセット - cookie += header + ";" setCookie(url, header) } flush() - - // セッションID保存 - AwApp.instance.applicationContext.getSharedPreferences( - preferences, - Context.MODE_PRIVATE - ) - .edit() - .putString("sessionId", sessionId) - .apply() + // Cookieを保存 AwApp.instance.applicationContext.getSharedPreferences( preferences, Context.MODE_PRIVATE @@ -42,8 +42,24 @@ class SessionRepository(private val activity: Activity?) { .edit() .putString("cookie", cookie) .apply() + } + } + } + fun extractJSessionId(cookie: String): String? { + val startIndex = cookie.indexOf("JSESSIONID=") + if (startIndex != -1) { + val jsessionIdPart = cookie.substring(startIndex) + val parts = jsessionIdPart.split(";") + if (parts.isNotEmpty()) { + val jsessionIdValuePair = parts[0] + val valueParts = jsessionIdValuePair.split("=",) + if (valueParts.size == 2) { + return valueParts[1] + } + } } + return null } } } \ No newline at end of file diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt index cdb7cca6..f516c958 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebFragment.kt @@ -573,12 +573,7 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { response!!.session_id?.apply { sessionId = response!!.session_id headers?.get("set-cookie")?.also { setCookieHeaders -> - val preferences = "cookie" + ServerRepository().loadServer().toString() - val preferencesSessionId = AwApp.instance.applicationContext.getSharedPreferences(preferences, Context.MODE_PRIVATE).getString("sessionId", null) - Log.d(TAG, "preferencesSessionId=" + preferencesSessionId) - if(preferencesSessionId != null && sessionId != preferencesSessionId) { - SessionRepository.setCookie(setCookieHeaders, sessionId!!, "https://${uri.host}") - } + SessionRepository.setCookie(setCookieHeaders, sessionId!!, "https://${uri.host}") } } if (updateLanguage) { diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt index f9dcba66..da5374b9 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt @@ -134,7 +134,7 @@ class LoginFragment: Fragment() { Log.d(TAG,"appBackGroundStatus == true") disableButtonFlg = true disableLogin() - setCookie(false) + setCookie() } else { // 認証済みの場合、生体/デバイス認証を実行 Log.d(TAG, "authState.isAuthorized == true") @@ -334,7 +334,7 @@ class LoginFragment: Fragment() { disableButtonFlg = true disableLogin() } - setCookie(false) + setCookie() } BiometricPrompt.Result.UnsupportedHardware -> onFailureAuthBiometricPrompt(R.string.auth_biometric_unsupported_hardware) BiometricPrompt.Result.NotHasBiometricsOnHardware -> onFailureAuthBiometricPrompt(R.string.auth_biometric_not_has_biometrics_on_hardware) @@ -479,7 +479,7 @@ class LoginFragment: Fragment() { if (deviceId != null) { // レスポンスが返ってきたらMainActivity起動 ServerRepository().addServerList() - setCookie(true) + setCookie() } else { LoginUtil.clearAuthStateAndNotificationToken{ requireActivity().runOnUiThread { @@ -539,7 +539,7 @@ class LoginFragment: Fragment() { } // Cookieにセッション情報がセットされているかを判定 - private fun setCookie(newLogin: Boolean) { + private fun setCookie() { val url = AwApp.Baseurl() CookieManager.getInstance().apply { // メインスレッドでHTTP通信をするとエラーになるためスレッドを分けて処理 @@ -554,9 +554,7 @@ class LoginFragment: Fragment() { response.body()!!.session_id?.apply { val setCookieHeaders = response.headers().values("Set-Cookie") val sessionId = response.body()!!.session_id - if(newLogin) { - SessionRepository.setCookie(setCookieHeaders, sessionId, "https://${LoginRepository().loadServerUrl()}") - } + SessionRepository.setCookie(setCookieHeaders, sessionId, "https://${LoginRepository().loadServerUrl()}") } //トークン更新に成功するとメイン画面へ whenAuthorizationSucceeds() -- GitLab From c93737d6f2a72f5cc5cfada27673d6e7b5f352d6 Mon Sep 17 00:00:00 2001 From: sitou Date: Fri, 4 Apr 2025 09:30:37 +0900 Subject: [PATCH 13/18] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=B8=AD=E3=81=AB?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=E3=81=97=E3=81=9F=E3=81=8C=E4=B8=8D=E8=A6=81?= =?UTF-8?q?=E3=81=AB=E3=81=AA=E3=81=A3=E3=81=9Fimport=E3=81=AE=E5=89=8A?= =?UTF-8?q?=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/jp/atled/agileworks/model/SessionRepository.kt | 1 - .../java/jp/atled/agileworks/view/ui/login/LoginFragment.kt | 2 -- 2 files changed, 3 deletions(-) diff --git a/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt b/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt index 98312e7c..eec33d59 100644 --- a/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt +++ b/app/src/main/java/jp/atled/agileworks/model/SessionRepository.kt @@ -2,7 +2,6 @@ package jp.atled.agileworks.model import android.app.Activity import android.content.Context -import android.util.Log import android.webkit.CookieManager import jp.atled.agileworks.AwApp import jp.atled.agileworks.model.api.SessionApiCallback diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt index da5374b9..13a77d7c 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt @@ -36,8 +36,6 @@ import com.journeyapps.barcodescanner.ScanOptions import com.journeyapps.barcodescanner.ScanIntentResult import jp.atled.agileworks.model.* -import jp.atled.agileworks.view.ui.documentweb.DocumentWebFragment -import jp.atled.agileworks.view.ui.documentweb.DocumentWebFragment.Companion import jp.atled.agileworks.view.ui.login.OAuthService.handleAuthorizationResponse import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers -- GitLab From ecd3ed361f91926c72fc0d8d9934f02028fbfed3 Mon Sep 17 00:00:00 2001 From: sitou Date: Tue, 22 Apr 2025 11:03:08 +0900 Subject: [PATCH 14/18] =?UTF-8?q?Manifest=E3=83=95=E3=82=A1=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E3=81=AB=E5=86=99=E7=9C=9F=E9=81=B8=E6=8A=9E=E3=82=A2?= =?UTF-8?q?=E3=82=AF=E3=82=BB=E3=82=B9=E6=A8=A9=E3=81=AE=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1f6cbec0..3c450c43 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,6 +6,9 @@ + + + Date: Tue, 22 Apr 2025 17:34:28 +0900 Subject: [PATCH 15/18] =?UTF-8?q?=E6=8E=A5=E7=B6=9A=E5=85=88=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=E3=81=A7=E6=8E=A5=E7=B6=9A=E6=B8=88=E3=81=BF=E3=82=B5?= =?UTF-8?q?=E3=83=BC=E3=83=90=E3=83=BC=E3=82=92=E5=85=A5=E5=8A=9B=E3=81=97?= =?UTF-8?q?=E3=81=9F=E3=81=A8=E3=81=8D=E3=81=AB=E3=82=A8=E3=83=A9=E3=83=BC?= =?UTF-8?q?=E3=81=8C=E5=87=BA=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 2 +- .../agileworks/view/ui/login/LoginFragment.kt | 54 ++++++++++--------- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 51dd3c29..81c4e1ff 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,7 +11,7 @@ android { applicationId "jp.atled.agileworks" minSdkVersion 24 targetSdk 34 - versionCode 3 + versionCode 40 versionName "1.1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt index 13a77d7c..20fbf9a8 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt @@ -51,6 +51,7 @@ class LoginFragment: Fragment() { private var shouldClearTaskOnOAuthFailure = false private var disableButtonFlg = false private var tempServerNumber: Int? = 0 + private var addServerFlg = false override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { Log.d(TAG, "call onCreateView()") @@ -124,6 +125,7 @@ class LoginFragment: Fragment() { } else if (requireActivity().intent.action == LoginActivity.ACTION_ADD_SERVER) { //サーバー追加のログイン画面 Log.d(TAG, "intent.action == LoginActivity.ACTION_ADD_SERVER") + addServerFlg = true } else { // 過去に認証したときの authState を取得 if (mOAuthService.getAuthState(savedInstanceState).isAuthorized) { @@ -178,7 +180,11 @@ class LoginFragment: Fragment() { binding.viewmodel?.setServerContext() if (checkServer()) { - whenAuthorizationSucceeds() + if(addServerFlg) { + loginAlert(R.string.login_server_check_alert) + } else { + startAuthorization() + } } else { try { startAuthorization() @@ -253,8 +259,6 @@ class LoginFragment: Fragment() { for (server in serverList) { val serverName = LoginRepository(server).loadServerUrl() if (serverName == serverHost) { - ServerRepository().setServer(server) - ServerRepository().changeServerList(server) return true } } @@ -346,7 +350,7 @@ class LoginFragment: Fragment() { // トークン更新に成功するとメイン画面へ Log.d(TAG, "call onBiometricAuth()") mOAuthService.performAction(AuthState.AuthStateAction() { - accessToken, _, ex -> + accessToken, _, ex -> if (ex != null) { val m = Throwable().stackTrace[0] Log.e(TAG, "${m}: ${ex}") @@ -371,19 +375,19 @@ class LoginFragment: Fragment() { showSnackBar(res) requireActivity().runOnUiThread { AlertDialog.Builder(requireContext()) - .setTitle(R.string.biometric_prompt_dialog_title) - .setMessage(R.string.auth_biometric_failure_dialog_message) - .setNeutralButton(R.string.auth_biometric_failure_dialog_retry) { _, _ -> - startBiometricPrompt() - } - .setPositiveButton(R.string.auth_biometric_failure_dialog_relogin) { _, _ -> - relogin() - } - .setNegativeButton(R.string.auth_biometric_failure_dialog_logout) { _, _ -> - LoginUtil.logout(requireActivity()) - } - .setCancelable(false) - .show() + .setTitle(R.string.biometric_prompt_dialog_title) + .setMessage(R.string.auth_biometric_failure_dialog_message) + .setNeutralButton(R.string.auth_biometric_failure_dialog_retry) { _, _ -> + startBiometricPrompt() + } + .setPositiveButton(R.string.auth_biometric_failure_dialog_relogin) { _, _ -> + relogin() + } + .setNegativeButton(R.string.auth_biometric_failure_dialog_logout) { _, _ -> + LoginUtil.logout(requireActivity()) + } + .setCancelable(false) + .show() } } @@ -415,13 +419,13 @@ class LoginFragment: Fragment() { fun loginAlert(@StringRes messageId: Int) { AlertDialog.Builder(requireContext()) - .setTitle(R.string.login_alert_title) - .setMessage(messageId) - .setPositiveButton(R.string.login_alert_button_label) { _, _ -> - whenAuthorizationFails(null) - } - .setCancelable(false) - .show() + .setTitle(R.string.login_alert_title) + .setMessage(messageId) + .setPositiveButton(R.string.login_alert_button_label) { _, _ -> + whenAuthorizationFails(null) + } + .setCancelable(false) + .show() } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { @@ -435,7 +439,7 @@ class LoginFragment: Fragment() { private fun handleAuthorizationResponse(data: Intent?) { Log.d(TAG, "call handleAuthorizationResponse()") mOAuthService.handleAuthorizationResponse(data, AuthorizationService.TokenResponseCallback() { - response, ex -> + response, ex -> Log.d(TAG, "response?.jsonSerializeString()=" + response?.jsonSerializeString()) mOAuthService.getAuthState().update(response, ex) try { -- GitLab From f08af766759ab4256afe9ae394a1b1125eeab3f4 Mon Sep 17 00:00:00 2001 From: sitou Date: Wed, 23 Apr 2025 09:49:07 +0900 Subject: [PATCH 16/18] =?UTF-8?q?=E4=B8=8D=E8=A6=81=E3=81=AA=E3=82=A4?= =?UTF-8?q?=E3=83=B3=E3=83=87=E3=83=B3=E3=83=88=E5=A4=89=E6=9B=B4=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 2 +- .../agileworks/view/ui/login/LoginFragment.kt | 44 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 81c4e1ff..51dd3c29 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,7 +11,7 @@ android { applicationId "jp.atled.agileworks" minSdkVersion 24 targetSdk 34 - versionCode 40 + versionCode 3 versionName "1.1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt index 20fbf9a8..9c28d6b0 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginFragment.kt @@ -350,7 +350,7 @@ class LoginFragment: Fragment() { // トークン更新に成功するとメイン画面へ Log.d(TAG, "call onBiometricAuth()") mOAuthService.performAction(AuthState.AuthStateAction() { - accessToken, _, ex -> + accessToken, _, ex -> if (ex != null) { val m = Throwable().stackTrace[0] Log.e(TAG, "${m}: ${ex}") @@ -375,19 +375,19 @@ class LoginFragment: Fragment() { showSnackBar(res) requireActivity().runOnUiThread { AlertDialog.Builder(requireContext()) - .setTitle(R.string.biometric_prompt_dialog_title) - .setMessage(R.string.auth_biometric_failure_dialog_message) - .setNeutralButton(R.string.auth_biometric_failure_dialog_retry) { _, _ -> - startBiometricPrompt() - } - .setPositiveButton(R.string.auth_biometric_failure_dialog_relogin) { _, _ -> - relogin() - } - .setNegativeButton(R.string.auth_biometric_failure_dialog_logout) { _, _ -> - LoginUtil.logout(requireActivity()) - } - .setCancelable(false) - .show() + .setTitle(R.string.biometric_prompt_dialog_title) + .setMessage(R.string.auth_biometric_failure_dialog_message) + .setNeutralButton(R.string.auth_biometric_failure_dialog_retry) { _, _ -> + startBiometricPrompt() + } + .setPositiveButton(R.string.auth_biometric_failure_dialog_relogin) { _, _ -> + relogin() + } + .setNegativeButton(R.string.auth_biometric_failure_dialog_logout) { _, _ -> + LoginUtil.logout(requireActivity()) + } + .setCancelable(false) + .show() } } @@ -419,13 +419,13 @@ class LoginFragment: Fragment() { fun loginAlert(@StringRes messageId: Int) { AlertDialog.Builder(requireContext()) - .setTitle(R.string.login_alert_title) - .setMessage(messageId) - .setPositiveButton(R.string.login_alert_button_label) { _, _ -> - whenAuthorizationFails(null) - } - .setCancelable(false) - .show() + .setTitle(R.string.login_alert_title) + .setMessage(messageId) + .setPositiveButton(R.string.login_alert_button_label) { _, _ -> + whenAuthorizationFails(null) + } + .setCancelable(false) + .show() } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { @@ -439,7 +439,7 @@ class LoginFragment: Fragment() { private fun handleAuthorizationResponse(data: Intent?) { Log.d(TAG, "call handleAuthorizationResponse()") mOAuthService.handleAuthorizationResponse(data, AuthorizationService.TokenResponseCallback() { - response, ex -> + response, ex -> Log.d(TAG, "response?.jsonSerializeString()=" + response?.jsonSerializeString()) mOAuthService.getAuthState().update(response, ex) try { -- GitLab From c19d94b81134ba57af8f808ca2ab96f7814be8d0 Mon Sep 17 00:00:00 2001 From: sitou Date: Wed, 23 Apr 2025 09:54:06 +0900 Subject: [PATCH 17/18] =?UTF-8?q?=E3=82=A2=E3=83=97=E3=83=AA=E3=81=AE?= =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7=E3=83=B3=E3=82=A2=E3=83=83?= =?UTF-8?q?=E3=83=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 51dd3c29..6ba7fe0a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,8 +11,8 @@ android { applicationId "jp.atled.agileworks" minSdkVersion 24 targetSdk 34 - versionCode 3 - versionName "1.1.0" + versionCode 4 + versionName "1.1.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { -- GitLab From 8fd1f3565a7488d5157c5fc5ea578f24f0fd25d8 Mon Sep 17 00:00:00 2001 From: sitou Date: Fri, 16 May 2025 14:59:11 +0900 Subject: [PATCH 18/18] =?UTF-8?q?=E3=83=8D=E3=83=83=E3=83=88=E3=83=AF?= =?UTF-8?q?=E3=83=BC=E3=82=AF=E9=80=9A=E4=BF=A1=E5=86=8D=E9=96=8B=E6=99=82?= =?UTF-8?q?=E3=81=AB=E3=82=A6=E3=82=A3=E3=82=B8=E3=82=A7=E3=83=83=E3=83=88?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 1 + .../main/java/jp/atled/agileworks/AwApp.kt | 12 ++ .../agileworks/widget/NetworkStateMonitor.kt | 109 ++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 app/src/main/java/jp/atled/agileworks/widget/NetworkStateMonitor.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3c450c43..ae7cb656 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ +