Skip to content

Commit

Permalink
Add support to open .eapk files
Browse files Browse the repository at this point in the history
  • Loading branch information
brahmkshatriya committed Oct 11, 2024
1 parent 09d995e commit 823ae8f
Show file tree
Hide file tree
Showing 5 changed files with 449 additions and 55 deletions.
13 changes: 13 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,19 @@
</intent-filter>
</activity>

<activity
android:name=".ExtensionOpenerActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file" />
<data android:scheme="content" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>

<service
android:name=".PlayerService"
android:exported="true"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package dev.brahmkshatriya.echo

import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.widget.Toast
import androidx.core.net.toFile
import androidx.core.net.toUri
import androidx.fragment.app.FragmentActivity
import dev.brahmkshatriya.echo.ui.extension.ApkLinkParser
import java.io.File


class ExtensionOpenerActivity : Activity() {
override fun onStart() {
super.onStart()
val uri = intent.data
val file = when (uri?.scheme) {
"content" -> getTempFile(uri)
else -> null
}
finish()
if (file == null)
Toast.makeText(this, "Could not find a file.", Toast.LENGTH_SHORT).show()
val startIntent = Intent(this, MainActivity::class.java)
startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startIntent.data = file?.let { Uri.fromFile(it) }
startActivity(startIntent)
}

private fun getTempFile(uri: Uri): File? {
val stream = contentResolver.openInputStream(uri) ?: return null
val bytes = stream.readBytes()
val tempFile = File.createTempFile("temp", ".apk", cacheDir)
tempFile.writeBytes(bytes)
return tempFile
}

companion object {
const val EXTENSION_INSTALLER = "extensionInstaller"
fun FragmentActivity.openExtensionInstaller(uri: Uri) {
val apk = uri.toFile()
val supportedLinks = ApkLinkParser.getSupportedLinks(apk)


supportFragmentManager.setFragmentResultListener(EXTENSION_INSTALLER, this) { _, bundle ->
val file = bundle.getString("file")?.toUri()?.toFile()
file?.delete()
}
}
}
}
61 changes: 8 additions & 53 deletions app/src/main/java/dev/brahmkshatriya/echo/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,9 @@ import com.google.android.material.navigation.NavigationBarView
import com.google.android.material.navigationrail.NavigationRailView
import com.google.common.util.concurrent.ListenableFuture
import dagger.hilt.android.AndroidEntryPoint
import dev.brahmkshatriya.echo.common.models.Album
import dev.brahmkshatriya.echo.common.models.Artist
import dev.brahmkshatriya.echo.common.models.EchoMediaItem
import dev.brahmkshatriya.echo.common.models.EchoMediaItem.Companion.toMediaItem
import dev.brahmkshatriya.echo.common.models.Playlist
import dev.brahmkshatriya.echo.common.models.Track
import dev.brahmkshatriya.echo.common.models.User
import dev.brahmkshatriya.echo.ExtensionOpenerActivity.Companion.openExtensionInstaller
import dev.brahmkshatriya.echo.databinding.ActivityMainBinding
import dev.brahmkshatriya.echo.ui.common.openFragment
import dev.brahmkshatriya.echo.ui.item.ItemFragment
import dev.brahmkshatriya.echo.ui.common.openItemFragmentFromUri
import dev.brahmkshatriya.echo.ui.settings.LookFragment.Companion.NAVBAR_GRADIENT
import dev.brahmkshatriya.echo.utils.animateTranslation
import dev.brahmkshatriya.echo.utils.checkAudioPermissions
Expand All @@ -38,7 +31,6 @@ import dev.brahmkshatriya.echo.utils.listenFuture
import dev.brahmkshatriya.echo.utils.observe
import dev.brahmkshatriya.echo.viewmodels.PlayerViewModel
import dev.brahmkshatriya.echo.viewmodels.PlayerViewModel.Companion.connectPlayerToUI
import dev.brahmkshatriya.echo.viewmodels.SnackBar
import dev.brahmkshatriya.echo.viewmodels.SnackBar.Companion.configureSnackBar
import dev.brahmkshatriya.echo.viewmodels.UiViewModel
import dev.brahmkshatriya.echo.viewmodels.UiViewModel.Companion.isNightMode
Expand Down Expand Up @@ -83,9 +75,9 @@ class MainActivity : AppCompatActivity() {

ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, insets ->
uiViewModel.setSystemInsets(this, insets)
val navBarSize = uiViewModel.systemInsets.value.bottom
val navBarSize = uiViewModel.systemInsets.value.bottom
val full = playerViewModel.settings.getBoolean(NAVBAR_GRADIENT, true)
navView.createNavDrawable(isRail,navBarSize, !full)
navView.createNavDrawable(isRail, navBarSize, !full)
insets
}

