diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 28cdfb4c06..5970e66b68 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -15,8 +15,8 @@ android { applicationId = "com.vanced.manager" minSdkVersion(21) targetSdkVersion(30) - versionCode = 220 - versionName = "2.2.0 (RootedFirebase)" + versionCode = 221 + versionName = "2.2.1 (RootedFirebase)" vectorDrawables.useSupportLibrary = true diff --git a/app/src/main/java/com/vanced/manager/adapter/AppListAdapter.kt b/app/src/main/java/com/vanced/manager/adapter/AppListAdapter.kt index 29f241adc9..0f62afb2d9 100644 --- a/app/src/main/java/com/vanced/manager/adapter/AppListAdapter.kt +++ b/app/src/main/java/com/vanced/manager/adapter/AppListAdapter.kt @@ -76,13 +76,13 @@ class AppListAdapter( override fun onBindViewHolder(holder: ListViewHolder, position: Int) { holder.bind(position) - + val dataModel = if (isRoot) rootDataModels[position] else dataModels[position] holder.appCard.setOnClickListener { tooltip.close() AppInfoDialog.newInstance( appName = apps[position], - appIcon = dataModels[position]?.appIcon, - changelog = dataModels[position]?.changelog?.value + appIcon = dataModel?.appIcon, + changelog = dataModel?.changelog?.value ).show(context.supportFragmentManager, "info") } } @@ -92,15 +92,21 @@ class AppListAdapter( init { if (prefs.getBoolean("enable_vanced", true)) { - dataModels.add(viewModel.vancedModel.value) - rootDataModels.add(viewModel.vancedRootModel.value) + if (isRoot) { + rootDataModels.add(viewModel.vancedRootModel.value) + } else { + dataModels.add(viewModel.vancedModel.value) + } apps.add(context.getString(R.string.vanced)) itemCount++ } if (prefs.getBoolean("enable_music", true)) { - dataModels.add(viewModel.musicModel.value) - rootDataModels.add(viewModel.musicRootModel.value) + if (isRoot) { + rootDataModels.add(viewModel.musicRootModel.value) + } else { + dataModels.add(viewModel.musicModel.value) + } apps.add(context.getString(R.string.music)) itemCount++ } diff --git a/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloader.kt b/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloader.kt index 2661e7d4cf..0defd939dd 100644 --- a/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloader.kt +++ b/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloader.kt @@ -2,6 +2,7 @@ package com.vanced.manager.core.downloader import android.content.Context import android.content.SharedPreferences +import android.util.Log import androidx.preference.PreferenceManager.getDefaultSharedPreferences import com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.analytics.ktx.logEvent @@ -15,6 +16,7 @@ import com.vanced.manager.utils.PackageHelper.downloadStockCheck import com.vanced.manager.utils.PackageHelper.installVanced import com.vanced.manager.utils.PackageHelper.installVancedRoot import java.io.File +import java.lang.Exception object VancedDownloader { @@ -58,7 +60,13 @@ object VancedDownloader { count = 0 vancedVersionCode = vanced.value?.int("versionCode") ?: 0 - downloadSplits(context) + try { + downloadSplits(context) + } catch (e: Exception) { + Log.d("VMDownloader", e.stackTraceToString()) + downloadProgress.value?.downloadingFile?.postValue(context.getString(R.string.error_downloading, "Vanced")) + } + } private fun downloadSplits(context: Context, type: String = "theme") { diff --git a/app/src/main/java/com/vanced/manager/model/DataModel.kt b/app/src/main/java/com/vanced/manager/model/DataModel.kt index 0d9b617afd..0b91d637e8 100644 --- a/app/src/main/java/com/vanced/manager/model/DataModel.kt +++ b/app/src/main/java/com/vanced/manager/model/DataModel.kt @@ -16,9 +16,9 @@ import kotlinx.coroutines.launch open class DataModel( private val jsonObject: LiveData<JsonObject?>, private val context: Context, - open val appPkg: String, - open val appName: String, - open val appIcon: Drawable?, + val appPkg: String, + val appName: String, + val appIcon: Drawable?, ) { private val versionCode = MutableLiveData<Int>() @@ -32,11 +32,9 @@ open class DataModel( private fun fetch() = CoroutineScope(Dispatchers.IO).launch { val jobj = jsonObject.value - isAppInstalled.postValue(isPackageInstalled(appPkg, context.packageManager)) + isAppInstalled.postValue(isAppInstalled(appPkg)) versionCode.postValue(jobj?.int("versionCode") ?: 0) - versionName.postValue(jobj?.string("version")?.removeSuffix("-vanced") ?: context.getString( - R.string.unavailable - )) + versionName.postValue(jobj?.string("version")?.removeSuffix("-vanced") ?: context.getString(R.string.unavailable)) changelog.postValue(jobj?.string("changelog") ?: context.getString(R.string.unavailable)) } @@ -50,8 +48,8 @@ open class DataModel( } this?.let { isAppInstalled.observe(it) { - installedVersionCode.postValue(getPkgVersionCode(appPkg)) - installedVersionName.postValue(getPkgVersionName(appPkg)) + installedVersionCode.value = getPkgVersionCode(appPkg) + installedVersionName.value = getPkgVersionName(appPkg) } } this?.let { @@ -64,10 +62,12 @@ open class DataModel( } } - open fun getPkgVersionName(pkg: String): String { + open fun isAppInstalled(pkg: String): Boolean = isPackageInstalled(pkg, context.packageManager) + + private fun getPkgVersionName(pkg: String): String { val pm = context.packageManager return if (isAppInstalled.value == true) { - pm.getPackageInfo(pkg, 0).versionName.removeSuffix("-vanced") + pm?.getPackageInfo(pkg, 0)?.versionName?.removeSuffix("-vanced") ?: context.getString(R.string.unavailable) } else { context.getString(R.string.unavailable) } @@ -75,16 +75,16 @@ open class DataModel( @Suppress("DEPRECATION") private fun getPkgVersionCode(pkg: String): Int { + val pm = context.packageManager return if (isAppInstalled.value == true) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) - context.packageManager.getPackageInfo(pkg, 0).longVersionCode.and(0xFFFFFFFF) - .toInt() + pm?.getPackageInfo(pkg, 0)?.longVersionCode?.and(0xFFFFFFFF)?.toInt() ?: 0 else - context.packageManager.getPackageInfo(pkg, 0).versionCode + pm?.getPackageInfo(pkg, 0)?.versionCode ?: 0 } else 0 } - open fun compareInt(int1: Int?, int2: Int?): String { + private fun compareInt(int1: Int?, int2: Int?): String { if (int2 != null && int1 != null) { return when { int1 == 0 -> context.getString(R.string.install) diff --git a/app/src/main/java/com/vanced/manager/model/ProgressModel.kt b/app/src/main/java/com/vanced/manager/model/ProgressModel.kt index c0014803a3..208e343c41 100644 --- a/app/src/main/java/com/vanced/manager/model/ProgressModel.kt +++ b/app/src/main/java/com/vanced/manager/model/ProgressModel.kt @@ -23,7 +23,7 @@ open class ProgressModel { } init { - installing.value = false + installing.postValue(false) reset() } diff --git a/app/src/main/java/com/vanced/manager/model/RootDataModel.kt b/app/src/main/java/com/vanced/manager/model/RootDataModel.kt index 2466772dd5..bf80ac837a 100644 --- a/app/src/main/java/com/vanced/manager/model/RootDataModel.kt +++ b/app/src/main/java/com/vanced/manager/model/RootDataModel.kt @@ -4,33 +4,30 @@ import android.content.Context import android.graphics.drawable.Drawable import androidx.lifecycle.LiveData import com.beust.klaxon.JsonObject -import com.vanced.manager.R import com.vanced.manager.utils.PackageHelper -open class RootDataModel( +class RootDataModel( jsonObject: LiveData<JsonObject?>, - private val context: Context, - override val appPkg: String, - override val appName: String, - override val appIcon: Drawable?, - private val scriptName: String + context: Context, + appPkg: String, + appName: String, + appIcon: Drawable?, + //BUG THIS! + //kotlin thinks that this value is null if we use + //private val scriptName: String + //Although it's impossible for it to be null. + //Ironic, isn't it? + private val scriptName: String? ): DataModel( jsonObject, context, appPkg, appName, appIcon ) { - override fun getPkgVersionName(pkg: String): String { - return if (PackageHelper.scriptExists(scriptName)) { - super.getPkgVersionName(pkg) + override fun isAppInstalled(pkg: String): Boolean { + //Adapt to nullable shit + return if (scriptName?.let { PackageHelper.scriptExists(it) } == true) { + super.isAppInstalled(appPkg) } else { - context.getString(R.string.unavailable) - } - } - - override fun compareInt(int1: Int?, int2: Int?): String { - return if (PackageHelper.scriptExists(scriptName)) { - super.compareInt(int1, int2) - } else { - context.getString(R.string.install) + false } } diff --git a/app/src/main/java/com/vanced/manager/ui/viewmodels/HomeViewModel.kt b/app/src/main/java/com/vanced/manager/ui/viewmodels/HomeViewModel.kt index 273e9195bf..cd2516b662 100644 --- a/app/src/main/java/com/vanced/manager/ui/viewmodels/HomeViewModel.kt +++ b/app/src/main/java/com/vanced/manager/ui/viewmodels/HomeViewModel.kt @@ -43,6 +43,7 @@ import kotlinx.coroutines.launch open class HomeViewModel(private val activity: FragmentActivity): ViewModel() { private val prefs = getDefaultSharedPreferences(activity) + private val variant get() = prefs.getString("vanced_variant", "nonroot") val vancedModel = MutableLiveData<DataModel>() val vancedRootModel = MutableLiveData<RootDataModel>() @@ -90,7 +91,6 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() { } fun openInstallDialog(view: View, app: String) { - val variant = prefs.getString("vanced_variant", "nonroot") if (variant == "nonroot" && app != activity.getString(R.string.microg) && !microgModel.value?.isAppInstalled?.value!!) { microgToast.show() return @@ -147,7 +147,7 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() { } fun uninstallPackage(pkg: String) { - if (prefs.getString("vanced_variant", "nonroot") == "root" && uninstallRootApk(pkg)) { + if (variant == "root" && uninstallRootApk(pkg)) { viewModelScope.launch { loadJson(activity) } } else { uninstallApk(pkg, activity) @@ -155,13 +155,14 @@ open class HomeViewModel(private val activity: FragmentActivity): ViewModel() { } init { - if (prefs.getString("vanced_variant", "nonroot") == "root") { + if (variant == "root") { vancedRootModel.value = RootDataModel(vanced, activity, vancedRootPkg, activity.getString(R.string.vanced), AppCompatResources.getDrawable(activity, R.drawable.ic_vanced), "vanced") musicRootModel.value = RootDataModel(music, activity, musicRootPkg, activity.getString(R.string.music), AppCompatResources.getDrawable(activity, R.drawable.ic_music), "music") + } else { + vancedModel.value = DataModel(vanced, activity, vancedPkg, activity.getString(R.string.vanced), AppCompatResources.getDrawable(activity, R.drawable.ic_vanced)) + musicModel.value = DataModel(music, activity, musicPkg, activity.getString(R.string.music), AppCompatResources.getDrawable(activity, R.drawable.ic_music)) + microgModel.value = DataModel(microg, activity, microgPkg, activity.getString(R.string.microg), AppCompatResources.getDrawable(activity, R.drawable.ic_microg)) } - vancedModel.value = DataModel(vanced, activity, vancedPkg, activity.getString(R.string.vanced), AppCompatResources.getDrawable(activity, R.drawable.ic_vanced)) - musicModel.value = DataModel(music, activity, musicPkg, activity.getString(R.string.music), AppCompatResources.getDrawable(activity, R.drawable.ic_music)) - microgModel.value = DataModel(microg, activity, microgPkg, activity.getString(R.string.microg), AppCompatResources.getDrawable(activity, R.drawable.ic_microg)) managerModel.value = DataModel(manager, activity, managerPkg, activity.getString(R.string.app_name), AppCompatResources.getDrawable(activity, R.mipmap.ic_launcher)) } } diff --git a/app/src/main/java/com/vanced/manager/utils/AppUtils.kt b/app/src/main/java/com/vanced/manager/utils/AppUtils.kt index 2ebbc562fc..0e1665b3b8 100644 --- a/app/src/main/java/com/vanced/manager/utils/AppUtils.kt +++ b/app/src/main/java/com/vanced/manager/utils/AppUtils.kt @@ -59,6 +59,16 @@ object AppUtils: CoroutineScope by CoroutineScope(Dispatchers.IO) { } } + fun sendFailure(error: String, context: Context): Job { + return launch { + delay(700) + val intent = Intent(HomeFragment.INSTALL_FAILED) + intent.putExtra("errorMsg", getErrorMessage(error, context)) + intent.putExtra("fullErrorMsg", error) + LocalBroadcastManager.getInstance(context).sendBroadcast(intent) + } + } + @Throws(IOException::class) fun generateChecksum(data: ByteArray): String { try { diff --git a/app/src/main/java/com/vanced/manager/utils/DownloadHelper.kt b/app/src/main/java/com/vanced/manager/utils/DownloadHelper.kt index 10cd58a8b7..d0de877447 100644 --- a/app/src/main/java/com/vanced/manager/utils/DownloadHelper.kt +++ b/app/src/main/java/com/vanced/manager/utils/DownloadHelper.kt @@ -117,7 +117,7 @@ object DownloadHelper : CoroutineScope by CoroutineScope(Dispatchers.IO) { fun downloadManager(context: Context) { val url = "https://github.com/YTVanced/VancedManager/releases/latest/download/manager.apk" - download(url,"https://github.com/YTVanced/VancedManager", "manager", "manager.apk", context, onDownloadComplete = { + download(url,"https://github.com/YTVanced/VancedManager/", "manager", "manager.apk", context, onDownloadComplete = { val apk = File("${context.getExternalFilesDir("manager")?.path}/manager.apk") val uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) diff --git a/app/src/main/java/com/vanced/manager/utils/PackageHelper.kt b/app/src/main/java/com/vanced/manager/utils/PackageHelper.kt index 7315dc5f71..be032d826b 100644 --- a/app/src/main/java/com/vanced/manager/utils/PackageHelper.kt +++ b/app/src/main/java/com/vanced/manager/utils/PackageHelper.kt @@ -161,23 +161,28 @@ object PackageHelper { } fun install(path: String, context: Context) { - val callbackIntent = Intent(context, AppInstallerService::class.java) - val pendingIntent = PendingIntent.getService(context, 0, callbackIntent, 0) - val packageInstaller = context.packageManager.packageInstaller - val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL) - val sessionId = packageInstaller.createSession(params) - val session = packageInstaller.openSession(sessionId) - val inputStream: InputStream = FileInputStream(path) - val outputStream = session.openWrite("install", 0, -1) - val buffer = ByteArray(65536) - var c: Int - while (inputStream.read(buffer).also { c = it } != -1) { - outputStream.write(buffer, 0, c) - } - session.fsync(outputStream) - inputStream.close() - outputStream.close() - session.commit(pendingIntent.intentSender) + try { + val callbackIntent = Intent(context, AppInstallerService::class.java) + val pendingIntent = PendingIntent.getService(context, 0, callbackIntent, 0) + val packageInstaller = context.packageManager.packageInstaller + val params = PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL) + val sessionId = packageInstaller.createSession(params) + val session = packageInstaller.openSession(sessionId) + val inputStream: InputStream = FileInputStream(path) + val outputStream = session.openWrite("install", 0, -1) + val buffer = ByteArray(65536) + var c: Int + while (inputStream.read(buffer).also { c = it } != -1) { + outputStream.write(buffer, 0, c) + } + session.fsync(outputStream) + inputStream.close() + outputStream.close() + session.commit(pendingIntent.intentSender) + } catch (e: IOException) { + Log.d(INSTALLER_TAG, e.stackTraceToString()) + } + } private fun installRootMusic(files: ArrayList<FileInfo>, context: Context): Boolean { @@ -271,7 +276,7 @@ object PackageHelper { } doCommitSession(sessionId, context) Log.d(INSTALLER_TAG,"Success") - } catch (e: IOException) { + } catch (e: Exception) { e.printStackTrace() } return sessionId @@ -326,19 +331,16 @@ object PackageHelper { private fun doCommitSession(sessionId: Int, context: Context) { var session: PackageInstaller.Session? = null try { - try { - session = context.packageManager.packageInstaller.openSession(sessionId) - val callbackIntent = Intent(context, AppInstallerService::class.java) - val pendingIntent = PendingIntent.getService(context, 0, callbackIntent, 0) - session.commit(pendingIntent.intentSender) - session.close() - Log.d(INSTALLER_TAG, "install request sent") - Log.d(INSTALLER_TAG, "doCommitSession: " + context.packageManager.packageInstaller.mySessions) - Log.d(INSTALLER_TAG, "doCommitSession: after session commit ") - } catch (e: IOException) { - e.printStackTrace() - } - + session = context.packageManager.packageInstaller.openSession(sessionId) + val callbackIntent = Intent(context, AppInstallerService::class.java) + val pendingIntent = PendingIntent.getService(context, 0, callbackIntent, 0) + session.commit(pendingIntent.intentSender) + session.close() + Log.d(INSTALLER_TAG, "install request sent") + Log.d(INSTALLER_TAG, "doCommitSession: " + context.packageManager.packageInstaller.mySessions) + Log.d(INSTALLER_TAG, "doCommitSession: after session commit ") + } catch (e: IOException) { + e.printStackTrace() } finally { session?.close() } diff --git a/app/src/main/res/values-so-rSO/strings.xml b/app/src/main/res/values-so-rSO/strings.xml index 97bc92b51a..a04699657a 100644 --- a/app/src/main/res/values-so-rSO/strings.xml +++ b/app/src/main/res/values-so-rSO/strings.xml @@ -51,9 +51,9 @@ <string name="link_title">Isticmaal Daaqadaha Chrome</string> <string name="link_custom_tabs">Linkiyadu waxay ku furmi doonaan daaqadaha Chrome-ka ee loogu talagalay</string> <string name="system_default">Sida aaladu tahay</string> - <string name="script_save_failed">Failed to save new time value</string> - <string name="script_sleep_timer">Root Script Sleep Time</string> - <string name="script_sleep_timer_description">Adjust sleep time value used in /data/adb/service.d/app.sh script, useful for fixing mounting issues</string> + <string name="script_save_failed">Laguma guulaysan in cadadka wakhtiga la kaydiyo</string> + <string name="script_sleep_timer">Qormada Wakhtiga Jiifka ee Root-ka</string> + <string name="script_sleep_timer_description">Habee cadadka wakhtiga jiifka ee loo isticmaalay qormada /data/adb/service.d/app.s, waxay muhiim u tahay cilladaha galinta</string> <string name="theme">Nashqada</string> <string name="theme_dark">Nashqad Madow</string> <string name="theme_light">Nashqad Cad</string> @@ -104,7 +104,7 @@ <string name="installation_aborted">Ku shubidii way guuldaraysatay sababtoo ah qofka aalada isticmaalaya ayaa joojiyay.</string> <string name="installation_blocked">Ku shubidii way guuldaraysatay sababtoo ah qofka aalada isticmaalaya ayaa xanibay.</string> <string name="installation_downgrade">Ku shubidii way guuldaraysatay sababtoo ah qofka aalada isticmaalaya ayaa isku dayay inuu nooc hore ku shubo. Ka saar cusboonaysiinta xaga app-ka YouTube-ka caadiga ah, kadibna markale isku day.</string> - <string name="installation_conflict">Installation failed because the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string> + <string name="installation_conflict">Ku shubidii way guuldaraysatay sababtoo ah app-ka waxay iskhilaafeen mid horay ugu jiray aalada. Ka saar nooca hadda ee kujira, kadib markale ku celi.</string> <string name="installation_failed">Ku shubidii way guuldaraysatay sababo aan la garanaynin awgood, kusoo biir Telegram-kanaga ama Discord-ka si aad caawin dheerad ah u hesho.</string> <string name="installation_incompatible">Ku shubidii way guuldaraysatay sababtoo ah faylka kuma shaqaynayo aaladaada. Xaga Fadhiga ka saar waxyaabaha lasoo dajiyay, kadib markale isku day.</string> <string name="installation_invalid">Ku shubidii way guuldaraysatay sababtoo ah faylashii apk-ga ayaa khalkhalsan, markale isku day.</string> diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml index c311a6f2d6..e859fafa2b 100644 --- a/app/src/main/res/values-tr-rTR/strings.xml +++ b/app/src/main/res/values-tr-rTR/strings.xml @@ -51,9 +51,9 @@ <string name="link_title">Chrome Özel Sekmelerini kullan</string> <string name="link_custom_tabs">Bağlantılar Chrome Özel Sekmelerinde açılacaktır</string> <string name="system_default">Sistem varsayılanı</string> - <string name="script_save_failed">Failed to save new time value</string> + <string name="script_save_failed">Yeni zaman değeri kaydedilemedi</string> <string name="script_sleep_timer">Root Script Sleep Time</string> - <string name="script_sleep_timer_description">Adjust sleep time value used in /data/adb/service.d/app.sh script, useful for fixing mounting issues</string> + <string name="script_sleep_timer_description">/data/adb/service.d/app.sh komut dosyasında kullanılan uyku süresi değerini ayarlayın, montaj sorunlarını düzeltmek için yararlıdır</string> <string name="theme">Tema</string> <string name="theme_dark">Koyu Tema</string> <string name="theme_light">Açık Tema</string> @@ -104,7 +104,7 @@ <string name="installation_aborted">Kullanıcı kurulumu iptal ettiği için kurulum başarısız oldu.</string> <string name="installation_blocked">Kullanıcı kurulumu engellediği için kurulum başarısız oldu.</string> <string name="installation_downgrade">Kullanıcı eski sürümü yüklemeye çalıştığı için kurulum tamamlanamadı. Orijinal YouTube uygulamasının güncellemelerini kaldırdıktan sonra yeniden deneyin.</string> - <string name="installation_conflict">Installation failed because the app conflicts with an already installed app. Uninstall the current version of the app, then try again.</string> + <string name="installation_conflict">Uygulama önceden yüklenmiş bir uygulamayla çakıştığından yükleme başarısız oldu. Uygulamanın mevcut sürümünü kaldırın ve ardından tekrar deneyin.</string> <string name="installation_failed">Kurulum bilinmeyen nedenlerden dolayı başarısız oldu. Telegram veya Discord\'a katılarak destek alabilirsin.</string> <string name="installation_incompatible">Kurulum dosyası cihazınız ile uyumsuz olduğu için kurulum işlemi başarısız oldu. Ayarlar\'da indirilen dosyaları temizleyip, tekrar deneyin.</string> <string name="installation_invalid">APK dosyaları çözümlenemediğinden, kurulum başarısız oldu. Lütfen yeniden deneyin.</string> diff --git a/core-ui/src/main/java/com/vanced/manager/core/ui/ext/FragmentExt.kt b/core-ui/src/main/java/com/vanced/manager/core/ui/ext/FragmentExt.kt index c7fe6fe064..6dc5d24dd6 100644 --- a/core-ui/src/main/java/com/vanced/manager/core/ui/ext/FragmentExt.kt +++ b/core-ui/src/main/java/com/vanced/manager/core/ui/ext/FragmentExt.kt @@ -1,10 +1,16 @@ package com.vanced.manager.core.ui.ext +import android.util.Log import androidx.fragment.app.DialogFragment import androidx.fragment.app.Fragment fun Fragment.requireSupportFM() = requireActivity().supportFragmentManager fun <D : DialogFragment> Fragment.showDialog(dialog: D) { - dialog.show(requireSupportFM(), dialog::class.simpleName) + try { + dialog.show(requireSupportFM(), dialog::class.simpleName) + } catch (e: IllegalStateException) { + Log.d("VMUI", "Can not perform this action after onSaveInstanceState") + } + } \ No newline at end of file