#!/bin/bash if [ "$#" -ne 2 ]; then echo "USAGE: $0 APP_NAME DESCRIPTION" exit 1 fi PROJECT_HOME=~/AndroidStudioProjects ORG_PATH="$PROJECT_HOME/defaultOrg" KEY_PROPERTIES_PATH="$PROJECT_HOME/defaultKeyProperties" appName="$1" packageName=`echo "$appName" | tr ' ' '_' | tr '[:upper:]' '[:lower:]'` description="$2" echo "App Name: $appName" echo "Package Name: $packageName" echo "Description: $description" if [[ -f "$ORG_PATH" ]]; then org=`cat "$PROJECT_HOME/defaultOrg"` else echo "Could not find file with default org in $ORG_PATH" exit 1 fi if [[ -f "$KEY_PROPERTIES_PATH" ]]; then keyProperties=`cat "$PROJECT_HOME/defaultKeyProperties"` else echo "Could not find file with default key properties in $KEY_PROPERTIES_PATH" exit 1 fi flutter create --android-language java --org "$org" "$packageName" || exit 1 cd "$packageName" ########################## ## append to .gitignore ## ########################## echo "android/key.properties" >> .gitignore git init ################################## ## generate empty launcher icon ## ################################## convert -size 2048x2048 xc:white LauncherIcon.png ############################ ## overwrite pubspec.yaml ## ############################ cat > pubspec.yaml <<EOF name: $packageName description: $description version: 1.0.0+1 environment: sdk: ">=2.2.2 <3.0.0" dependencies: flutter: sdk: flutter intl: ^0.15.7 shared_preferences: ^0.5.4+8 cupertino_icons: ^0.1.2 dev_dependencies: flutter_test: sdk: flutter flutter_launcher_icons: "^0.7.3" flutter_icons: image_path: "LauncherIcon.png" android: true ios: true flutter: uses-material-design: true EOF ######################################### ## generate key.properties for signing ## ######################################### cat > android/key.properties <<EOF $keyProperties EOF ############################ ## overwrite build.gradle ## ############################ cat > android/app/build.gradle <<EOF def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply from: "\$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" def keystoreProperties = new Properties() def keystorePropertiesFile = rootProject.file('key.properties') if (keystorePropertiesFile.exists()) { keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) } android { compileSdkVersion 28 lintOptions { disable 'InvalidPackage' } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "$org.$packageName" minSdkVersion 16 targetSdkVersion 28 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } signingConfigs { release { keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] storeFile file(keystoreProperties['storeFile']) storePassword keystoreProperties['storePassword'] } } buildTypes { release { signingConfig signingConfigs.release } } } flutter { source '../..' } dependencies { testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' } EOF ####################### ## set android label ## ####################### sed -i "s/android:label=\"$packageName\"/android:label=\"$appName\"/" android/app/src/main/AndroidManifest.xml ##################### ## empty README.md ## ##################### cat > README.md <<EOF # $appName $description EOF ######################### ## overwrite main.dart ## ######################### cat > lib/main.dart <<EOF import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: '$appName', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: '$appName'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int state = 1; void _changeState(int s) { setState(() { state = s; }); } List<String> popupMenuItems = ["About"]; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), actions: <Widget>[ PopupMenuButton<String>( onSelected: (String value) => handleClick(context, value), itemBuilder: (BuildContext context) { return popupMenuItems.map((String choice) { return PopupMenuItem<String>( value: choice, child: Text(choice), ); }).toList(); }, ), ], ), body: Padding( padding: const EdgeInsets.all(8.0), child: ListView(children: [ Text("Lorem ipsum dolor sit amet"), ]), ), ); } void handleClick(BuildContext context, String value) { switch (value) { case 'About': showLicensePage(context: context, applicationName: widget.title); } } } EOF ##################### ## create Makefile ## ##################### cat > Makefile <<EOF .PHONY: clean all launcherIcon all: launcherIcon flutter pub get flutter build appbundle clean: flutter clean launcherIcon: flutter pub get flutter pub run "flutter_launcher_icons:main" EOF ################ ## test build ## ################ make clean launcherIcon all make clean