Expand Down Expand Up @@ -152,47 +144,10 @@ class MainActivity : AppCompatActivity() {
return
}
val uri = data
if (uri != null) {
fun createSnack(id: Int) {
val snackbar by viewModels<SnackBar>()
val message = getString(id)
snackbar.create(SnackBar.Message(message))
}

val extensionType = uri.host
when (extensionType) {
"music" -> {
val extensionId = uri.pathSegments.firstOrNull()
if (extensionId == null) {
createSnack(R.string.error_no_client)
return
}
val type = uri.pathSegments.getOrNull(1)
val id = uri.pathSegments.getOrNull(2)
if (id == null) {
createSnack(R.string.error_no_id)
return
}
val name = uri.getQueryParameter("name").orEmpty()
val item: EchoMediaItem? = when (type) {
"user" -> User(id, name).toMediaItem()
"artist" -> Artist(id, name).toMediaItem()
"track" -> Track(id, name).toMediaItem()
"album" -> Album(id, name).toMediaItem()
"playlist" -> Playlist(id, name, false).toMediaItem()
else -> null
}
if (item == null) {
createSnack(R.string.error_invalid_type)
return
}
openFragment(ItemFragment.newInstance(extensionId, item))
}

else -> {
createSnack(R.string.invalid_extension_host)
}
}
println("URI: $uri")
when (uri?.scheme) {
"echo" -> openItemFragmentFromUri(uri)
"file" -> openExtensionInstaller(uri)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
package dev.brahmkshatriya.echo.ui.common

import android.net.Uri
import android.os.Bundle
import android.view.View
import androidx.activity.viewModels
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.commit
import dev.brahmkshatriya.echo.R
import dev.brahmkshatriya.echo.common.models.Album
import dev.brahmkshatriya.echo.common.models.Artist
import dev.brahmkshatriya.echo.common.models.EchoMediaItem
import dev.brahmkshatriya.echo.common.models.EchoMediaItem.Companion.toMediaItem
import dev.brahmkshatriya.echo.common.models.Playlist
import dev.brahmkshatriya.echo.common.models.Track
import dev.brahmkshatriya.echo.common.models.User
import dev.brahmkshatriya.echo.ui.item.ItemFragment
import dev.brahmkshatriya.echo.viewmodels.SnackBar
import dev.brahmkshatriya.echo.viewmodels.UiViewModel

fun Fragment.openFragment(newFragment: Fragment, view: View? = null) {
parentFragmentManager.commit {
if (view != null) {
addSharedElement(view, view.transitionName)
newFragment.run {
if(arguments == null) arguments = Bundle()
if (arguments == null) arguments = Bundle()
arguments!!.putString("transitionName", view.transitionName)
}
}
Expand All @@ -31,4 +42,47 @@ fun Fragment.openFragment(newFragment: Fragment, view: View? = null) {
fun FragmentActivity.openFragment(newFragment: Fragment, view: View? = null) {
val oldFragment = supportFragmentManager.findFragmentById(R.id.navHostFragment)!!
oldFragment.openFragment(newFragment, view)
}
}

fun FragmentActivity.openItemFragmentFromUri(uri: Uri) {
fun createSnack(id: Int) {
val snackbar by viewModels<SnackBar>()
val message = getString(id)
snackbar.create(SnackBar.Message(message))
}

val extensionType = uri.host
when (extensionType) {
"music" -> {
val extensionId = uri.pathSegments.firstOrNull()
if (extensionId == null) {
createSnack(R.string.error_no_client)
return
}
val type = uri.pathSegments.getOrNull(1)
val id = uri.pathSegments.getOrNull(2)
if (id == null) {
createSnack(R.string.error_no_id)
return
}
val name = uri.getQueryParameter("name").orEmpty()
val item: EchoMediaItem? = when (type) {
"user" -> User(id, name).toMediaItem()
"artist" -> Artist(id, name).toMediaItem()
"track" -> Track(id, name).toMediaItem()
"album" -> Album(id, name).toMediaItem()
"playlist" -> Playlist(id, name, false).toMediaItem()
else -> null
}
if (item == null) {
createSnack(R.string.error_invalid_type)
return
}
openFragment(ItemFragment.newInstance(extensionId, item))
}

else -> {
createSnack(R.string.invalid_extension_host)
}
}
}
Loading

0 comments on commit 823ae8f

Please sign in to comment.