mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-29 15:15:30 +03:00
Support creating launcher shortcuts for ROMs
This commit adds the ability to create launcher shortcuts to specific ROMs for convenience.
This commit is contained in:
parent
4a72704c4d
commit
abaa404baa
@ -21,6 +21,7 @@ import emu.skyline.adapter.GameItem
|
|||||||
import emu.skyline.loader.BaseLoader
|
import emu.skyline.loader.BaseLoader
|
||||||
import emu.skyline.loader.NroLoader
|
import emu.skyline.loader.NroLoader
|
||||||
import emu.skyline.loader.TitleEntry
|
import emu.skyline.loader.TitleEntry
|
||||||
|
import emu.skyline.utility.GameDialog
|
||||||
import emu.skyline.utility.RandomAccessDocument
|
import emu.skyline.utility.RandomAccessDocument
|
||||||
import kotlinx.android.synthetic.main.main_activity.*
|
import kotlinx.android.synthetic.main.main_activity.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -31,7 +32,7 @@ import java.util.*
|
|||||||
class MainActivity : AppCompatActivity(), View.OnClickListener {
|
class MainActivity : AppCompatActivity(), View.OnClickListener {
|
||||||
private lateinit var sharedPreferences: SharedPreferences
|
private lateinit var sharedPreferences: SharedPreferences
|
||||||
private var adapter = GameAdapter(this)
|
private var adapter = GameAdapter(this)
|
||||||
private fun notifyUser(text: String) {
|
fun notifyUser(text: String) {
|
||||||
Snackbar.make(findViewById(android.R.id.content), text, Snackbar.LENGTH_SHORT).show()
|
Snackbar.make(findViewById(android.R.id.content), text, Snackbar.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,6 +117,14 @@ class MainActivity : AppCompatActivity(), View.OnClickListener {
|
|||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
game_list.onItemLongClickListener = AdapterView.OnItemLongClickListener { parent, _, position, _ ->
|
||||||
|
val item = parent.getItemAtPosition(position)
|
||||||
|
if (item is GameItem) {
|
||||||
|
val dialog = GameDialog(item)
|
||||||
|
dialog.show(supportFragmentManager, "game")
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
if (sharedPreferences.getString("search_location", "") == "") {
|
if (sharedPreferences.getString("search_location", "") == "") {
|
||||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
||||||
intent.flags = Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION or Intent.FLAG_GRANT_PREFIX_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION
|
intent.flags = Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION or Intent.FLAG_GRANT_PREFIX_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||||
|
@ -16,7 +16,7 @@ import android.widget.TextView
|
|||||||
import emu.skyline.R
|
import emu.skyline.R
|
||||||
import emu.skyline.loader.TitleEntry
|
import emu.skyline.loader.TitleEntry
|
||||||
|
|
||||||
internal class GameItem(val meta: TitleEntry) : BaseItem() {
|
class GameItem(val meta: TitleEntry) : BaseItem() {
|
||||||
val icon: Bitmap?
|
val icon: Bitmap?
|
||||||
get() = meta.icon
|
get() = meta.icon
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ fun getTitleFormat(uri: Uri, contentResolver: ContentResolver): TitleFormat {
|
|||||||
return TitleFormat.valueOf(uriStr.substring(uriStr.lastIndexOf(".") + 1).toUpperCase(Locale.ROOT))
|
return TitleFormat.valueOf(uriStr.substring(uriStr.lastIndexOf(".") + 1).toUpperCase(Locale.ROOT))
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TitleEntry(var name: String, var author: String, var romType: TitleFormat, var valid: Boolean, @Transient var uri: Uri, @Transient var icon: Bitmap) : Serializable {
|
class TitleEntry(var name: String, var author: String, var romType: TitleFormat, var valid: Boolean, var uri: Uri, var icon: Bitmap) : Serializable {
|
||||||
constructor(context: Context, author: String, romType: TitleFormat, valid: Boolean, uri: Uri) : this("", author, romType, valid, uri, context.resources.getDrawable(R.drawable.ic_missing, context.theme).toBitmap(256, 256)) {
|
constructor(context: Context, author: String, romType: TitleFormat, valid: Boolean, uri: Uri) : this("", author, romType, valid, uri, context.resources.getDrawable(R.drawable.ic_missing, context.theme).toBitmap(256, 256)) {
|
||||||
context.contentResolver.query(uri, null, null, null, null)?.use { cursor ->
|
context.contentResolver.query(uri, null, null, null, null)?.use { cursor ->
|
||||||
val nameIndex: Int = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
val nameIndex: Int = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
|
||||||
|
60
app/src/main/java/emu/skyline/utility/GameDialog.kt
Normal file
60
app/src/main/java/emu/skyline/utility/GameDialog.kt
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package emu.skyline.utility
|
||||||
|
|
||||||
|
import android.content.ComponentName
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.ShortcutInfo
|
||||||
|
import android.content.pm.ShortcutManager
|
||||||
|
import android.graphics.drawable.Icon
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import emu.skyline.GameActivity
|
||||||
|
import emu.skyline.R
|
||||||
|
import emu.skyline.adapter.GameItem
|
||||||
|
import kotlinx.android.synthetic.main.game_dialog.*
|
||||||
|
|
||||||
|
class GameDialog() : DialogFragment() {
|
||||||
|
var item: GameItem? = null
|
||||||
|
|
||||||
|
constructor(item: GameItem) : this() {
|
||||||
|
this.item = item
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
return requireActivity().layoutInflater.inflate(R.layout.game_dialog, container)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
if (item is GameItem) {
|
||||||
|
game_icon.setImageBitmap(item?.icon)
|
||||||
|
game_title.text = item?.title
|
||||||
|
game_subtitle.text = item?.subTitle
|
||||||
|
val shortcutManager = activity?.getSystemService(ShortcutManager::class.java)!!
|
||||||
|
game_pin.isEnabled = shortcutManager.isRequestPinShortcutSupported
|
||||||
|
game_pin.setOnClickListener {
|
||||||
|
run {
|
||||||
|
val info = ShortcutInfo.Builder(context, item?.title)
|
||||||
|
info.setShortLabel(item?.meta?.name!!)
|
||||||
|
info.setActivity(ComponentName(context!!, GameActivity::class.java))
|
||||||
|
info.setIcon(Icon.createWithBitmap(item?.icon))
|
||||||
|
val intent = Intent(context, GameActivity::class.java)
|
||||||
|
intent.data = item?.uri
|
||||||
|
intent.action = Intent.ACTION_VIEW
|
||||||
|
info.setIntent(intent)
|
||||||
|
shortcutManager.requestPinShortcut(info.build(), null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
game_play.setOnClickListener {
|
||||||
|
run {
|
||||||
|
val intent = Intent(activity, GameActivity::class.java)
|
||||||
|
intent.data = item?.uri
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
activity?.supportFragmentManager?.beginTransaction()?.remove(this)?.commit()
|
||||||
|
}
|
||||||
|
}
|
83
app/src/main/res/layout/game_dialog.xml
Normal file
83
app/src/main/res/layout/game_dialog.xml
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginEnd="12dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/game_icon"
|
||||||
|
android:layout_width="60dp"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:contentDescription="@string/icon"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/game_icon">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/game_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Display1"
|
||||||
|
android:textSize="18sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/game_subtitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Display2"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linearLayout"
|
||||||
|
style="?android:attr/buttonBarStyle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:layout_marginEnd="12dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:gravity="clip_vertical|fill_horizontal"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/game_pin"
|
||||||
|
style="?android:attr/buttonBarButtonStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="6dp"
|
||||||
|
android:text="@string/pin" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/game_play"
|
||||||
|
style="?android:attr/buttonBarButtonStyle"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="6dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/play" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -12,6 +12,8 @@
|
|||||||
<string name="icon">Icon</string>
|
<string name="icon">Icon</string>
|
||||||
<string name="no_rom">Cannot find any ROMs</string>
|
<string name="no_rom">Cannot find any ROMs</string>
|
||||||
<string name="nro">NROs</string>
|
<string name="nro">NROs</string>
|
||||||
|
<string name="pin">Pin</string>
|
||||||
|
<string name="play">Play</string>
|
||||||
<!-- Toolbar Logger -->
|
<!-- Toolbar Logger -->
|
||||||
<string name="clear">Clear</string>
|
<string name="clear">Clear</string>
|
||||||
<string name="share">Share</string>
|
<string name="share">Share</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user