add support for pinned shortcuts

This commit is contained in:
tibbi 2022-10-09 19:59:24 +02:00
parent 4280886656
commit 3a6aa2e96e
6 changed files with 95 additions and 19 deletions

View File

@ -42,7 +42,12 @@
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="true" android:exported="true"
android:screenOrientation="portrait" android:screenOrientation="portrait"
android:theme="@style/LauncherTheme" /> android:theme="@style/LauncherTheme">
<intent-filter>
<action android:name="android.content.pm.action.CONFIRM_PIN_SHORTCUT" />
</intent-filter>
</activity>
<activity <activity
android:name=".activities.SettingsActivity" android:name=".activities.SettingsActivity"

View File

@ -11,10 +11,12 @@ import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo
import android.content.pm.LauncherApps
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.res.Configuration import android.content.res.Configuration
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.Color import android.graphics.Color
import android.graphics.Rect
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
@ -85,6 +87,65 @@ class MainActivity : SimpleActivity(), FlingListener {
fragment.y = mScreenHeight.toFloat() fragment.y = mScreenHeight.toFloat()
fragment.beVisible() fragment.beVisible()
} }
if (intent.action == LauncherApps.ACTION_CONFIRM_PIN_SHORTCUT) {
val launcherApps = applicationContext.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
val item = launcherApps.getPinItemRequest(intent)
if (item.shortcutInfo == null) {
return
}
ensureBackgroundThread {
val shortcutId = item.shortcutInfo?.id!!
val label = item.shortcutInfo?.shortLabel?.toString() ?: item.shortcutInfo?.longLabel?.toString() ?: ""
val icon = launcherApps.getShortcutIconDrawable(item.shortcutInfo!!, resources.displayMetrics.densityDpi)
val rect = findFirstEmptyCell() ?: return@ensureBackgroundThread
val gridItem = HomeScreenGridItem(
null,
rect.left,
rect.top,
rect.right,
rect.bottom,
item.shortcutInfo!!.`package`,
label,
ITEM_TYPE_SHORTCUT,
"",
-1,
"",
shortcutId,
icon.toBitmap(),
icon
)
// delay showing the shortcut both to let the user see adding it in realtime and hackily avoid concurrent modification exception at HomeScreenGrid
Thread.sleep(2000)
item.accept()
home_screen_grid.storeAndShowGridItem(gridItem)
}
}
}
private fun findFirstEmptyCell(): Rect? {
val gridItems = homeScreenGridItemsDB.getAllItems() as ArrayList<HomeScreenGridItem>
val occupiedCells = ArrayList<Pair<Int, Int>>()
gridItems.forEach { item ->
for (xCell in item.left..item.right) {
for (yCell in item.top..item.bottom) {
occupiedCells.add(Pair(xCell, yCell))
}
}
}
for (checkedYCell in 0 until COLUMN_COUNT) {
for (checkedXCell in 0 until ROW_COUNT - 1) {
val wantedCell = Pair(checkedXCell, checkedYCell)
if (!occupiedCells.contains(wantedCell)) {
return Rect(wantedCell.first, wantedCell.second, wantedCell.first, wantedCell.second)
}
}
}
return null
} }
override fun onResume() { override fun onResume() {
@ -330,7 +391,12 @@ class MainActivity : SimpleActivity(), FlingListener {
if (clickedGridItem.type == ITEM_TYPE_ICON) { if (clickedGridItem.type == ITEM_TYPE_ICON) {
launchApp(clickedGridItem.packageName) launchApp(clickedGridItem.packageName)
} else if (clickedGridItem.type == ITEM_TYPE_SHORTCUT) { } else if (clickedGridItem.type == ITEM_TYPE_SHORTCUT) {
launchShortcutIntent(clickedGridItem) val id = clickedGridItem.shortcutId
val packageName = clickedGridItem.packageName
val userHandle = android.os.Process.myUserHandle()
val shortcutBounds = home_screen_grid.getClickableRect(clickedGridItem)
val launcherApps = applicationContext.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
launcherApps.startShortcut(packageName, id, shortcutBounds, null, userHandle)
} }
} }
} }
@ -527,7 +593,7 @@ class MainActivity : SimpleActivity(), FlingListener {
try { try {
val defaultDialerPackage = (getSystemService(Context.TELECOM_SERVICE) as TelecomManager).defaultDialerPackage val defaultDialerPackage = (getSystemService(Context.TELECOM_SERVICE) as TelecomManager).defaultDialerPackage
appLaunchers.firstOrNull { it.packageName == defaultDialerPackage }?.apply { appLaunchers.firstOrNull { it.packageName == defaultDialerPackage }?.apply {
val dialerIcon = HomeScreenGridItem(null, 0, ROW_COUNT - 1, 0, ROW_COUNT - 1, defaultDialerPackage, title, ITEM_TYPE_ICON, "", -1, "", null) val dialerIcon = HomeScreenGridItem(null, 0, ROW_COUNT - 1, 0, ROW_COUNT - 1, defaultDialerPackage, title, ITEM_TYPE_ICON, "", -1, "", "", null)
homeScreenGridItems.add(dialerIcon) homeScreenGridItems.add(dialerIcon)
} }
} catch (e: Exception) { } catch (e: Exception) {
@ -537,7 +603,7 @@ class MainActivity : SimpleActivity(), FlingListener {
val defaultSMSMessengerPackage = Telephony.Sms.getDefaultSmsPackage(this) val defaultSMSMessengerPackage = Telephony.Sms.getDefaultSmsPackage(this)
appLaunchers.firstOrNull { it.packageName == defaultSMSMessengerPackage }?.apply { appLaunchers.firstOrNull { it.packageName == defaultSMSMessengerPackage }?.apply {
val SMSMessengerIcon = val SMSMessengerIcon =
HomeScreenGridItem(null, 1, ROW_COUNT - 1, 1, ROW_COUNT - 1, defaultSMSMessengerPackage, title, ITEM_TYPE_ICON, "", -1, "", null) HomeScreenGridItem(null, 1, ROW_COUNT - 1, 1, ROW_COUNT - 1, defaultSMSMessengerPackage, title, ITEM_TYPE_ICON, "", -1, "", "", null)
homeScreenGridItems.add(SMSMessengerIcon) homeScreenGridItems.add(SMSMessengerIcon)
} }
} catch (e: Exception) { } catch (e: Exception) {
@ -549,7 +615,7 @@ class MainActivity : SimpleActivity(), FlingListener {
val defaultBrowserPackage = resolveInfo!!.activityInfo.packageName val defaultBrowserPackage = resolveInfo!!.activityInfo.packageName
appLaunchers.firstOrNull { it.packageName == defaultBrowserPackage }?.apply { appLaunchers.firstOrNull { it.packageName == defaultBrowserPackage }?.apply {
val browserIcon = val browserIcon =
HomeScreenGridItem(null, 2, ROW_COUNT - 1, 2, ROW_COUNT - 1, defaultBrowserPackage, title, ITEM_TYPE_ICON, "", -1, "", null) HomeScreenGridItem(null, 2, ROW_COUNT - 1, 2, ROW_COUNT - 1, defaultBrowserPackage, title, ITEM_TYPE_ICON, "", -1, "", "", null)
homeScreenGridItems.add(browserIcon) homeScreenGridItems.add(browserIcon)
} }
} catch (e: Exception) { } catch (e: Exception) {
@ -560,7 +626,7 @@ class MainActivity : SimpleActivity(), FlingListener {
val storePackage = potentialStores.firstOrNull { isPackageInstalled(it) && appLaunchers.map { it.packageName }.contains(it) } val storePackage = potentialStores.firstOrNull { isPackageInstalled(it) && appLaunchers.map { it.packageName }.contains(it) }
if (storePackage != null) { if (storePackage != null) {
appLaunchers.firstOrNull { it.packageName == storePackage }?.apply { appLaunchers.firstOrNull { it.packageName == storePackage }?.apply {
val storeIcon = HomeScreenGridItem(null, 3, ROW_COUNT - 1, 3, ROW_COUNT - 1, storePackage, title, ITEM_TYPE_ICON, "", -1, "", null) val storeIcon = HomeScreenGridItem(null, 3, ROW_COUNT - 1, 3, ROW_COUNT - 1, storePackage, title, ITEM_TYPE_ICON, "", -1, "", "", null)
homeScreenGridItems.add(storeIcon) homeScreenGridItems.add(storeIcon)
} }
} }
@ -572,7 +638,7 @@ class MainActivity : SimpleActivity(), FlingListener {
val resolveInfo = packageManager.resolveActivity(cameraIntent, PackageManager.MATCH_DEFAULT_ONLY) val resolveInfo = packageManager.resolveActivity(cameraIntent, PackageManager.MATCH_DEFAULT_ONLY)
val defaultCameraPackage = resolveInfo!!.activityInfo.packageName val defaultCameraPackage = resolveInfo!!.activityInfo.packageName
appLaunchers.firstOrNull { it.packageName == defaultCameraPackage }?.apply { appLaunchers.firstOrNull { it.packageName == defaultCameraPackage }?.apply {
val cameraIcon = HomeScreenGridItem(null, 4, ROW_COUNT - 1, 4, ROW_COUNT - 1, defaultCameraPackage, title, ITEM_TYPE_ICON, "", -1, "", null) val cameraIcon = HomeScreenGridItem(null, 4, ROW_COUNT - 1, 4, ROW_COUNT - 1, defaultCameraPackage, title, ITEM_TYPE_ICON, "", -1, "", "", null)
homeScreenGridItems.add(cameraIcon) homeScreenGridItems.add(cameraIcon)
} }
} catch (e: Exception) { } catch (e: Exception) {
@ -581,7 +647,12 @@ class MainActivity : SimpleActivity(), FlingListener {
homeScreenGridItemsDB.insertAll(homeScreenGridItems) homeScreenGridItemsDB.insertAll(homeScreenGridItems)
} }
fun handleWidgetBinding(appWidgetManager: AppWidgetManager, appWidgetId: Int, appWidgetInfo: AppWidgetProviderInfo, callback: (canBind: Boolean) -> Unit) { fun handleWidgetBinding(
appWidgetManager: AppWidgetManager,
appWidgetId: Int,
appWidgetInfo: AppWidgetProviderInfo,
callback: (canBind: Boolean) -> Unit
) {
mActionOnCanBindWidget = null mActionOnCanBindWidget = null
val canCreateWidget = appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, appWidgetInfo.provider) val canCreateWidget = appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, appWidgetInfo.provider)
if (canCreateWidget) { if (canCreateWidget) {

View File

@ -141,7 +141,7 @@ class AllAppsFragment(context: Context, attributeSet: AttributeSet) : MyFragment
override fun onAppLauncherLongPressed(x: Float, y: Float, appLauncher: AppLauncher) { override fun onAppLauncherLongPressed(x: Float, y: Float, appLauncher: AppLauncher) {
val gridItem = val gridItem =
HomeScreenGridItem(null, -1, -1, -1, -1, appLauncher.packageName, appLauncher.title, ITEM_TYPE_ICON, "", -1, "", null, appLauncher.drawable) HomeScreenGridItem(null, -1, -1, -1, -1, appLauncher.packageName, appLauncher.title, ITEM_TYPE_ICON, "", -1, "", "", null, appLauncher.drawable)
activity?.showHomeIconMenu(x, y, gridItem, true) activity?.showHomeIconMenu(x, y, gridItem, true)
ignoreTouches = true ignoreTouches = true
} }

View File

@ -241,6 +241,7 @@ class WidgetsFragment(context: Context, attributeSet: AttributeSet) : MyFragment
appWidget.className, appWidget.className,
-1, -1,
"", "",
"",
null, null,
appWidget.widgetPreviewImage, appWidget.widgetPreviewImage,
appWidget.providerInfo, appWidget.providerInfo,

View File

@ -1,14 +1,13 @@
package com.simplemobiletools.launcher.models package com.simplemobiletools.launcher.models
import android.appwidget.AppWidgetProviderInfo import android.appwidget.AppWidgetProviderInfo
import android.content.ComponentName
import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import androidx.room.* import androidx.room.*
import com.simplemobiletools.launcher.helpers.ITEM_TYPE_ICON import com.simplemobiletools.launcher.helpers.ITEM_TYPE_ICON
// grid cells are from 0-5 by default. Icons occupy 1 slot only, widgets can be bigger // grid cells are from 0-5 by default. Icons and shortcuts occupy 1 slot only, widgets can be bigger
@Entity(tableName = "home_screen_grid_items", indices = [(Index(value = ["id"], unique = true))]) @Entity(tableName = "home_screen_grid_items", indices = [(Index(value = ["id"], unique = true))])
data class HomeScreenGridItem( data class HomeScreenGridItem(
@PrimaryKey(autoGenerate = true) var id: Long?, @PrimaryKey(autoGenerate = true) var id: Long?,
@ -21,8 +20,9 @@ data class HomeScreenGridItem(
@ColumnInfo(name = "type") var type: Int, @ColumnInfo(name = "type") var type: Int,
@ColumnInfo(name = "class_name") var className: String, @ColumnInfo(name = "class_name") var className: String,
@ColumnInfo(name = "widget_id") var widgetId: Int, @ColumnInfo(name = "widget_id") var widgetId: Int,
@ColumnInfo(name = "intent") var intent: String, // used at shortcuts on click @ColumnInfo(name = "intent") var intent: String, // used at static and dynamic shortcuts on click
@ColumnInfo(name = "icon") var icon: Bitmap? = null, // store only images of shortcuts, those cannot be retrieved anytime @ColumnInfo(name = "shortcut_id") var shortcutId: String, // used at pinned shortcuts at startLauncher call
@ColumnInfo(name = "icon") var icon: Bitmap? = null, // store images of pinned shortcuts, those cannot be retrieved after creating
@Ignore var drawable: Drawable? = null, @Ignore var drawable: Drawable? = null,
@Ignore var providerInfo: AppWidgetProviderInfo? = null, // used at widgets @Ignore var providerInfo: AppWidgetProviderInfo? = null, // used at widgets
@ -30,7 +30,7 @@ data class HomeScreenGridItem(
@Ignore var widthCells: Int = 1, @Ignore var widthCells: Int = 1,
@Ignore var heightCells: Int = 1 @Ignore var heightCells: Int = 1
) { ) {
constructor() : this(null, -1, -1, -1, -1, "", "", ITEM_TYPE_ICON, "", -1, "", null, null, null, null, 1, 1) constructor() : this(null, -1, -1, -1, -1, "", "", ITEM_TYPE_ICON, "", -1, "", "", null, null, null, null, 1, 1)
fun getWidthInCells() = if (right == -1 || left == -1) { fun getWidthInCells() = if (right == -1 || left == -1) {
widthCells widthCells
@ -43,6 +43,4 @@ data class HomeScreenGridItem(
} else { } else {
bottom - top + 1 bottom - top + 1
} }
fun getComponentName() = ComponentName(activityInfo?.packageName ?: "", activityInfo?.name ?: "")
} }

View File

@ -283,6 +283,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
"", "",
-1, -1,
"", "",
"",
draggedItem!!.icon, draggedItem!!.icon,
draggedItem!!.drawable, draggedItem!!.drawable,
draggedItem!!.providerInfo, draggedItem!!.providerInfo,
@ -299,7 +300,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
newHomeScreenGridItem.title = label newHomeScreenGridItem.title = label
newHomeScreenGridItem.icon = icon newHomeScreenGridItem.icon = icon
newHomeScreenGridItem.intent = intent newHomeScreenGridItem.intent = intent
newHomeScreenGridItem.drawable = BitmapDrawable(newHomeScreenGridItem.icon) newHomeScreenGridItem.drawable = BitmapDrawable(icon)
storeAndShowGridItem(newHomeScreenGridItem) storeAndShowGridItem(newHomeScreenGridItem)
} }
} }
@ -318,7 +319,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
} }
} }
private fun storeAndShowGridItem(item: HomeScreenGridItem) { fun storeAndShowGridItem(item: HomeScreenGridItem) {
val newId = context.homeScreenGridItemsDB.insert(item) val newId = context.homeScreenGridItemsDB.insert(item)
item.id = newId item.id = newId
gridItems.add(item) gridItems.add(item)
@ -642,7 +643,7 @@ class HomeScreenGrid(context: Context, attrs: AttributeSet, defStyle: Int) : Rel
} }
// get the clickable area around the icon, it includes text too // get the clickable area around the icon, it includes text too
private fun getClickableRect(item: HomeScreenGridItem): Rect { fun getClickableRect(item: HomeScreenGridItem): Rect {
if (cellXCoords.isEmpty()) { if (cellXCoords.isEmpty()) {
fillCellSizes() fillCellSizes()
} }