Skip to content

Commit

Permalink
Merge pull request #11 from Fmaldonado6/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
Fmaldonado6 committed May 5, 2021
2 parents eb26e58 + 2e10c58 commit 8282a08
Show file tree
Hide file tree
Showing 21 changed files with 429 additions and 23 deletions.
7 changes: 5 additions & 2 deletions mobile_app/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ android {
applicationId "com.fmaldonado.akiyama"
minSdkVersion 23
targetSdkVersion 30
versionCode 2
versionName "2.0"
versionCode 3
versionName "v2.1"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand All @@ -32,10 +32,12 @@ android {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
buildConfigField "String", "BASE_URL", "\"https://akiyamarest.herokuapp.com/\""
buildConfigField "String", "GITHUB_URL", "\"https://api.github.com/repos/Fmaldonado6/Akiyama/releases/\""

}

debug {
buildConfigField "String", "GITHUB_URL", "\"https://api.github.com/repos/Fmaldonado6/Akiyama/releases/\""
buildConfigField "String", "BASE_URL", "\"http://10.0.2.2:4000/\""
applicationIdSuffix ".debug"

Expand Down Expand Up @@ -73,6 +75,7 @@ dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation("ru.gildor.coroutines:kotlin-coroutines-okhttp:1.0")

//Glide
implementation 'com.github.bumptech.glide:glide:4.12.0'
Expand Down
4 changes: 2 additions & 2 deletions mobile_app/app/release/output-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
{
"type": "SINGLE",
"filters": [],
"versionCode": 2,
"versionName": "2.0",
"versionCode": 3,
"versionName": "v2.1",
"outputFile": "app-release.apk"
}
]
Expand Down
12 changes: 12 additions & 0 deletions mobile_app/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
package="com.fmaldonado.akiyama">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />


<application
android:name=".AkiyamaApplication"
Expand Down Expand Up @@ -37,6 +39,16 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.fmaldonado.akiyama.data.models.version

data class GithubVersion(
val tag_name: String,
val name: String,
val prerelease: Boolean,
val assets: List<GithubAsset>
)

data class GithubAsset(
val name: String,
val browser_download_url: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.fmaldonado.akiyama.data.network

import com.fmaldonado.akiyama.data.models.version.GithubVersion
import retrofit2.http.GET

interface LatestVersionDataSource {
@GET("latest")
suspend fun getLatestRelease(): GithubVersion
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ class NetworkInterceptor : Interceptor {
throw AppError(response.body())

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.fmaldonado.akiyama.data.repositories.updater


import androidx.lifecycle.MutableLiveData
import com.fmaldonado.akiyama.AkiyamaApplication
import com.fmaldonado.akiyama.BuildConfig
import com.fmaldonado.akiyama.data.models.version.GithubVersion
import com.fmaldonado.akiyama.data.network.LatestVersionDataSource
import com.fmaldonado.akiyama.ui.common.UpdateEvents
import com.fmaldonado.akiyama.ui.common.UpdateStatus
import kotlinx.coroutines.delay
import okhttp3.OkHttpClient
import okhttp3.Request
import ru.gildor.coroutines.okhttp.await
import java.io.File
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class UpdaterRepository
@Inject
constructor(
private val latestVersionDataSource: LatestVersionDataSource,
private val okHttpClient: OkHttpClient,
private val application: AkiyamaApplication
) {

val hasNewVersion = MutableLiveData<UpdateEvents>()
val newVersionUri = MutableLiveData<File>()
private var version: GithubVersion? = null

suspend fun lookForNewVersion(manualClick: Boolean) {
if (manualClick) {
hasNewVersion.postValue(UpdateEvents(UpdateStatus.Looking, manualClick))
delay(1000)
}
version = latestVersionDataSource.getLatestRelease()
version?.let {
if (it.prerelease)
return
val status = if (it.tag_name != BuildConfig.VERSION_NAME && !BuildConfig.DEBUG)
UpdateStatus.NewUpdate
else
UpdateStatus.Updated
hasNewVersion.postValue(
UpdateEvents(
status,
manualClick
)
)
}
}

suspend fun downloadLatest() {
version?.let {
val asset = it.assets.firstOrNull() ?: throw Exception()
val req = Request.Builder().url(asset.browser_download_url).build()
val res = okHttpClient.newCall(req).await()
val bytes = res.body()?.byteStream() ?: throw Exception()
val file = File(application.externalCacheDir, "update.apk")
bytes.copyTo(file.outputStream())
newVersionUri.postValue(file)
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.fmaldonado.akiyama.data.utils

import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.util.Log
import androidx.core.content.FileProvider
import com.fmaldonado.akiyama.BuildConfig
import java.io.File


object ApkInstaller {
fun installApplication(context: Context, file: File) {
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(
uriFromFile(context, file),
"application/vnd.android.package-archive"
)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
try {
context.startActivity(intent)
} catch (e: ActivityNotFoundException) {
e.printStackTrace()
Log.e("TAG", "Error in opening the file!")
}
}

private fun uriFromFile(context: Context, file: File): Uri? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
FileProvider.getUriForFile(
context,
BuildConfig.APPLICATION_ID + ".provider",
file
)
} else {
Uri.fromFile(file)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.fmaldonado.akiyama.di

import com.fmaldonado.akiyama.BuildConfig
import com.fmaldonado.akiyama.data.network.LatestVersionDataSource
import com.fmaldonado.akiyama.data.network.NetworkDataSource
import com.fmaldonado.akiyama.data.network.interceptor.NetworkInterceptor
import dagger.Module
Expand Down Expand Up @@ -34,6 +35,29 @@ object NetworkModule {
.create(NetworkDataSource::class.java)
}

@Singleton
@Provides
fun provideOkHttpClient(networkInterceptor: NetworkInterceptor): OkHttpClient {
return OkHttpClient.Builder().addInterceptor(networkInterceptor).build()
}

@Singleton
@Provides
fun provideLatestVersionDataSource(networkInterceptor: NetworkInterceptor): LatestVersionDataSource {
val specs = listOf(ConnectionSpec.CLEARTEXT, ConnectionSpec.MODERN_TLS)
val okHttpClient =
OkHttpClient.Builder()
.addInterceptor(networkInterceptor)
.build()

return Retrofit.Builder()
.baseUrl(BuildConfig.GITHUB_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(LatestVersionDataSource::class.java)
}

@Singleton
@Provides
fun provideNetworkInterceptor(): NetworkInterceptor = NetworkInterceptor()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@ package com.fmaldonado.akiyama.ui.activities.main

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController
import com.fmaldonado.akiyama.R
import com.fmaldonado.akiyama.databinding.ActivityMainBinding
import com.fmaldonado.akiyama.ui.common.UpdateStatus
import com.fmaldonado.akiyama.ui.common.fragments.downloadDialog.DownloadDialog
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

private val viewModel: MainActivityViewModel by viewModels()
private lateinit var binding: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
Expand All @@ -22,5 +26,37 @@ class MainActivity : AppCompatActivity() {
val navHost = supportFragmentManager.findFragmentById(R.id.hostFragment) as NavHostFragment
val navController = navHost.navController
binding.bottomNav.setupWithNavController(navController)
viewModel.checkLatestVersion()

viewModel.hasNewVersion.observe(this, {
val manual = it.manualClick
when (it.status) {
UpdateStatus.Looking -> Snackbar.make(
binding.bottomNav,
getString(R.string.looking_for_update_text),
Snackbar.LENGTH_SHORT
).show()
UpdateStatus.NewUpdate -> Snackbar.make(
binding.bottomNav,
getString(R.string.new_update_text),
Snackbar.LENGTH_SHORT
).setAction("Download") {
viewModel.checkLatestVersion(manual)
}.show()
UpdateStatus.Updated ->
if (it.manualClick) Snackbar.make(
binding.bottomNav,
getString(R.string.updated_text),
Snackbar.LENGTH_SHORT
).show()
UpdateStatus.Error -> Snackbar.make(
binding.bottomNav,
getString(R.string.error_update_text),
Snackbar.LENGTH_SHORT
).show()
}
})

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.fmaldonado.akiyama.ui.activities.main

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.fmaldonado.akiyama.data.repositories.updater.UpdaterRepository
import com.fmaldonado.akiyama.ui.common.UpdateEvents
import com.fmaldonado.akiyama.ui.common.UpdateStatus
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.lang.Exception
import javax.inject.Inject

@HiltViewModel
class MainActivityViewModel
@Inject
constructor(
private val updaterRepository: UpdaterRepository
) : ViewModel() {

val hasNewVersion = updaterRepository.hasNewVersion
fun checkLatestVersion(manual: Boolean = false) {
viewModelScope.launch(Dispatchers.IO) {
try {
updaterRepository.lookForNewVersion(manual)
} catch (e: Exception) {
updaterRepository.hasNewVersion.postValue(UpdateEvents(UpdateStatus.Error, manual))
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.fmaldonado.akiyama.ui.activities.main.fragments.more
object PreferenceKeys {
val ABOUT = "about"
val TWITTER = "twitter"
val CHECK_UPDATES = "updates"
val VERSION = "version"
val SOURCE_CODE = "sourceCode"

Expand Down
Loading

0 comments on commit 8282a08

Please sign in to comment.