Initial commit: Minimal Flutter timer with push notifications
This commit is contained in:
65
android/app/build.gradle
Normal file
65
android/app/build.gradle
Normal file
@@ -0,0 +1,65 @@
|
||||
plugins {
|
||||
id "com.android.application"
|
||||
id "kotlin-android"
|
||||
id "dev.flutter.flutter-gradle-plugin"
|
||||
}
|
||||
|
||||
def localProperties = new Properties()
|
||||
def localPropertiesFile = rootProject.file('local.properties')
|
||||
if (localPropertiesFile.exists()) {
|
||||
localPropertiesFile.withReader('UTF-8') { reader ->
|
||||
localProperties.load(reader)
|
||||
}
|
||||
}
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = '1'
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty('flutter.versionName')
|
||||
if (flutterVersionName == null) {
|
||||
flutterVersionName = '1.0'
|
||||
}
|
||||
|
||||
def javaVersion = JavaVersion.VERSION_17
|
||||
|
||||
android {
|
||||
namespace "com.example.timer"
|
||||
compileSdk 34
|
||||
ndkVersion flutter.ndkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility javaVersion
|
||||
targetCompatibility javaVersion
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = javaVersion.toString()
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/java'
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.example.timer"
|
||||
minSdkVersion flutter.minSdkVersion
|
||||
targetSdk 34
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source '../..'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
}
|
||||
42
android/app/src/main/AndroidManifest.xml
Normal file
42
android/app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.timer">
|
||||
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
|
||||
<application
|
||||
android:label="Таймер"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@drawable/ic_launcher_foreground">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
|
||||
<receiver
|
||||
android:name="com.dexterous.flutterlocalnotifications.NotificationActionReceiver"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="ACTION_NOTIFICATION_TRIGGERED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.example.timer;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class MainActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Launch Flutter activity using reflection
|
||||
try {
|
||||
Class<?> flutterActivityClass = Class.forName("io.flutter.embedding.android.FlutterActivity");
|
||||
Intent intent = new Intent(this, flutterActivityClass);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// FlutterActivity not found - handle gracefully
|
||||
e.printStackTrace();
|
||||
}
|
||||
finish();
|
||||
}
|
||||
}
|
||||
16
android/app/src/main/res/drawable/ic_launcher_foreground.xml
Normal file
16
android/app/src/main/res/drawable/ic_launcher_foreground.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M54,30
|
||||
A24,24 0 1,1 53.99,30
|
||||
M54,36
|
||||
A18,18 0 1,0 54.01,36"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M54,42 L54,54 L66,54"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
20
android/app/src/main/res/mipmap-hdpi/ic_launcher.xml
Normal file
20
android/app/src/main/res/mipmap-hdpi/ic_launcher.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="48dp"
|
||||
android:height="48dp"
|
||||
android:viewportWidth="48"
|
||||
android:viewportHeight="48">
|
||||
<path
|
||||
android:fillColor="#6200EE"
|
||||
android:pathData="M0,0h48v48h-48z"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M24,8
|
||||
A16,16 0 1,1 23.99,8
|
||||
M24,12
|
||||
A12,12 0 1,0 24.01,12"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:strokeWidth="2"
|
||||
android:pathData="M24,16 L24,24 L32,24"/>
|
||||
</vector>
|
||||
20
android/app/src/main/res/mipmap-mdpi/ic_launcher.xml
Normal file
20
android/app/src/main/res/mipmap-mdpi/ic_launcher.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="48dp"
|
||||
android:height="48dp"
|
||||
android:viewportWidth="48"
|
||||
android:viewportHeight="48">
|
||||
<path
|
||||
android:fillColor="#6200EE"
|
||||
android:pathData="M0,0h48v48h-48z"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M24,8
|
||||
A16,16 0 1,1 23.99,8
|
||||
M24,12
|
||||
A12,12 0 1,0 24.01,12"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:strokeWidth="2"
|
||||
android:pathData="M24,16 L24,24 L32,24"/>
|
||||
</vector>
|
||||
20
android/app/src/main/res/mipmap-xhdpi/ic_launcher.xml
Normal file
20
android/app/src/main/res/mipmap-xhdpi/ic_launcher.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="48dp"
|
||||
android:height="48dp"
|
||||
android:viewportWidth="48"
|
||||
android:viewportHeight="48">
|
||||
<path
|
||||
android:fillColor="#6200EE"
|
||||
android:pathData="M0,0h48v48h-48z"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M24,8
|
||||
A16,16 0 1,1 23.99,8
|
||||
M24,12
|
||||
A12,12 0 1,0 24.01,12"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:strokeWidth="2"
|
||||
android:pathData="M24,16 L24,24 L32,24"/>
|
||||
</vector>
|
||||
20
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.xml
Normal file
20
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="48dp"
|
||||
android:height="48dp"
|
||||
android:viewportWidth="48"
|
||||
android:viewportHeight="48">
|
||||
<path
|
||||
android:fillColor="#6200EE"
|
||||
android:pathData="M0,0h48v48h-48z"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M24,8
|
||||
A16,16 0 1,1 23.99,8
|
||||
M24,12
|
||||
A12,12 0 1,0 24.01,12"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:strokeWidth="2"
|
||||
android:pathData="M24,16 L24,24 L32,24"/>
|
||||
</vector>
|
||||
20
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.xml
Normal file
20
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="48dp"
|
||||
android:height="48dp"
|
||||
android:viewportWidth="48"
|
||||
android:viewportHeight="48">
|
||||
<path
|
||||
android:fillColor="#6200EE"
|
||||
android:pathData="M0,0h48v48h-48z"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M24,8
|
||||
A16,16 0 1,1 23.99,8
|
||||
M24,12
|
||||
A12,12 0 1,0 24.01,12"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:strokeWidth="2"
|
||||
android:pathData="M24,16 L24,24 L32,24"/>
|
||||
</vector>
|
||||
4
android/app/src/main/res/values/colors.xml
Normal file
4
android/app/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#6200EE</color>
|
||||
</resources>
|
||||
9
android/app/src/main/res/values/styles.xml
Normal file
9
android/app/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">@android:color/white</item>
|
||||
</style>
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">@android:color/white</item>
|
||||
</style>
|
||||
</resources>
|
||||
41
android/build.gradle
Normal file
41
android/build.gradle
Normal file
@@ -0,0 +1,41 @@
|
||||
def flutterSdkPath = System.env.FLUTTER_SDK ?: System.properties['flutter.sdk']
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.8.22'
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.1.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.buildDir = '../build'
|
||||
subprojects {
|
||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||
}
|
||||
subprojects {
|
||||
project.evaluationDependsOn(':app')
|
||||
}
|
||||
|
||||
tasks.register("clean", Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
||||
String flutterProjectRoot = rootProject.projectDir.parentFile.toPath().normalize().toString()
|
||||
|
||||
File pluginsFile = new File(flutterProjectRoot, '.flutter-plugins')
|
||||
if (pluginsFile.exists()) {
|
||||
pluginsFile.text.eachLine { line ->
|
||||
def pluginDef = line.split('=')
|
||||
if (pluginDef.length == 2) {
|
||||
def pluginName = pluginDef[0]
|
||||
def pluginPath = pluginDef[1]
|
||||
include ":$pluginName"
|
||||
project(":$pluginName").projectDir = new File(pluginPath, 'android')
|
||||
}
|
||||
}
|
||||
}
|
||||
3
android/gradle.properties
Normal file
3
android/gradle.properties
Normal file
@@ -0,0 +1,3 @@
|
||||
org.gradle.jvmargs=-Xmx4G
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Executable file
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Executable file
Binary file not shown.
5
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip
|
||||
1
android/gradlew
vendored
Symbolic link
1
android/gradlew
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
gradlew.bat
|
||||
90
android/gradlew.bat
vendored
Executable file
90
android/gradlew.bat
vendored
Executable file
@@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
5
android/gradlew.sh
Normal file
5
android/gradlew.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
cd "$(dirname "$0")"
|
||||
export ANDROID_HOME=$HOME/android-sdk
|
||||
export FLUTTER_SDK=$HOME/bin/flutter
|
||||
exec /home/minimax/bin/jdk-17.0.17+10/bin/java -classpath gradle/wrapper/gradle-wrapper.jar org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
26
android/settings.gradle
Normal file
26
android/settings.gradle
Normal file
@@ -0,0 +1,26 @@
|
||||
pluginManagement {
|
||||
def flutterSdkPath = System.env.FLUTTER_SDK ?: System.properties['flutter.sdk']
|
||||
assert flutterSdkPath != null, "FLUTTER_SDK not set. Run: export FLUTTER_SDK=/path/to/flutter"
|
||||
|
||||
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven {
|
||||
url "https://storage.googleapis.com/download.flutter.io"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = 'minimal_timer'
|
||||
include(':app')
|
||||
Reference in New Issue
Block a user