diff --git a/.idea/misc.xml b/.idea/misc.xml index 54d5acd7d7803e035156e6a92b2eac33785c8994..69d113f42b6501e3869200a85c41835667325f4f 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,13 @@ - - + + + + diff --git a/app/build.gradle b/app/build.gradle index a7f325d4ed13ab69f200f03a5c230b6c4df052f1..79b2381c5449c94b271b82a33514230973b07388 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,11 +7,11 @@ apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.android.gms.oss-licenses-plugin' android { - compileSdkVersion 30 + compileSdk 33 defaultConfig { applicationId "jp.atled.agileworks" minSdkVersion 24 - targetSdkVersion 30 + targetSdk 33 versionCode 39 versionName "1.0.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 640c0cf26a5a8f7aa06515f2c445dedcd208b161..64c2f5a72197c92a8d34ecf45afc7dbb47306565 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,6 +5,7 @@ + + android:exported="true"> @@ -30,10 +31,11 @@ - + @@ -44,7 +46,8 @@ android:name="android.appwidget.provider" android:resource="@xml/aw_app_widget_info" /> - + @@ -56,7 +59,8 @@ android:resource="@xml/aw_app_widget_approveonly_info" /> + tools:node="replace" + android:exported="true"> diff --git a/app/src/main/java/jp/atled/agileworks/model/FcmRepository.kt b/app/src/main/java/jp/atled/agileworks/model/FcmRepository.kt index 129c00b665254f16ea3c6ff4b77bc7384bd6580a..3b57b3bd96b0e3c4aeb5f43631eaab5275f00363 100644 --- a/app/src/main/java/jp/atled/agileworks/model/FcmRepository.kt +++ b/app/src/main/java/jp/atled/agileworks/model/FcmRepository.kt @@ -1,14 +1,15 @@ package jp.atled.agileworks.model import android.os.AsyncTask -import com.google.firebase.iid.FirebaseInstanceId +import com.google.firebase.installations.FirebaseInstallations +import com.google.firebase.messaging.FirebaseMessaging class FcmRepository { fun getFcmToken(onResponse: (isSuccess: Boolean, token: String?) -> Unit) { - FirebaseInstanceId.getInstance().instanceId.addOnCompleteListener { task -> + FirebaseMessaging.getInstance().token.addOnCompleteListener { task -> val result = task.result; if (task.isSuccessful && (result != null)) { - onResponse(true, result.token) + onResponse(true, result) } else { onResponse(false, null) } @@ -21,7 +22,9 @@ class FcmRepository { private class DeleteInstanceIdTask(private val onResponse: () -> Unit) : AsyncTask() { override fun doInBackground(vararg params: Unit?) { - FirebaseInstanceId.getInstance().deleteInstanceId() + FirebaseInstallations.getInstance().delete() + FirebaseMessaging.getInstance().deleteToken() + //FirebaseInstanceId.getInstance().deleteInstanceId() } override fun onPostExecute(result: Unit?) { diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/MainActivity.kt b/app/src/main/java/jp/atled/agileworks/view/ui/MainActivity.kt index 6c5399cd2b608ce399c9f7fa74f1f1854718e3a4..dfea07bc0a2398dd36a6a800fb9ca0a45994d1db 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/MainActivity.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/MainActivity.kt @@ -1,18 +1,23 @@ package jp.atled.agileworks.view.ui +import android.Manifest import android.app.NotificationChannel import android.app.NotificationManager import android.content.Context import android.content.Intent +import android.content.pm.PackageManager import android.content.res.Configuration import android.os.Build import android.os.Bundle import android.util.Log +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.annotation.RequiresApi import androidx.annotation.StringRes import androidx.appcompat.app.ActionBar import androidx.core.app.NotificationManagerCompat +import androidx.core.content.ContextCompat import androidx.lifecycle.LiveData import androidx.lifecycle.Observer import androidx.navigation.NavController @@ -35,6 +40,7 @@ class MainActivity : BaseActivity() { private var currentNavController: LiveData? = null private lateinit var appBarConfiguration: AppBarConfiguration private val viewModel by viewModels() + private lateinit var requestPermissionLauncher: ActivityResultLauncher override fun onCreate(savedInstanceState: Bundle?) { Log.d(TAG, "call onCreate, url = ${intent?.getStringExtra("url")}, title = ${intent?.getStringExtra("title")}") @@ -70,6 +76,7 @@ class MainActivity : BaseActivity() { } private fun setupNotification() { + checkNotificationPermission() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val notificationManager = NotificationManagerCompat.from(this) createNotificationChannel(notificationManager, NotificationManager.IMPORTANCE_DEFAULT, R.string.notification_channel_id_document, R.string.notification_channel_name_document, R.string.notification_channel_description_document) @@ -77,6 +84,26 @@ class MainActivity : BaseActivity() { } } + private fun checkNotificationPermission() { + // OS バージョン確認 + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) { + // Android 13 未満は通知権限不要 + return + } + + // 通知権限が許可されているか確認 + if (ContextCompat.checkSelfPermission( + this, Manifest.permission.POST_NOTIFICATIONS) + == PackageManager.PERMISSION_GRANTED) { + // 権限許可済 + return + } + + // 通知権限をリクエスト + requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()){} + requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) + } + @RequiresApi(Build.VERSION_CODES.O) private fun createNotificationChannel(manager: NotificationManagerCompat, importance: Int, @StringRes idId: Int, @StringRes nameId: Int, @StringRes descriptionId: Int) { val id = getString(idId) diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebClient.kt b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebClient.kt index 185531064d628514941ded1ae2d791f61aa80f84..41d82faced067adca95d01c253e3be354fae1160 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebClient.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebClient.kt @@ -56,7 +56,7 @@ class DocumentWebViewClient(private val webShare: DocumentWebShare): WebViewClie webShare.presenter.updateSession(url, false) // ネットワーク切断時Viewを表示する必要があるか設定する(URL変更時) - url?.let { webShare.presenter.updateDisconnectViewDisplayState(it) } + view?.url?.let { webShare.presenter.updateDisconnectViewDisplayState(it) } } } diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebDownload.kt b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebDownload.kt index 63f4605d45114b0ef3761b893df502e5fa13d75b..92c564e0090f33a3a8063bafb7332cabe96ad6bb 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebDownload.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/documentweb/DocumentWebDownload.kt @@ -140,7 +140,7 @@ class DocumentWebDownloader(private val handlingFragment: Fragment, private val val openUriIntent = Intent(Intent.ACTION_VIEW, destinationUri).apply { addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) } - val pendingIntent = PendingIntent.getActivity(AwApp.instance.applicationContext, 0, openUriIntent, PendingIntent.FLAG_CANCEL_CURRENT) + val pendingIntent = PendingIntent.getActivity(AwApp.instance.applicationContext, 0, openUriIntent, PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_CANCEL_CURRENT) progressNotificationBuilder .setContentText(context.resources.getText(R.string.download_notification_successful_message)) .setSmallIcon(android.R.drawable.stat_sys_download_done) 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 63df9e73bca6e7efcc4e47c076b67e50b91d4c29..98b672dfe1adfea00cf1efd3361eb8f4e2163288 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 @@ -256,7 +256,7 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { scrollAmount += scrollX - oldScrollX } - override fun onFling(e1: MotionEvent?, e2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean { + override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { // 横方向のスクロールが発生した時は基本的にページ遷移しないが、画面橋付近でページめくりをした時には反応するよう、短いスクロールは無視する。 if (scrollAmount.absoluteValue > SCROLL_THRESHOLD) { return false @@ -310,7 +310,7 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { return false } // ピンチが終わった際に閾値初期化 - override fun onScaleEnd(detector: ScaleGestureDetector?) { + override fun onScaleEnd(detector: ScaleGestureDetector) { pinchThreshold = 0.0F } @@ -355,7 +355,7 @@ class DocumentWebFragment : Fragment(), DocumentWebPresenter { it.setInitialScale(1) it.addJavascriptInterface(DocumentWebJavaScriptMessageReceiver(this, webShare), JAVASCRIPT_INTERFACE_NAME) val webSettings = it.settings - webSettings.setAppCacheEnabled(false) + //webSettings.setAppCacheEnabled(false) webSettings.builtInZoomControls = false webSettings.displayZoomControls = false webSettings.javaScriptEnabled = true diff --git a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginActivity.kt b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginActivity.kt index 536ab6c164e9810faec3ecff61e3e76c12f3f532..fb757d9c02500882e64a0332bde3f70be219dc6e 100644 --- a/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginActivity.kt +++ b/app/src/main/java/jp/atled/agileworks/view/ui/login/LoginActivity.kt @@ -1,11 +1,17 @@ package jp.atled.agileworks.view.ui.login +import android.Manifest import android.content.Context import android.content.Intent +import android.content.pm.PackageManager import android.content.res.Configuration +import android.os.Build import android.os.Bundle import android.util.Log +import androidx.activity.result.ActivityResultLauncher +import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.ContextCompat import jp.atled.agileworks.R import jp.atled.agileworks.view.ui.toDeepLinkArguments import jp.atled.agileworks.view.ui.toDirectOpenArguments 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 a41e633418251f5c26ad43248d42387db81a5909..3a311ccbe783105c85bcb9d52d66a83063cd3818 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 @@ -18,7 +18,7 @@ import androidx.fragment.app.Fragment import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders import com.google.android.material.snackbar.Snackbar -import com.google.firebase.iid.FirebaseInstanceId +import com.google.firebase.messaging.FirebaseMessaging import jp.atled.agileworks.BuildConfig import jp.atled.agileworks.R import jp.atled.agileworks.AwApp @@ -374,10 +374,10 @@ class LoginFragment: Fragment() { } if (response != null) { // トークンの更新に成功したら、MainActivity を起動 - FirebaseInstanceId.getInstance().instanceId.addOnCompleteListener { task -> + FirebaseMessaging.getInstance().token.addOnCompleteListener { task -> if (task.isSuccessful) { task.result?.apply { - NotificationRepository().setToken(requireActivity(), token) + NotificationRepository().setToken(requireActivity(), task.result!!) } } else { Log.w(TAG, "getInstanceId failed", task.exception) diff --git a/app/src/main/java/jp/atled/agileworks/widget/AwAppWidget.kt b/app/src/main/java/jp/atled/agileworks/widget/AwAppWidget.kt index 149c85f38b0747cc906c2f322534c6bac3f3fa2f..a66dd783f362d21aa652197fb66e63eb8108fbce 100644 --- a/app/src/main/java/jp/atled/agileworks/widget/AwAppWidget.kt +++ b/app/src/main/java/jp/atled/agileworks/widget/AwAppWidget.kt @@ -59,7 +59,7 @@ sealed class AwAppWidgetBase(private val widgetLayoutId: Int, private val approv val clickIntentTemplate = Intent(context, LoginActivity::class.java) val clickPendingIntentTemplate: PendingIntent = TaskStackBuilder.create(context) .addNextIntentWithParentStack(clickIntentTemplate) - .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT) + .getPendingIntent(0, PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT) views.setPendingIntentTemplate(R.id.widgetGridView, clickPendingIntentTemplate) appWidgetManager.updateAppWidget(appWidgetId, views) diff --git a/app/src/main/java/jp/atled/agileworks/widget/AwFirebaseMessagingService.kt b/app/src/main/java/jp/atled/agileworks/widget/AwFirebaseMessagingService.kt index 493f5ab68786cb6be39cd4fc70b6d42add19f2cd..687a63b5b01ac01c84018cfa8a809a35453e6fbd 100644 --- a/app/src/main/java/jp/atled/agileworks/widget/AwFirebaseMessagingService.kt +++ b/app/src/main/java/jp/atled/agileworks/widget/AwFirebaseMessagingService.kt @@ -69,12 +69,12 @@ class AwFirebaseMessagingService: FirebaseMessagingService() { /*val intent = Intent(this, LoginActivity::class.java).apply { setupForDirectOpen(data) }*/ - val intent = Intent(this, DirectOpenDocumentActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP).apply { + val intent = Intent(this, DirectOpenDocumentActivity::class.java).apply { setupForDirectOpen(data) } // 被り防止のために request code に notification id を用いる // FIXME: 低確率ながら firebase-messaging がバックグラウンドで表示するものと被る可能性あり - return PendingIntent.getActivity(this, notificationId, intent, PendingIntent.FLAG_CANCEL_CURRENT) + return PendingIntent.getActivity(this, notificationId, intent, PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_CANCEL_CURRENT) } /** diff --git a/build.gradle b/build.gradle index 977d62405d2d37460ed557d50d6173ed42a92e39..e5765d1e8571c8548b3e61fcf11e76663acb3bba 100644 --- a/build.gradle +++ b/build.gradle @@ -4,14 +4,14 @@ buildscript { ext{ kotlin_version = '1.4.10' nav_version = '2.3.2' - workVersion = '2.4.0' + workVersion = '2.7.0' anko_version = '0.10.8' retrofit_version = '2.8.1' coroutines_version = '1.3.7' moshi_version = '1.9.2' google_services_version='4.3.3' firebase_analytics_version = '18.0.0' - firebase_messaging_version = '21.0.0' + firebase_messaging_version = '23.0.0' constraint_layout_version = '2.0.4' appcompat_version = '1.3.0-alpha02' lifecycle_extention_version='1.1.1'