DEV Community

myougaTheAxo
myougaTheAxo

Posted on

Android App Signing & Glance Widgets — Release & Home Screen Guide

Android App Signing & Glance Widgets — Release & Home Screen Guide

Building production Android apps requires two critical layers: secure app signing for Play Store releases and home screen widgets for user engagement. Here's how to implement both.

Part 1: Android App Signing

Understanding App Signing

App signing proves your app's authenticity. Google Play requires all APKs to be signed with your app signing key. There are two key types:

  1. Upload key - Signs APKs you upload to Play Console
  2. App signing key - Signs apps delivered to users (managed by Google Play)

Step 1: Create a Keystore with Keytool

Generate a keystore containing your upload key:

keytool -genkey -v -keystore release.keystore \
  -keyalg RSA -keysize 2048 -validity 10000 \
  -alias upload_key -storepass your_store_pass \
  -keypass your_key_pass \
  -dname "CN=Your Name, O=Your Company, L=City, ST=State, C=US"
Enter fullscreen mode Exit fullscreen mode

Parameters:

  • -keyalg RSA: RSA encryption algorithm (industry standard)
  • -keysize 2048: 2048-bit key strength
  • -validity 10000: Valid for ~27 years
  • -alias upload_key: Identifier for this key pair
  • -dname: Your identity information

Step 2: Configure Signing in build.gradle.kts

Store credentials securely using environment variables:

android {
    signingConfigs {
        create("release") {
            storeFile = file(System.getenv("KEYSTORE_PATH") ?: "release.keystore")
            storePassword = System.getenv("KEYSTORE_PASSWORD")
            keyAlias = System.getenv("KEY_ALIAS") ?: "upload_key"
            keyPassword = System.getenv("KEY_PASSWORD")
        }
    }

    buildTypes {
        release {
            signingConfig = signingConfigs.getByName("release")
            minifyEnabled = true
            shrinkResources = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Why environment variables?

  • Never commit keystores or passwords to git
  • CI/CD pipelines inject credentials safely
  • Local development stays secure

Step 3: Build AAB for Play Store

Android App Bundles (AAB) optimize app size by device:

./gradlew bundleRelease
Enter fullscreen mode Exit fullscreen mode

AAB location: app/build/outputs/bundle/release/app-release.aab

Benefits over APK:

  • 15-35% smaller downloads (users get only their device's resources)
  • Dynamic delivery for on-demand features
  • Required by Google Play for new apps

Step 4: Play App Signing Benefits

When you enable Play App Signing:

  1. Google manages your app key - Protects against compromise
  2. Key rotation without updates - Google can re-sign apps if needed
  3. Enrollment requirement - All Play Store apps since 2021
  4. Two-key model - Upload key (you) + app key (Google)

Play Console automatically generates your app signing certificate. You keep the upload key; Google uses the app key for delivery.


Part 2: Glance Widgets

What is Glance?

Glance API provides a declarative, Compose-like framework for Android home screen widgets with:

  • Real-time updates
  • Interactive elements
  • Simplified state management
  • No XML layouts needed

Step 1: Add Glance Dependency

In build.gradle.kts:

dependencies {
    implementation "androidx.glance:glance-appwidget:1.0.0"
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Create a GlanceAppWidget

import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.provideContent
import androidx.compose.runtime.Composable
import androidx.glance.text.Text
import androidx.glance.layout.Column
import androidx.glance.GlanceModifier

class MyAppWidget : GlanceAppWidget() {
    override suspend fun provideContent() {
        provideContent {
            MyWidgetContent()
        }
    }
}

@Composable
fun MyWidgetContent() {
    Column(modifier = GlanceModifier.fillMaxSize()) {
        Text("Hello, Home Screen!")
        Text("Widget Update Time")
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Add Widget Receiver to AndroidManifest.xml

<receiver
    android:name=".MyAppWidgetReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data
        android:name="android.appwidget.provider"
        android:resource="@xml/app_widget_info" />
</receiver>
Enter fullscreen mode Exit fullscreen mode

Step 4: Create Widget Receiver

import androidx.glance.appwidget.GlanceAppWidgetReceiver

class MyAppWidgetReceiver : GlanceAppWidgetReceiver() {
    override val glanceAppWidget: GlanceAppWidget = MyAppWidget()
}
Enter fullscreen mode Exit fullscreen mode

Step 5: Add Interactive Elements with actionRunCallback

import androidx.glance.action.actionRunCallback
import androidx.glance.action.ActionParameters
import androidx.glance.Button
import androidx.glance.appwidget.updateAll

class ClickAction : ActionCallback {
    override suspend fun onAction(
        context: Context,
        glanceId: GlanceId,
        parameters: ActionParameters
    ) {
        MyAppWidget().updateData(context, glanceId)
        MyAppWidget().updateAll(context)
    }
}

@Composable
fun InteractiveWidget() {
    Button(
        text = "Update",
        onClick = actionRunCallback<ClickAction>()
    )
}
Enter fullscreen mode Exit fullscreen mode

Step 6: Create Widget Info XML

Create res/xml/app_widget_info.xml:

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="250dp"
    android:minHeight="110dp"
    android:updatePeriodMillis="86400000"
    android:previewImage="@drawable/widget_preview"
    android:initialLayout="@layout/widget_layout"
    android:description="@string/app_widget_description"
    android:widgetCategory="home_screen" />
Enter fullscreen mode Exit fullscreen mode

Comparison: Widget Frameworks

Feature Glance RemoteViews Jetpack Compose
Syntax Declarative Compose-like XML layouts Compose DSL
Learning curve Easy (Compose familiar) Moderate Easy (Android dev)
Real-time updates Native support Manual polling Via ViewModel
Interactive actions actionRunCallback PendingIntent Built-in
Size limit 1MB 1MB 1MB

Best Practices

  1. Sign with Play App Signing - Let Google manage your app key
  2. Use AAB format - Smaller downloads, required by Play Store
  3. Store keystores outside git - Use .gitignore and env vars
  4. Widget updates - Use updatePeriodMillis conservatively (battery impact)
  5. Test on devices - Widget behavior varies by launcher and Android version

Key Takeaways

  • Signing: Keytool + signingConfigs + AAB = secure, optimized releases
  • Glance: GlanceAppWidget + provideContent + actionRunCallback = simple, powerful widgets
  • Security: Environment variables for credentials, Google manages app key
  • Performance: AAB delivers 15-35% smaller app sizes

8 Android App Templates ready to customize → myougatheax.gumroad.com

Top comments (0)