├── KawaHello
├── libs
│ ├── .keepme
│ └── kawa.jar
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-ldpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── values
│ │ └── strings.xml
│ └── layout
│ │ └── main.xml
├── make-and-send
├── project.properties
├── local.properties
├── AndroidManifest.xml
├── ant.properties
├── src
│ └── kawa
│ │ └── android
│ │ └── hello.scm
└── build.xml
├── LunarLander
├── libs
│ ├── .keepme
│ └── kawa.jar
├── res
│ ├── drawable
│ │ ├── lander_plain.png
│ │ ├── lander_crashed.png
│ │ ├── lander_firing.png
│ │ └── app_lunar_lander.png
│ ├── drawable-land
│ │ └── earthrise.png
│ ├── drawable-port
│ │ └── earthrise.png
│ ├── layout
│ │ └── main.xml
│ └── values
│ │ └── strings.xml
├── make-and-send
├── project.properties
├── local.properties
├── AndroidManifest.xml
├── ant.properties
└── build.xml
├── LearningAndroid-chapter10
├── libs
│ ├── .keepme
│ └── kawa.jar
├── res
│ ├── drawable
│ │ ├── icon.png
│ │ └── background.png
│ ├── xml
│ │ └── prefs.xml
│ ├── layout
│ │ ├── timeline.xml
│ │ ├── row.xml
│ │ └── status.xml
│ ├── menu
│ │ └── menu.xml
│ └── values
│ │ └── strings.xml
├── make-and-send
├── project.properties
├── local.properties
├── ant.properties
├── AndroidManifest.xml
├── build.xml
└── src
│ └── com
│ └── zeroxab
│ └── learningandroid
│ └── yamba
│ ├── collections_utils.scm
│ └── Yamba.scm
├── LearningAndroid-chapter6
├── libs
│ ├── .keepme
│ └── kawa.jar
├── res
│ ├── drawable
│ │ ├── icon.png
│ │ └── background.png
│ ├── values
│ │ └── strings.xml
│ └── layout
│ │ └── status.xml
├── make-and-send
├── project.properties
├── local.properties
├── ant.properties
├── AndroidManifest.xml
├── src
│ └── com
│ │ └── zeroxab
│ │ └── learningandroid
│ │ └── yamba
│ │ └── Yamba.scm
└── build.xml
├── LearningAndroid-chapter7
├── libs
│ ├── .keepme
│ └── kawa.jar
├── res
│ ├── drawable
│ │ ├── icon.png
│ │ └── background.png
│ ├── menu
│ │ └── menu.xml
│ ├── xml
│ │ └── prefs.xml
│ ├── values
│ │ └── strings.xml
│ └── layout
│ │ └── status.xml
├── make-and-send
├── project.properties
├── local.properties
├── ant.properties
├── AndroidManifest.xml
├── build.xml
└── src
│ └── com
│ └── zeroxab
│ └── learningandroid
│ └── yamba
│ └── Yamba.scm
├── LearningAndroid-chapter8
├── libs
│ ├── .keepme
│ └── kawa.jar
├── res
│ ├── drawable
│ │ ├── icon.png
│ │ └── background.png
│ ├── menu
│ │ └── menu.xml
│ ├── xml
│ │ └── prefs.xml
│ ├── values
│ │ └── strings.xml
│ └── layout
│ │ └── status.xml
├── make-and-send
├── project.properties
├── local.properties
├── ant.properties
├── AndroidManifest.xml
├── build.xml
└── src
│ └── com
│ └── zeroxab
│ └── learningandroid
│ └── yamba
│ ├── collections_utils.scm
│ └── Yamba.scm
├── LearningAndroid-chapter9
├── libs
│ ├── .keepme
│ └── kawa.jar
├── res
│ ├── drawable
│ │ ├── icon.png
│ │ └── background.png
│ ├── menu
│ │ └── menu.xml
│ ├── xml
│ │ └── prefs.xml
│ ├── values
│ │ └── strings.xml
│ └── layout
│ │ └── status.xml
├── make-and-send
├── project.properties
├── local.properties
├── ant.properties
├── AndroidManifest.xml
├── build.xml
└── src
│ └── com
│ └── zeroxab
│ └── learningandroid
│ └── yamba
│ ├── collections_utils.scm
│ └── Yamba.scm
├── SpeedRead
├── libs
│ └── kawa.jar
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-ldpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── values
│ │ └── strings.xml
│ └── layout
│ │ ├── main.xml
│ │ └── player.xml
├── make-and-send
├── src
│ └── zeroxab
│ │ └── speedread
│ │ └── speedread.java
├── local.properties
├── project.properties
├── ant.properties
├── proguard-project.txt
├── AndroidManifest.xml
└── build.xml
├── libkawadroid
├── libs
│ └── kawa.jar
├── local.properties
├── project.properties
├── build.xml
└── src
│ └── com
│ └── zeroxab
│ └── libkawadroid
│ └── misc.scm
├── bin
├── start-emulator
├── colorize-adb-logcat
├── setup-kawa
└── make-project
└── README.org
/KawaHello/libs/.keepme:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/LunarLander/libs/.keepme:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/libs/.keepme:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter6/libs/.keepme:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter7/libs/.keepme:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter8/libs/.keepme:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter9/libs/.keepme:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/KawaHello/libs/kawa.jar:
--------------------------------------------------------------------------------
1 | ../../kawa/kawa.jar
--------------------------------------------------------------------------------
/SpeedRead/libs/kawa.jar:
--------------------------------------------------------------------------------
1 | ../../kawa/kawa.jar
--------------------------------------------------------------------------------
/LunarLander/libs/kawa.jar:
--------------------------------------------------------------------------------
1 | ../../kawa/kawa.jar
--------------------------------------------------------------------------------
/libkawadroid/libs/kawa.jar:
--------------------------------------------------------------------------------
1 | ../../kawa/kawa.jar
--------------------------------------------------------------------------------
/bin/start-emulator:
--------------------------------------------------------------------------------
1 | emulator -avd Test -qemu -sdl
2 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/libs/kawa.jar:
--------------------------------------------------------------------------------
1 | ../../kawa/kawa.jar
--------------------------------------------------------------------------------
/LearningAndroid-chapter6/libs/kawa.jar:
--------------------------------------------------------------------------------
1 | ../../kawa/kawa.jar
--------------------------------------------------------------------------------
/LearningAndroid-chapter7/libs/kawa.jar:
--------------------------------------------------------------------------------
1 | ../../kawa/kawa.jar
--------------------------------------------------------------------------------
/LearningAndroid-chapter8/libs/kawa.jar:
--------------------------------------------------------------------------------
1 | ../../kawa/kawa.jar
--------------------------------------------------------------------------------
/LearningAndroid-chapter9/libs/kawa.jar:
--------------------------------------------------------------------------------
1 | ../../kawa/kawa.jar
--------------------------------------------------------------------------------
/LunarLander/res/drawable/lander_plain.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/LunarLander/res/drawable/lander_plain.png
--------------------------------------------------------------------------------
/KawaHello/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/KawaHello/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/KawaHello/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/KawaHello/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/KawaHello/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/KawaHello/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/LunarLander/res/drawable-land/earthrise.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/LunarLander/res/drawable-land/earthrise.png
--------------------------------------------------------------------------------
/LunarLander/res/drawable-port/earthrise.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/LunarLander/res/drawable-port/earthrise.png
--------------------------------------------------------------------------------
/LunarLander/res/drawable/lander_crashed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/LunarLander/res/drawable/lander_crashed.png
--------------------------------------------------------------------------------
/LunarLander/res/drawable/lander_firing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/LunarLander/res/drawable/lander_firing.png
--------------------------------------------------------------------------------
/SpeedRead/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/SpeedRead/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/SpeedRead/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/SpeedRead/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/SpeedRead/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/SpeedRead/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/SpeedRead/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/SpeedRead/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/LearningAndroid-chapter6/res/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/LearningAndroid-chapter6/res/drawable/icon.png
--------------------------------------------------------------------------------
/LearningAndroid-chapter7/res/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/LearningAndroid-chapter7/res/drawable/icon.png
--------------------------------------------------------------------------------
/LearningAndroid-chapter8/res/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/LearningAndroid-chapter8/res/drawable/icon.png
--------------------------------------------------------------------------------
/LearningAndroid-chapter9/res/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/LearningAndroid-chapter9/res/drawable/icon.png
--------------------------------------------------------------------------------
/LunarLander/res/drawable/app_lunar_lander.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/LunarLander/res/drawable/app_lunar_lander.png
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/res/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/LearningAndroid-chapter10/res/drawable/icon.png
--------------------------------------------------------------------------------
/KawaHello/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | hello
4 |
5 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/res/drawable/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/LearningAndroid-chapter10/res/drawable/background.png
--------------------------------------------------------------------------------
/LearningAndroid-chapter6/res/drawable/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/LearningAndroid-chapter6/res/drawable/background.png
--------------------------------------------------------------------------------
/LearningAndroid-chapter7/res/drawable/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/LearningAndroid-chapter7/res/drawable/background.png
--------------------------------------------------------------------------------
/LearningAndroid-chapter8/res/drawable/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/LearningAndroid-chapter8/res/drawable/background.png
--------------------------------------------------------------------------------
/LearningAndroid-chapter9/res/drawable/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/abarbu/android-kawa/HEAD/LearningAndroid-chapter9/res/drawable/background.png
--------------------------------------------------------------------------------
/KawaHello/make-and-send:
--------------------------------------------------------------------------------
1 | adb shell kill $(adb shell ps|grep -i kawa.android|awk '{ print $2 }')
2 | ant debug && adb install -r bin/KawaHello-debug.apk && adb shell am start -a android.intent.action.MAIN kawa.android/.hello
--------------------------------------------------------------------------------
/LunarLander/make-and-send:
--------------------------------------------------------------------------------
1 | adb shell kill $(adb shell ps|grep -i com.zeroxab.lunarlander|awk '{ print $2 }')
2 | ant debug && adb install -r bin/LunarLander-debug.apk && adb shell am start -a android.intent.action.MAIN com.zeroxab.lunarlander/.LunarLander
--------------------------------------------------------------------------------
/SpeedRead/make-and-send:
--------------------------------------------------------------------------------
1 | adb shell kill $(adb shell ps|grep -i zeroxab.speedread|awk '{ print SpeedRead }') > /dev/null
2 | ant debug && adb install -r bin/SpeedRead-debug.apk && adb shell am start -a android.intent.action.MAIN zeroxab.speedread/.speedread
3 |
--------------------------------------------------------------------------------
/SpeedRead/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | speedread
4 | loading ...
5 | location
6 |
7 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter6/make-and-send:
--------------------------------------------------------------------------------
1 | adb shell kill $(adb shell ps|grep -i com.zeroxab.learningandroid|awk '{ print $2 }')
2 | ant debug && adb install -r bin/LearningAndroid-debug.apk && adb shell am start -a android.intent.action.MAIN com.zeroxab.learningandroid.yamba/.StatusActivity
--------------------------------------------------------------------------------
/LearningAndroid-chapter7/make-and-send:
--------------------------------------------------------------------------------
1 | adb shell kill $(adb shell ps|grep -i com.zeroxab.learningandroid|awk '{ print $2 }')
2 | ant debug && adb install -r bin/LearningAndroid-debug.apk && adb shell am start -a android.intent.action.MAIN com.zeroxab.learningandroid.yamba/.StatusActivity
--------------------------------------------------------------------------------
/LearningAndroid-chapter8/make-and-send:
--------------------------------------------------------------------------------
1 | adb shell kill $(adb shell ps|grep -i com.zeroxab.learningandroid|awk '{ print $2 }')
2 | ant debug && adb install -r bin/LearningAndroid-debug.apk && adb shell am start -a android.intent.action.MAIN com.zeroxab.learningandroid.yamba/.StatusActivity
--------------------------------------------------------------------------------
/LearningAndroid-chapter9/make-and-send:
--------------------------------------------------------------------------------
1 | adb shell kill $(adb shell ps|grep -i com.zeroxab.learningandroid|awk '{ print $2 }')
2 | ant debug && adb install -r bin/LearningAndroid-debug.apk && adb shell am start -a android.intent.action.MAIN com.zeroxab.learningandroid.yamba/.StatusActivity
--------------------------------------------------------------------------------
/LearningAndroid-chapter7/res/menu/menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/make-and-send:
--------------------------------------------------------------------------------
1 | adb shell kill $(adb shell ps|grep -i com.zeroxab.learningandroid|awk '{ print $2 }')
2 | ant debug && adb install -r bin/LearningAndroid-debug.apk && adb shell am start -a android.intent.action.MAIN com.zeroxab.learningandroid.yamba/.TimelineActivity
3 | # StatusActivity
--------------------------------------------------------------------------------
/LearningAndroid-chapter6/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | LearningAndroid
4 | LearningAndroid
5 | Status Update
6 | Please enter your 140-character status
7 | Update
8 |
9 |
--------------------------------------------------------------------------------
/KawaHello/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system use,
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 |
10 | # Project target.
11 | target=android-17
12 |
--------------------------------------------------------------------------------
/LunarLander/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system use,
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 |
10 | # Project target.
11 | target=android-14
12 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system use,
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 |
10 | # Project target.
11 | target=android-17
12 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter6/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system use,
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 |
10 | # Project target.
11 | target=android-17
12 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter7/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system use,
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 |
10 | # Project target.
11 | target=android-17
12 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter8/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system use,
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 |
10 | # Project target.
11 | target=android-17
12 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter9/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system use,
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 |
10 | # Project target.
11 | target=android-17
12 |
--------------------------------------------------------------------------------
/SpeedRead/src/zeroxab/speedread/speedread.java:
--------------------------------------------------------------------------------
1 | package zeroxab.speedread;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 |
6 | public class speedread extends Activity
7 | {
8 | /** Called when the activity is first created. */
9 | @Override
10 | public void onCreate(Bundle savedInstanceState)
11 | {
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.main);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/KawaHello/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/KawaHello/local.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked in Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 |
7 | # location of the SDK. This is only used by Ant
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | sdk.dir=/opt/android-sdk-update-manager
11 |
--------------------------------------------------------------------------------
/LunarLander/local.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked in Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 |
7 | # location of the SDK. This is only used by Ant
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | sdk.dir=/opt/android-sdk-update-manager
11 |
--------------------------------------------------------------------------------
/SpeedRead/local.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked into Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 |
7 | # location of the SDK. This is only used by Ant
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | sdk.dir=/opt/android-sdk-update-manager
11 |
--------------------------------------------------------------------------------
/libkawadroid/local.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked into Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 |
7 | # location of the SDK. This is only used by Ant
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | sdk.dir=/opt/android-sdk-update-manager
11 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/local.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked in Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 |
7 | # location of the SDK. This is only used by Ant
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | sdk.dir=/opt/android-sdk-update-manager
11 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter6/local.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked in Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 |
7 | # location of the SDK. This is only used by Ant
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | sdk.dir=/opt/android-sdk-update-manager
11 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter7/local.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked in Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 |
7 | # location of the SDK. This is only used by Ant
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | sdk.dir=/opt/android-sdk-update-manager
11 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter8/local.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked in Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 |
7 | # location of the SDK. This is only used by Ant
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | sdk.dir=/opt/android-sdk-update-manager
11 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter9/local.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked in Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 |
7 | # location of the SDK. This is only used by Ant
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | sdk.dir=/opt/android-sdk-update-manager
11 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter8/res/menu/menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter9/res/menu/menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
--------------------------------------------------------------------------------
/bin/colorize-adb-logcat:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | adb logcat | \
4 | perl -p -e '$|=1; s/^.\/NetworkStats\(.*//g' | \
5 | perl -p -e '$|=1; s/^V\//\e[01;30m/g' | # dark grey \
6 | perl -p -e '$|=1; s/^I\//\e[00;32m/g' | # dark green \
7 | perl -p -e '$|=1; s/^D\//\e[00;37m/g' | # white \
8 | perl -p -e '$|=1; s/^W\//\e[01;31m/g' | # dark red \
9 | perl -p -e '$|=1; s/^E\//\e[00;41m/g' | # red \
10 | perl -p -e '$|=1; s/^F\//\e[00;41m/g' | # red \
11 | perl -p -e '$|=1; s/^(.*?)\( *(.*?)\): +/\1,\2,/g' | \
12 | awk -F, '{ printf "%30s %5s %s\033[00;37m\n", $1, $2, $3}'
13 |
--------------------------------------------------------------------------------
/SpeedRead/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-17
15 |
--------------------------------------------------------------------------------
/libkawadroid/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-17
15 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/res/xml/prefs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
10 |
13 |
14 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter7/res/xml/prefs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
10 |
13 |
14 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter8/res/xml/prefs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
10 |
13 |
14 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter9/res/xml/prefs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
10 |
13 |
14 |
--------------------------------------------------------------------------------
/KawaHello/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/LunarLander/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/res/layout/timeline.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
11 |
14 |
15 |
--------------------------------------------------------------------------------
/KawaHello/ant.properties:
--------------------------------------------------------------------------------
1 | # This file is used to override default values used by the Ant build system.
2 | #
3 | # This file must be checked in Version Control Systems, as it is
4 | # integral to the build system of your project.
5 |
6 | # This file is only used by the Ant script.
7 |
8 | # You can use this to override default values such as
9 | # 'source.dir' for the location of your java source folder and
10 | # 'out.dir' for the location of your output folder.
11 |
12 | # You can also use it define how the release builds are signed by declaring
13 | # the following properties:
14 | # 'key.store' for the location of your keystore and
15 | # 'key.alias' for the name of the key to use.
16 | # The password will be asked during the build when you use the 'release' target.
17 |
18 |
--------------------------------------------------------------------------------
/LunarLander/ant.properties:
--------------------------------------------------------------------------------
1 | # This file is used to override default values used by the Ant build system.
2 | #
3 | # This file must be checked in Version Control Systems, as it is
4 | # integral to the build system of your project.
5 |
6 | # This file is only used by the Ant script.
7 |
8 | # You can use this to override default values such as
9 | # 'source.dir' for the location of your java source folder and
10 | # 'out.dir' for the location of your output folder.
11 |
12 | # You can also use it define how the release builds are signed by declaring
13 | # the following properties:
14 | # 'key.store' for the location of your keystore and
15 | # 'key.alias' for the name of the key to use.
16 | # The password will be asked during the build when you use the 'release' target.
17 |
18 |
--------------------------------------------------------------------------------
/SpeedRead/ant.properties:
--------------------------------------------------------------------------------
1 | # This file is used to override default values used by the Ant build system.
2 | #
3 | # This file must be checked into Version Control Systems, as it is
4 | # integral to the build system of your project.
5 |
6 | # This file is only used by the Ant script.
7 |
8 | # You can use this to override default values such as
9 | # 'source.dir' for the location of your java source folder and
10 | # 'out.dir' for the location of your output folder.
11 |
12 | # You can also use it define how the release builds are signed by declaring
13 | # the following properties:
14 | # 'key.store' for the location of your keystore and
15 | # 'key.alias' for the name of the key to use.
16 | # The password will be asked during the build when you use the 'release' target.
17 |
18 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/ant.properties:
--------------------------------------------------------------------------------
1 | # This file is used to override default values used by the Ant build system.
2 | #
3 | # This file must be checked in Version Control Systems, as it is
4 | # integral to the build system of your project.
5 |
6 | # This file is only used by the Ant script.
7 |
8 | # You can use this to override default values such as
9 | # 'source.dir' for the location of your java source folder and
10 | # 'out.dir' for the location of your output folder.
11 |
12 | # You can also use it define how the release builds are signed by declaring
13 | # the following properties:
14 | # 'key.store' for the location of your keystore and
15 | # 'key.alias' for the name of the key to use.
16 | # The password will be asked during the build when you use the 'release' target.
17 |
18 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter6/ant.properties:
--------------------------------------------------------------------------------
1 | # This file is used to override default values used by the Ant build system.
2 | #
3 | # This file must be checked in Version Control Systems, as it is
4 | # integral to the build system of your project.
5 |
6 | # This file is only used by the Ant script.
7 |
8 | # You can use this to override default values such as
9 | # 'source.dir' for the location of your java source folder and
10 | # 'out.dir' for the location of your output folder.
11 |
12 | # You can also use it define how the release builds are signed by declaring
13 | # the following properties:
14 | # 'key.store' for the location of your keystore and
15 | # 'key.alias' for the name of the key to use.
16 | # The password will be asked during the build when you use the 'release' target.
17 |
18 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter7/ant.properties:
--------------------------------------------------------------------------------
1 | # This file is used to override default values used by the Ant build system.
2 | #
3 | # This file must be checked in Version Control Systems, as it is
4 | # integral to the build system of your project.
5 |
6 | # This file is only used by the Ant script.
7 |
8 | # You can use this to override default values such as
9 | # 'source.dir' for the location of your java source folder and
10 | # 'out.dir' for the location of your output folder.
11 |
12 | # You can also use it define how the release builds are signed by declaring
13 | # the following properties:
14 | # 'key.store' for the location of your keystore and
15 | # 'key.alias' for the name of the key to use.
16 | # The password will be asked during the build when you use the 'release' target.
17 |
18 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter8/ant.properties:
--------------------------------------------------------------------------------
1 | # This file is used to override default values used by the Ant build system.
2 | #
3 | # This file must be checked in Version Control Systems, as it is
4 | # integral to the build system of your project.
5 |
6 | # This file is only used by the Ant script.
7 |
8 | # You can use this to override default values such as
9 | # 'source.dir' for the location of your java source folder and
10 | # 'out.dir' for the location of your output folder.
11 |
12 | # You can also use it define how the release builds are signed by declaring
13 | # the following properties:
14 | # 'key.store' for the location of your keystore and
15 | # 'key.alias' for the name of the key to use.
16 | # The password will be asked during the build when you use the 'release' target.
17 |
18 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter9/ant.properties:
--------------------------------------------------------------------------------
1 | # This file is used to override default values used by the Ant build system.
2 | #
3 | # This file must be checked in Version Control Systems, as it is
4 | # integral to the build system of your project.
5 |
6 | # This file is only used by the Ant script.
7 |
8 | # You can use this to override default values such as
9 | # 'source.dir' for the location of your java source folder and
10 | # 'out.dir' for the location of your output folder.
11 |
12 | # You can also use it define how the release builds are signed by declaring
13 | # the following properties:
14 | # 'key.store' for the location of your keystore and
15 | # 'key.alias' for the name of the key to use.
16 | # The password will be asked during the build when you use the 'release' target.
17 |
18 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter7/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | LearningAndroid
4 | LearningAndroid
5 |
6 | Please enter your 140-character status
7 | Update
8 |
9 | Status Update
10 | Prefs
11 | Username
12 | Password
13 | API Root
14 |
15 | Enter your username
16 | Enter your password
17 | URL of Root API
18 |
19 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/res/menu/menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter6/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/SpeedRead/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter8/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | LearningAndroid
4 | LearningAndroid
5 |
6 | Please enter your 140-character status
7 | Update
8 |
9 | Status Update
10 | Prefs
11 | Username
12 | Password
13 | API Root
14 |
15 | Stop
16 | Start
17 |
18 | Enter your username
19 | Enter your password
20 | URL of Root API
21 |
22 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter9/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | LearningAndroid
4 | LearningAndroid
5 |
6 | Please enter your 140-character status
7 | Update
8 |
9 | Status Update
10 | Prefs
11 | Username
12 | Password
13 | API Root
14 |
15 | Stop
16 | Start
17 |
18 | Enter your username
19 | Enter your password
20 | URL of Root API
21 |
22 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter7/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/LunarLander/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
15 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter8/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter9/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/res/layout/row.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
12 |
17 |
18 |
22 |
23 |
--------------------------------------------------------------------------------
/LunarLander/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Lunar Lander
4 | Start
5 | Stop
6 | Pause
7 | Resume
8 | Easy
9 | Medium
10 | Hard
11 |
12 | Lunar Lander\nPress Up To Play
13 | Paused\nPress Up To Resume
14 | Game Over\nPress Up To Play
15 | Success!\n
16 | in a row\nPress Up to Play
17 |
18 | Stopped
19 | Off Landing Pad
20 | Too Fast
21 | Bad Angle
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
18 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | LearningAndroid
4 | LearningAndroid
5 |
6 | Please enter your 140-character status
7 | Update
8 |
9 | Status Update
10 | Preferences
11 | Username
12 | Password
13 | API Root
14 | Timeline
15 | Purge
16 |
17 | Stop
18 | Start
19 |
20 | Enter your username
21 | Enter your password
22 | URL of Root API
23 |
24 | Enter username and password
25 | Data purged
26 |
27 |
--------------------------------------------------------------------------------
/SpeedRead/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/res/layout/status.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
13 |
14 |
18 |
19 |
25 |
26 |
29 |
30 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter6/res/layout/status.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
13 |
14 |
18 |
19 |
25 |
26 |
29 |
30 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter7/res/layout/status.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
13 |
14 |
18 |
19 |
25 |
26 |
29 |
30 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter8/res/layout/status.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
13 |
14 |
18 |
19 |
25 |
26 |
29 |
30 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter9/res/layout/status.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
13 |
14 |
18 |
19 |
25 |
26 |
29 |
30 |
--------------------------------------------------------------------------------
/KawaHello/src/kawa/android/hello.scm:
--------------------------------------------------------------------------------
1 | (require 'android-defs)
2 |
3 | (define-namespace Log "class:android.util.Log")
4 |
5 | (activity hello1
6 | (on-create-view
7 | (Log:i "kawa" "i")
8 | (Log:d "kawa" "d")
9 | (Log:e "kawa" "e")
10 | (android.widget.TextView
11 | (this)
12 | text: "Hello, Android from Kawa Scheme!")))
13 |
14 | (activity hello2
15 | (on-create-view
16 | (android.widget.LinearLayout
17 | (this)
18 | orientation: android.widget.LinearLayout:VERTICAL
19 | view:
20 | (android.widget.TextView
21 | (this)
22 | text: "Hello, Android from Kawa Scheme!")
23 | view:
24 | (android.widget.Button
25 | (this)
26 | text: "Click Me!"
27 | on-click-listener: (lambda (v)
28 | ((android.widget.Toast:makeText
29 | (this)
30 | "Clicked!"
31 | android.widget.Toast:LENGTH_LONG):show))))))
32 |
33 | (activity hello
34 | (on-create-view
35 | (define mTts
36 | (android.speech.tts.TextToSpeech
37 | (this)
38 | (lambda (i) ())))
39 | (android.widget.LinearLayout (this)
40 | orientation: android.widget.LinearLayout:VERTICAL
41 | view:
42 | (android.widget.TextView (this)
43 | text: "Enter the text to speak")
44 | view:
45 | (android.widget.EditText (this)
46 | id: 101)
47 | view:
48 | (android.widget.Button (this)
49 | text: "Speak!"
50 | on-click-listener:
51 | (lambda (v)
52 | (mTts:speak
53 | ((as
54 | ((this):findViewById 101)):getText)
55 | android.speech.tts.TextToSpeech:QUEUE_FLUSH
56 | #!null))))))
57 |
--------------------------------------------------------------------------------
/SpeedRead/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
23 |
24 |
31 |
32 |
40 |
41 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/bin/setup-kawa:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 | set -o pipefail
5 |
6 | EXPECTED_ARGS=2
7 | E_BADARGS=65
8 |
9 | KAWA_VERSION=1.13
10 |
11 | if [ $# -lt $EXPECTED_ARGS ]; then
12 | echo "Usage: `basename $0` android-home android-platform"
13 | echo " Setup a Kawa install in the current directory for a particular Android version."
14 | echo " for example: bin/setup-kawa /opt/android-sdk-update-manager android-17"
15 | exit $E_BADARGS
16 | fi
17 |
18 | echo "Fetching Kawa ${KAWA_VERSION}"
19 | if [ -e kawa ]; then
20 | rm -r kawa
21 | fi
22 | if [ ! -e kawa-${KAWA_VERSION}.tar.gz ]; then
23 | wget ftp://ftp.gnu.org/pub/gnu/kawa/kawa-1.13.tar.gz
24 | fi
25 | tar xvf kawa-1.13.tar.gz
26 | mv kawa-${KAWA_VERSION} kawa
27 | cd kawa
28 | echo "Patching kawa"
29 | patch -p0 <<\EOF
30 | --- Makefile.am.orig 2013-07-17 09:36:47.448268287 -0400
31 | +++ Makefile.am 2012-11-22 02:11:40.000000000 -0500
32 | @@ -258,7 +258,7 @@
33 | COMMENT_OUT = s|^\([[:space:]]*\)\([^/[:space:]]\)|\1// \2|
34 |
35 | gnu/kawa/util/PreProcess.class: $(srcdir)/gnu/kawa/util/PreProcess.java
36 | - $(JAVAC) -d . $(srcdir)/gnu/kawa/util/PreProcess.java
37 | + $(JAVAC) -d . $(JAVACFLAGS) $(srcdir)/gnu/kawa/util/PreProcess.java
38 |
39 | # JDK 1.1
40 | select-java1: $(srcdir)/patch-source-list gnu/kawa/util/PreProcess.class
41 | EOF
42 | patch -p0 <<\EOF
43 | --- Makefile.in.orig 2013-07-17 09:36:49.229268472 -0400
44 | +++ Makefile.in 2012-12-09 02:29:46.000000000 -0500
45 | @@ -959,7 +959,7 @@
46 | | sed -e 's|./||' | sort > $@
47 |
48 | gnu/kawa/util/PreProcess.class: $(srcdir)/gnu/kawa/util/PreProcess.java
49 | - $(JAVAC) -d . $(srcdir)/gnu/kawa/util/PreProcess.java
50 | + $(JAVAC) -d . $(JAVACFLAGS) $(srcdir)/gnu/kawa/util/PreProcess.java
51 |
52 | # JDK 1.1
53 | select-java1: $(srcdir)/patch-source-list gnu/kawa/util/PreProcess.class
54 | EOF
55 | echo "Building kawa"
56 | JAVACFLAGS="-source 1.6 -target 1.6" ./configure --with-android=$1/platforms/$2/android.jar --disable-xquery --disable-jemacs || (echo "Failed to configure Kawa!"; exit 1)
57 | # Because kawa docs sometimes fail to build.
58 | echo '' > doc/kawa.texi
59 | make || (echo "Failed to build Kawa!"; exit 1)
60 | cd ..
61 | rm kawa-1.13.tar.gz
62 | ln -s `pwd`/kawa/kawa-1.*.jar kawa/kawa.jar
63 | echo
64 | echo "Done! We're good to go"
65 |
--------------------------------------------------------------------------------
/SpeedRead/res/layout/player.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
17 |
18 |
28 |
29 |
39 |
40 |
49 |
50 |
59 |
60 |
66 |
67 |
74 |
75 |
--------------------------------------------------------------------------------
/bin/make-project:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | EXPECTED_ARGS=3
6 | E_BADARGS=65
7 |
8 | if [ $# -lt $EXPECTED_ARGS ]
9 | then
10 | echo "Usage: `basename $0` android-platform project-name activity package-name"
11 | echo "Setups a new Android project with Kawa."
12 | echo " Kawa should exist in the kawa/ directory as set up by bin/setup-kawa"
13 | echo " bin/make-project android-14 KawaHello2 hello"
14 | exit $E_BADARGS
15 | fi
16 |
17 | if [ ! -d kawa ]; then
18 | echo "Error: Kawa should exist in the kawa/ directory as set up by bin/setup-kawa."
19 | exit 1;
20 | fi
21 |
22 | if [ -d $2 ]; then
23 | echo "Error: $2 already exists. You can't create a new project into an existing directory."
24 | exit 1;
25 | fi
26 |
27 | PKG_PATH=$(echo $4 | sed -e "s:\.:/:g")
28 | TARGET=$1
29 | NAME=$2
30 | ACTIVITY=$3
31 | PKG=$4
32 |
33 | android create project --target ${TARGET} --name ${NAME} --activity ${ACTIVITY} --path ${NAME} --package ${PKG} > /dev/null || (echo "Failed to create an android project! File a bug at github.com/abarbu/android-kawa" && exit 1)
34 | rm -f ${NAME}/src/${PKG_PATH}/${ACTIVITY}.jar
35 | touch ${NAME}/src/${PKG_PATH}/${ACTIVITY}.scm
36 | ln -s `pwd`/kawa/kawa-1.*.jar ${NAME}/libs/kawa.jar
37 |
38 | (cd ${NAME}; (patch -p0 <
43 |
44 |
45 | +
46 | +
47 | +
48 | +
49 | +
50 | +
51 | +
52 | +
53 | +
54 | +
55 | +
56 | +
57 | +
58 | +
59 | +
60 | +
61 | +
65 | +
66 | +
67 | +
68 |
69 | EOF
70 | ) > /dev/null \
71 | || (echo "Failed to patch the build file! File a bug at github.com/abarbu/android-kawa" && exit 1))
72 | echo "adb shell kill \$(adb shell ps|grep -i ${PKG}|awk '{ print $2 }') > /dev/null" > ${NAME}/make-and-send
73 | echo "ant debug && adb install -r bin/${NAME}-debug.apk && adb shell am start -a android.intent.action.MAIN ${PKG}/.${ACTIVITY}" >> ${NAME}/make-and-send
74 | chmod +x ${NAME}/make-and-send
75 |
76 | cat > ${NAME}/src/${PKG_PATH}/${ACTIVITY}.scm <
29 | )
30 | (edit-text ::EditText)
31 | (update-button ::Button)
32 | (twitter ::Twitter)
33 | (text-count ::TextView)
34 |
35 | ((onCreate (savedInstanceState ::Bundle))
36 | (invoke-special android.app.Activity (this) 'onCreate savedInstanceState)
37 | (setContentView R$layout:status)
38 |
39 | (set! edit-text (as EditText (findViewById com.zeroxab.learningandroid.yamba.R$id:editText)))
40 | (set! update-button (as Button (findViewById com.zeroxab.learningandroid.yamba.R$id:buttonUpdate)))
41 | (update-button:setOnClickListener (this))
42 |
43 | (set! text-count (as TextView (findViewById com.zeroxab.learningandroid.yamba.R$id:textCount)))
44 | (text-count:setText (140:toString))
45 | (text-count:setTextColor Color:GREEN)
46 | (edit-text:addTextChangedListener (this))
47 |
48 | (set! twitter (Twitter:new "student" "password"))
49 | (twitter:setAPIRootUrl "http://yamba.marakana.com/api"))
50 |
51 | ((onClick (view ::View))
52 | (let* ( ;; FIXME this is nasty
53 | (activity-this (this))
54 | (post-to-twitter
55 | (object (android.os.AsyncTask)
56 | ((doInBackground (statuses ::java.lang.Object[])) (@java.lang.Override) ::Object
57 | (try-catch (begin (twitter:setStatus (statuses 0))
58 | (statuses 0))
59 | (e winterwell.jtwitter.TwitterException
60 | ((Toast:makeText activity-this
61 | "Ooops, failed to set twitter status!"
62 | Toast:LENGTH_SHORT):show)
63 | (Log:e "Yamba-StatusActivity" "Failed to set twitter status!")
64 | (e:printStackTrace)
65 | "Failed to post")))
66 | ((onProgressUpdate values) (@java.lang.Override) ::void
67 | #!null)
68 | ((onPostExecute result) (@java.lang.Override)
69 | ((Toast:makeText activity-this (as result) Toast:LENGTH_LONG):show)))))
70 | (*:execute post-to-twitter ((edit-text:getText):toString))
71 | (Log:d "Yamba-StatusActivity" "Clicked!")))
72 |
73 | ((afterTextChanged (status-text ::Editable))
74 | (let ((count (- 140 (status-text:length))))
75 | (text-count:setText (format #f "~a" count))
76 | (text-count:setTextColor (cond ((< count 0) Color:RED)
77 | ((< count 10) Color:YELLOW)
78 | (else Color:GREEN)))))
79 | ((beforeTextChanged sequence start count after) #f)
80 | ((onTextChanged sequence start before count) #f))
81 |
--------------------------------------------------------------------------------
/libkawadroid/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
29 |
30 |
31 |
35 |
36 |
37 |
38 |
39 |
40 |
49 |
50 |
51 |
52 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter6/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
29 |
30 |
31 |
40 |
41 |
42 |
43 |
47 |
48 |
49 |
51 |
63 |
64 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter7/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
29 |
30 |
31 |
40 |
41 |
42 |
43 |
47 |
48 |
49 |
51 |
63 |
64 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter8/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
29 |
30 |
31 |
40 |
41 |
42 |
43 |
47 |
48 |
49 |
51 |
63 |
64 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/KawaHello/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
29 |
30 |
31 |
40 |
41 |
42 |
43 |
47 |
48 |
49 |
51 |
63 |
64 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
106 |
107 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/LunarLander/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
29 |
30 |
31 |
40 |
41 |
42 |
43 |
47 |
48 |
49 |
51 |
63 |
64 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
105 |
106 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
29 |
30 |
31 |
40 |
41 |
42 |
43 |
47 |
48 |
49 |
51 |
63 |
64 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter9/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
29 |
30 |
31 |
40 |
41 |
42 |
43 |
47 |
48 |
49 |
51 |
63 |
64 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter7/src/com/zeroxab/learningandroid/yamba/Yamba.scm:
--------------------------------------------------------------------------------
1 | (require 'android-defs)
2 | (require 'srfi-1)
3 |
4 | (define-namespace Log "class:android.util.Log")
5 |
6 | (define-alias Math java.lang.Math)
7 |
8 | (define-alias Bitmap android.graphics.Bitmap)
9 | (define-alias Canvas android.graphics.Canvas)
10 | (define-alias Color android.graphics.Color)
11 | (define-alias Drawable android.graphics.drawable.Drawable)
12 | (define-alias Resources android.content.res.Resources)
13 | (define-alias Context android.content.Context)
14 | (define-alias Intent android.content.Intent)
15 | (define-alias SharedPreferences android.content.SharedPreferences)
16 | (define-alias Activity android.app.Activity)
17 | (define-alias Handler android.os.Handler)
18 | (define-alias Bundle android.os.Bundle)
19 | (define-alias KeyEvent android.view.KeyEvent)
20 | (define-alias OnClickListener android.view.View$OnClickListener)
21 | (define-alias SurfaceHolder android.view.SurfaceHolder)
22 | (define-alias Menu android.view.Menu)
23 | (define-alias MenuItem android.view.MenuItem)
24 | (define-alias Toast android.widget.Toast)
25 | (define-alias Editable android.text.Editable)
26 | (define-alias TextWatcher android.text.TextWatcher)
27 | (define-alias PreferenceActivity android.preference.PreferenceActivity)
28 | (define-alias PreferenceManager android.preference.PreferenceManager)
29 |
30 |
31 | (define-alias R com.zeroxab.learningandroid.yamba.R)
32 |
33 | (define-alias Twitter winterwell.jtwitter.Twitter)
34 |
35 | (define-simple-class PrefActivity (PreferenceActivity)
36 | ((onCreate (savedInstanceState ::Bundle))
37 | (invoke-special android.app.Activity (this) 'onCreate savedInstanceState)
38 | (addPreferencesFromResource R$xml:prefs)))
39 |
40 | (define-simple-class StatusActivity (Activity
41 | )
42 | (edit-text ::EditText)
43 | (update-button ::Button)
44 | (twitter ::Twitter)
45 | (text-count ::TextView)
46 | (preferences ::SharedPreferences)
47 |
48 | ((onCreate (savedInstanceState ::Bundle))
49 | (invoke-special android.app.Activity (this) 'onCreate savedInstanceState)
50 | (setContentView R$layout:status)
51 |
52 | (set! edit-text (findViewById R$id:editText))
53 | (set! update-button (findViewById R$id:buttonUpdate))
54 | (update-button:setOnClickListener (this))
55 |
56 | (set! text-count (findViewById R$id:textCount))
57 | (text-count:setText (140:toString))
58 | (text-count:setTextColor Color:GREEN)
59 | (edit-text:addTextChangedListener (this))
60 |
61 | (set! preferences (PreferenceManager:getDefaultSharedPreferences (this)))
62 | (preferences:registerOnSharedPreferenceChangeListener
63 | (lambda ((preferences ::SharedPreferences) (key ::String))
64 | (set! twitter #!null))))
65 |
66 | ((get-twitter)
67 | (when (equal? twitter #!null)
68 | (set! twitter (Twitter:new (preferences:getString "username" "")
69 | (preferences:getString "password" "")))
70 | (twitter:setAPIRootUrl (preferences:getString "apiRoot" "http://yamba.marakana.com/api")))
71 | twitter)
72 |
73 | ((onClick (view ::View))
74 | (let* ( ;; FIXME this is nasty
75 | (activity-this (this))
76 | (post-to-twitter
77 | (object (android.os.AsyncTask)
78 | ((doInBackground (statuses ::java.lang.Object[])) (@java.lang.Override) ::Object
79 | (try-catch (begin ((get-twitter):setStatus (statuses 0))
80 | (statuses 0))
81 | (e winterwell.jtwitter.TwitterException
82 | ((Toast:makeText activity-this
83 | "Ooops, failed to set twitter status!"
84 | Toast:LENGTH_SHORT):show)
85 | (Log:e "Yamba-StatusActivity" "Failed to set twitter status!")
86 | (e:printStackTrace)
87 | "Failed to post")))
88 | ((onProgressUpdate values) (@java.lang.Override) ::void
89 | #!null)
90 | ((onPostExecute result) (@java.lang.Override)
91 | ((Toast:makeText activity-this (as result) Toast:LENGTH_LONG):show)))))
92 | (*:execute post-to-twitter ((edit-text:getText):toString))
93 | (Log:d "Yamba-StatusActivity" "Clicked!")))
94 |
95 | ((afterTextChanged (status-text ::Editable))
96 | (let ((count (- 140 (status-text:length))))
97 | (text-count:setText (format #f "~a" count))
98 | (text-count:setTextColor (cond ((< count 0) Color:RED)
99 | ((< count 10) Color:YELLOW)
100 | (else Color:GREEN)))))
101 | ((beforeTextChanged sequence start count after) #f)
102 | ((onTextChanged sequence start before count) #f)
103 |
104 | ((onCreateOptionsMenu (menu ::Menu))
105 | ((getMenuInflater):inflate R$menu:menu menu)
106 | #t)
107 | ((onOptionsItemSelected (item ::MenuItem))
108 | (cond ((equal? (item:getItemId) R$id:itemPrefs)
109 | (startActivity (make (this) PrefActivity)))
110 | (else #f))
111 | #t))
112 |
--------------------------------------------------------------------------------
/SpeedRead/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
29 |
30 |
31 |
35 |
36 |
37 |
38 |
39 |
40 |
49 |
50 |
51 |
52 |
56 |
57 |
69 |
70 |
71 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter9/src/com/zeroxab/learningandroid/yamba/collections_utils.scm:
--------------------------------------------------------------------------------
1 | ;; Some handy functions for dealing with java.util.Collections.
2 | ;; Jamison Hope 2009-12-07 15:06:52EST jrh collections-utils.scm
3 | ;; Time-stamp: <2009-12-08 16:42:00EST jrh collections_utils.scm>
4 | ;; $Id: collections_utils.scm 160 2009-12-09 22:13:24Z jhope $
5 | (module-export Enumeration->list
6 | Iterator->list
7 | Iterable->list
8 | Array->list
9 | ->list
10 | map-enumeration
11 | map-iterator
12 | map-iterable
13 | map-array
14 | for-each-enumeration
15 | for-each-iterator
16 | for-each-iterable
17 | for-each-array
18 | better-map
19 | better-for-each)
20 |
21 | ;;; Returns a list of the elements of the given Enumeration.
22 | (define (Enumeration->list (enum :: java.util.Enumeration)) :: list
23 | (let loop ((ls '()))
24 | (if (enum:hasMoreElements)
25 | (loop (cons (enum:nextElement) ls))
26 | (reverse ls))))
27 |
28 | ;;; Returns a list of the elements of the given Iterator.
29 | (define (Iterator->list (iter :: java.util.Iterator)) :: list
30 | (let loop ((ls '()))
31 | (if (iter:hasNext)
32 | (loop (cons (iter:next) ls))
33 | (reverse ls))))
34 |
35 | ;;; Returns a list of the elements of the given Iterable.
36 | (define (Iterable->list (it :: java.lang.Iterable)) :: list
37 | (Iterator->list (it:iterator)))
38 |
39 | ;;; Returns a list of the elements of the given array.
40 | (define (Array->list (array :: Object)) :: list
41 | (when (*:isArray (array:getClass))
42 | (let* ((n :: int (java.lang.reflect.Array:getLength array))
43 | (result-vector :: vector (make-vector n)))
44 | (do ((i 0 (+ i 1)))
45 | ((= i n) (vector->list result-vector))
46 | (vector-set! result-vector i (array i))))))
47 |
48 | ;;; Converts the given object into a list.
49 | (define ->list
50 | (case-lambda
51 | ((l :: list) l)
52 | ((l :: java.lang.Iterable) (Iterable->list l))
53 | ((l :: java.util.Iterator) (Iterator->list l))
54 | ((l :: java.util.Enumeration) (Enumeration->list l))
55 | ((l :: Object) (Array->list l))))
56 |
57 | ;;; Map for an Enumeration
58 | (define (map-enumeration (f :: procedure)
59 | (enum :: java.util.Enumeration))
60 | :: list
61 | (let loop ((ls '()))
62 | (if (enum:hasMoreElements)
63 | (loop (cons (f (enum:nextElement)) ls))
64 | (reverse ls))))
65 |
66 | ;;; Map for an Iterator
67 | (define (map-iterator (f :: procedure)
68 | (iter :: java.util.Iterator))
69 | :: list
70 | (let loop ((ls '()))
71 | (if (iter:hasNext)
72 | (loop (cons (f (iter:next)) ls))
73 | (reverse ls))))
74 |
75 | ;;; Map for an Iterable
76 | (define (map-iterable (f :: procedure)
77 | (it :: java.lang.Iterable))
78 | :: list
79 | (map-iterator f (it:iterator)))
80 |
81 | ;;; Map for an Array
82 | (define (map-array (f :: procedure)
83 | (obj :: Object))
84 | :: list
85 | (when (*:isArray (obj:getClass))
86 | (let* ((n :: int (java.lang.reflect.Array:getLength obj))
87 | (result-vector :: vector (make-vector n)))
88 | (do ((i 0 (+ i 1)))
89 | ((= i n) (vector->list result-vector))
90 | (vector-set! result-vector i (f (obj i)))))))
91 |
92 | ;;; For-each for an Enumeration
93 | (define (for-each-enumeration (f :: procedure)
94 | (enum :: java.util.Enumeration))
95 | (let loop ()
96 | (when (enum:hasMoreElements)
97 | (f (enum:nextElement))
98 | (loop))))
99 |
100 | ;;; For-each for an Iterator
101 | (define (for-each-iterator (f :: procedure)
102 | (iter :: java.util.Iterator))
103 | (let loop ()
104 | (when (iter:hasNext)
105 | (f (iter:next))
106 | (loop))))
107 |
108 | ;;; For-each for an Iterable
109 | (define (for-each-iterable (f :: procedure)
110 | (it :: java.lang.Iterable))
111 | (for-each-iterator f (it:iterator)))
112 |
113 | ;;; For-each for an Array
114 | (define (for-each-array (f :: procedure)
115 | (obj :: Object))
116 | (when (*:isArray (obj:getClass))
117 | (let ((n :: int (java.lang.reflect.Array:getLength obj)))
118 | (do ((i 0 (+ i 1)))
119 | ((= i n))
120 | (f (obj i))))))
121 |
122 | ;;; A version of map which works with lists, Enumerations, Iterators,
123 | ;;; Iterables, and Arrays.
124 | (define better-map
125 | (case-lambda
126 | (((f :: procedure) (l :: list))
127 | (map f l))
128 | (((f :: procedure) (l :: java.util.Enumeration))
129 | (map-enumeration f l))
130 | (((f :: procedure) (l :: java.util.Iterator))
131 | (map-iterator f l))
132 | (((f :: procedure) (l :: java.lang.Iterable))
133 | (map-iterable f l))
134 | (((f :: procedure) (l :: Object))
135 | (map-array f l))
136 | (((f :: procedure) (l1 :: Object) (l2 :: Object) . rest)
137 | (apply map f (append (map ->list `(,l1 ,l2))
138 | (map ->list rest))))))
139 |
140 | ;;; A version of for-each which works with lists, Enumerations,
141 | ;;; Iterators, Iterables, and Arrays.
142 | (define better-for-each
143 | (case-lambda
144 | (((f :: procedure) (l :: list))
145 | (for-each f l))
146 | (((f :: procedure) (l :: java.util.Enumeration))
147 | (for-each-enumeration f l))
148 | (((f :: procedure) (l :: java.util.Iterator))
149 | (for-each-iterator f l))
150 | (((f :: procedure) (l :: java.lang.Iterable))
151 | (for-each-iterable f l))
152 | (((f :: procedure) (l :: Object))
153 | (for-each-array f l))
154 | (((f :: procedure) (l1 :: Object) (l2 :: Object) . rest)
155 | (apply for-each f (append (map ->list `(,l1 ,l2))
156 | (map ->list rest))))))
157 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/src/com/zeroxab/learningandroid/yamba/collections_utils.scm:
--------------------------------------------------------------------------------
1 | ;; Some handy functions for dealing with java.util.Collections.
2 | ;; Jamison Hope 2009-12-07 15:06:52EST jrh collections-utils.scm
3 | ;; Time-stamp: <2009-12-08 16:42:00EST jrh collections_utils.scm>
4 | ;; $Id: collections_utils.scm 160 2009-12-09 22:13:24Z jhope $
5 | (module-export Enumeration->list
6 | Iterator->list
7 | Iterable->list
8 | Array->list
9 | ->list
10 | map-enumeration
11 | map-iterator
12 | map-iterable
13 | map-array
14 | for-each-enumeration
15 | for-each-iterator
16 | for-each-iterable
17 | for-each-array
18 | better-map
19 | better-for-each)
20 |
21 | ;;; Returns a list of the elements of the given Enumeration.
22 | (define (Enumeration->list (enum :: java.util.Enumeration)) :: list
23 | (let loop ((ls '()))
24 | (if (enum:hasMoreElements)
25 | (loop (cons (enum:nextElement) ls))
26 | (reverse ls))))
27 |
28 | ;;; Returns a list of the elements of the given Iterator.
29 | (define (Iterator->list (iter :: java.util.Iterator)) :: list
30 | (let loop ((ls '()))
31 | (if (iter:hasNext)
32 | (loop (cons (iter:next) ls))
33 | (reverse ls))))
34 |
35 | ;;; Returns a list of the elements of the given Iterable.
36 | (define (Iterable->list (it :: java.lang.Iterable)) :: list
37 | (Iterator->list (it:iterator)))
38 |
39 | ;;; Returns a list of the elements of the given array.
40 | (define (Array->list (array :: Object)) :: list
41 | (when (*:isArray (array:getClass))
42 | (let* ((n :: int (java.lang.reflect.Array:getLength array))
43 | (result-vector :: vector (make-vector n)))
44 | (do ((i 0 (+ i 1)))
45 | ((= i n) (vector->list result-vector))
46 | (vector-set! result-vector i (array i))))))
47 |
48 | ;;; Converts the given object into a list.
49 | (define ->list
50 | (case-lambda
51 | ((l :: list) l)
52 | ((l :: java.lang.Iterable) (Iterable->list l))
53 | ((l :: java.util.Iterator) (Iterator->list l))
54 | ((l :: java.util.Enumeration) (Enumeration->list l))
55 | ((l :: Object) (Array->list l))))
56 |
57 | ;;; Map for an Enumeration
58 | (define (map-enumeration (f :: procedure)
59 | (enum :: java.util.Enumeration))
60 | :: list
61 | (let loop ((ls '()))
62 | (if (enum:hasMoreElements)
63 | (loop (cons (f (enum:nextElement)) ls))
64 | (reverse ls))))
65 |
66 | ;;; Map for an Iterator
67 | (define (map-iterator (f :: procedure)
68 | (iter :: java.util.Iterator))
69 | :: list
70 | (let loop ((ls '()))
71 | (if (iter:hasNext)
72 | (loop (cons (f (iter:next)) ls))
73 | (reverse ls))))
74 |
75 | ;;; Map for an Iterable
76 | (define (map-iterable (f :: procedure)
77 | (it :: java.lang.Iterable))
78 | :: list
79 | (map-iterator f (it:iterator)))
80 |
81 | ;;; Map for an Array
82 | (define (map-array (f :: procedure)
83 | (obj :: Object))
84 | :: list
85 | (when (*:isArray (obj:getClass))
86 | (let* ((n :: int (java.lang.reflect.Array:getLength obj))
87 | (result-vector :: vector (make-vector n)))
88 | (do ((i 0 (+ i 1)))
89 | ((= i n) (vector->list result-vector))
90 | (vector-set! result-vector i (f (obj i)))))))
91 |
92 | ;;; For-each for an Enumeration
93 | (define (for-each-enumeration (f :: procedure)
94 | (enum :: java.util.Enumeration))
95 | (let loop ()
96 | (when (enum:hasMoreElements)
97 | (f (enum:nextElement))
98 | (loop))))
99 |
100 | ;;; For-each for an Iterator
101 | (define (for-each-iterator (f :: procedure)
102 | (iter :: java.util.Iterator))
103 | (let loop ()
104 | (when (iter:hasNext)
105 | (f (iter:next))
106 | (loop))))
107 |
108 | ;;; For-each for an Iterable
109 | (define (for-each-iterable (f :: procedure)
110 | (it :: java.lang.Iterable))
111 | (for-each-iterator f (it:iterator)))
112 |
113 | ;;; For-each for an Array
114 | (define (for-each-array (f :: procedure)
115 | (obj :: Object))
116 | (when (*:isArray (obj:getClass))
117 | (let ((n :: int (java.lang.reflect.Array:getLength obj)))
118 | (do ((i 0 (+ i 1)))
119 | ((= i n))
120 | (f (obj i))))))
121 |
122 | ;;; A version of map which works with lists, Enumerations, Iterators,
123 | ;;; Iterables, and Arrays.
124 | (define better-map
125 | (case-lambda
126 | (((f :: procedure) (l :: list))
127 | (map f l))
128 | (((f :: procedure) (l :: java.util.Enumeration))
129 | (map-enumeration f l))
130 | (((f :: procedure) (l :: java.util.Iterator))
131 | (map-iterator f l))
132 | (((f :: procedure) (l :: java.lang.Iterable))
133 | (map-iterable f l))
134 | (((f :: procedure) (l :: Object))
135 | (map-array f l))
136 | (((f :: procedure) (l1 :: Object) (l2 :: Object) . rest)
137 | (apply map f (append (map ->list `(,l1 ,l2))
138 | (map ->list rest))))))
139 |
140 | ;;; A version of for-each which works with lists, Enumerations,
141 | ;;; Iterators, Iterables, and Arrays.
142 | (define better-for-each
143 | (case-lambda
144 | (((f :: procedure) (l :: list))
145 | (for-each f l))
146 | (((f :: procedure) (l :: java.util.Enumeration))
147 | (for-each-enumeration f l))
148 | (((f :: procedure) (l :: java.util.Iterator))
149 | (for-each-iterator f l))
150 | (((f :: procedure) (l :: java.lang.Iterable))
151 | (for-each-iterable f l))
152 | (((f :: procedure) (l :: Object))
153 | (for-each-array f l))
154 | (((f :: procedure) (l1 :: Object) (l2 :: Object) . rest)
155 | (apply for-each f (append (map ->list `(,l1 ,l2))
156 | (map ->list rest))))))
157 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter8/src/com/zeroxab/learningandroid/yamba/collections_utils.scm:
--------------------------------------------------------------------------------
1 | ;; Some handy functions for dealing with java.util.Collections.
2 | ;; Jamison Hope 2009-12-07 15:06:52EST jrh collections-utils.scm
3 | ;; Time-stamp: <2009-12-08 16:42:00EST jrh collections_utils.scm>
4 | ;; $Id: collections_utils.scm 160 2009-12-09 22:13:24Z jhope $
5 | (module-export Enumeration->list
6 | Iterator->list
7 | Iterable->list
8 | Array->list
9 | ->list
10 | map-enumeration
11 | map-iterator
12 | map-iterable
13 | map-array
14 | for-each-enumeration
15 | for-each-iterator
16 | for-each-iterable
17 | for-each-array
18 | better-map
19 | better-for-each)
20 |
21 | ;;; Returns a list of the elements of the given Enumeration.
22 | (define (Enumeration->list (enum :: java.util.Enumeration)) :: list
23 | (let loop ((ls '()))
24 | (if (enum:hasMoreElements)
25 | (loop (cons (enum:nextElement) ls))
26 | (reverse ls))))
27 |
28 | ;;; Returns a list of the elements of the given Iterator.
29 | (define (Iterator->list (iter :: java.util.Iterator)) :: list
30 | (let loop ((ls '()))
31 | (if (iter:hasNext)
32 | (loop (cons (iter:next) ls))
33 | (reverse ls))))
34 |
35 | ;;; Returns a list of the elements of the given Iterable.
36 | (define (Iterable->list (it :: java.lang.Iterable)) :: list
37 | (Iterator->list (it:iterator)))
38 |
39 | ;;; Returns a list of the elements of the given array.
40 | (define (Array->list (array :: Object)) :: list
41 | (when (*:isArray (array:getClass))
42 | (let* ((n :: int (java.lang.reflect.Array:getLength array))
43 | (result-vector :: vector (make-vector n)))
44 | (do ((i 0 (+ i 1)))
45 | ((= i n) (vector->list result-vector))
46 | (vector-set! result-vector i (array i))))))
47 |
48 | ;;; Converts the given object into a list.
49 | (define ->list
50 | (case-lambda
51 | ((l :: list) l)
52 | ((l :: java.lang.Iterable) (Iterable->list l))
53 | ((l :: java.util.Iterator) (Iterator->list l))
54 | ((l :: java.util.Enumeration) (Enumeration->list l))
55 | ((l :: Object) (Array->list l))))
56 |
57 | ;;; Map for an Enumeration
58 | (define (map-enumeration (f :: procedure)
59 | (enum :: java.util.Enumeration))
60 | :: list
61 | (let loop ((ls '()))
62 | (if (enum:hasMoreElements)
63 | (loop (cons (f (enum:nextElement)) ls))
64 | (reverse ls))))
65 |
66 | ;;; Map for an Iterator
67 | (define (map-iterator (f :: procedure)
68 | (iter :: java.util.Iterator))
69 | :: list
70 | (let loop ((ls '()))
71 | (if (iter:hasNext)
72 | (loop (cons (f (iter:next)) ls))
73 | (reverse ls))))
74 |
75 | ;;; Map for an Iterable
76 | (define (map-iterable (f :: procedure)
77 | (it :: java.lang.Iterable))
78 | :: list
79 | (map-iterator f (it:iterator)))
80 |
81 | ;;; Map for an Array
82 | (define (map-array (f :: procedure)
83 | (obj :: Object))
84 | :: list
85 | (when (*:isArray (obj:getClass))
86 | (let* ((n :: int (java.lang.reflect.Array:getLength obj))
87 | (result-vector :: vector (make-vector n)))
88 | (do ((i 0 (+ i 1)))
89 | ((= i n) (vector->list result-vector))
90 | (vector-set! result-vector i (f (obj i)))))))
91 |
92 | ;;; For-each for an Enumeration
93 | (define (for-each-enumeration (f :: procedure)
94 | (enum :: java.util.Enumeration))
95 | (let loop ()
96 | (when (enum:hasMoreElements)
97 | (f (enum:nextElement))
98 | (loop))))
99 |
100 | ;;; For-each for an Iterator
101 | (define (for-each-iterator (f :: procedure)
102 | (iter :: java.util.Iterator))
103 | (let loop ()
104 | (when (iter:hasNext)
105 | (f (iter:next))
106 | (loop))))
107 |
108 | ;;; For-each for an Iterable
109 | (define (for-each-iterable (f :: procedure)
110 | (it :: java.lang.Iterable))
111 | (for-each-iterator f (it:iterator)))
112 |
113 | ;;; For-each for an Array
114 | (define (for-each-array (f :: procedure)
115 | (obj :: Object))
116 | (when (*:isArray (obj:getClass))
117 | (let ((n :: int (java.lang.reflect.Array:getLength obj)))
118 | (do ((i 0 (+ i 1)))
119 | ((= i n))
120 | (f (obj i))))))
121 |
122 | ;;; A version of map which works with lists, Enumerations, Iterators,
123 | ;;; Iterables, and Arrays.
124 | (define better-map
125 | (case-lambda
126 | (((f :: procedure) (l :: list))
127 | (map f l))
128 | (((f :: procedure) (l :: java.util.Enumeration))
129 | (map-enumeration f l))
130 | (((f :: procedure) (l :: java.util.Iterator))
131 | (map-iterator f l))
132 | (((f :: procedure) (l :: java.lang.Iterable))
133 | (map-iterable f l))
134 | (((f :: procedure) (l :: Object))
135 | (map-array f l))
136 | (((f :: procedure) (l1 :: Object) (l2 :: Object) . rest)
137 | (apply map f (append (map ->list `(,l1 ,l2))
138 | (map ->list rest))))))
139 |
140 | ;;; A version of for-each which works with lists, Enumerations,
141 | ;;; Iterators, Iterables, and Arrays.
142 | (define better-for-each
143 | (case-lambda
144 | (((f :: procedure) (l :: list))
145 | (for-each f l))
146 | (((f :: procedure) (l :: java.util.Enumeration))
147 | (for-each-enumeration f l))
148 | (((f :: procedure) (l :: java.util.Iterator))
149 | (for-each-iterator f l))
150 | (((f :: procedure) (l :: java.lang.Iterable))
151 | (for-each-iterable f l))
152 | (((f :: procedure) (l :: Object))
153 | (for-each-array f l))
154 | (((f :: procedure) (l1 :: Object) (l2 :: Object) . rest)
155 | (apply for-each f (append (map ->list `(,l1 ,l2))
156 | (map ->list rest))))))
157 |
--------------------------------------------------------------------------------
/README.org:
--------------------------------------------------------------------------------
1 | * Kawa Scheme on Android
2 | This started as a collection of examples of Kawa on Android because I
3 | couldn't find anything substantive. It will slowly morph into a
4 | tutorial. At the moment it consists of a number of examples ported
5 | from Java and an application written from scratch in Kawa,
6 | SpeedRead. If you're new, work your way up with the simpler examples
7 | first. If you want to dive right in, look at SpeedRead. It's much
8 | cleaner.
9 |
10 | ** Setting up
11 | We'll first need to get an Android SDK set up, skip this if you've
12 | already got one. You'll need to install the Android SDK; your
13 | distribution's package management software will help with this. Once
14 | you're done, run /android/, select and install the latest API
15 | revision (17 as of this document).
16 |
17 | To get started with Scheme you'll need a custom build for Kawa, this
18 | will fetch and build the latest sources
19 | #+BEGIN_SRC sh
20 | bin/setup-kawa
21 | #+END_SRC
22 |
23 | You'll need to point it to your android SDK directory and give it the
24 | platform number. On my machine this looks like:
25 | #+BEGIN_SRC sh
26 | bin/setup-kawa /opt/android-sdk-update-manager android-17
27 | #+END_SRC
28 |
29 | ** Creating a new project
30 | To create a new project you can use
31 | #+BEGIN_SRC sh
32 | bin/make-project
33 | #+END_SRC
34 | for example
35 | #+BEGIN_SRC sh
36 | bin/make-project android-17 HelloWorld hello kawa.example
37 | #+END_SRC
38 | The arguments are: the platform/api level, the project name and the
39 | original activity name. This calls 'android create project' and
40 | patches the resulting build.xml file. It will create a trivial
41 | application that displays a message. Sources are in
42 | /src/kawa/android/.scm. The resulting
43 | application will have package name kawa.android. You should probably
44 | change this, It's recorded in src/kawa/kawa/example.java,
45 | AndroidManifest.xml, and build.xml. The name is how Android
46 | will internally refer to this application. So if you want to start it
47 | or for example uninstall it you would use the package name, for example
48 | #+BEGIN_SRC sh
49 | adb uninstall kawa.example
50 | #+END_SRC
51 |
52 | *** Running on the phone
53 |
54 | Building and running are both done by the same script.
55 | #+BEGIN_SRC sh
56 | cd SpeedRead && ./make-and-send
57 | #+END_SRC
58 | This will create an apk and send it out to the phone and run it. When
59 | you modify the code just rerun make-and-send. Your first compile will
60 | likely be slow but subsequent ones will be much faster. When you're
61 | done you can clean up with
62 | #+BEGIN_SRC sh
63 | adb uninstall zeroxab.speedread
64 | #+END_SRC
65 |
66 | *** Running in the emulator
67 |
68 | You first need to set up the emulator by running
69 | #+BEGIN_SRC sh
70 | android create avd -a -n Test -t 1 --abi armeabi-v7a
71 | #+END_SRC
72 | and accepting the defaults. If you've got a plain-vanilla SDK setup id
73 | 1 will be the basic android platform. You can check with /android list
74 | targets/ and adjust accordingly. Once it's setup it, just run
75 | #+BEGIN_SRC sh
76 | bin/start-emulator
77 | #+END_SRC
78 | to fire it up, it'll take a while... The emulator is so obscenely
79 | slow that you'll want to either run things on your phone or set up
80 | vmware.
81 |
82 | Running and building work the same way they do for the phone from the
83 | same /make-and-send/ script.
84 |
85 | *** Debugging
86 |
87 | While debugging I have
88 | #+BEGIN_SRC sh
89 | bin/colorize-adb-logcat
90 | #+END_SRC
91 | running in a terminal to easily spot log messages.
92 |
93 | *** XML sanity
94 |
95 | I highly recommend editing your UIs and Manifest files in Eclipse with
96 | the Android plugins available from
97 |
98 | https://dl-ssl.google.com/android/eclipse/
99 |
100 | Click /Help/, /Install New Software/, add the above repository,
101 | and install all of the software it provides. Once you've created a
102 | project with the /make-project/ script above import it into
103 | Eclipse. Click /New/, /Project/, choose /Android/, /Android
104 | Project from Existing Code/ and select the toplevel directory of the
105 | project. Eclipse will eventually complain that classes are missing
106 | because it doesn't know about our Scheme code but editing Manifests
107 | and resources with the Eclipse UI isn't too bad.
108 |
109 | Click /AndroidManifest.xml/, select /Application/ (bottom),
110 | /Theme/, /Browse/, and pick /Holo.Light.ButtonBar/ and
111 | save. Navigate to /res/, /layout/, /main.xml/ and there's the UI
112 | of the application we just made and it's now using the pretty Holo
113 | UI.
114 |
115 | The default application that make-project creates doesn't use the xml
116 | file at all, it creates its own TextView widget on the fly:
117 | #+BEGIN_SRC scheme
118 | ((this):setContentView
119 | (android.widget.TextView
120 | (this)
121 | text: "Hello from Kawa Scheme!"))
122 | #+END_SRC scheme
123 | Replace that code with
124 | #+BEGIN_SRC scheme
125 | ((this):setContentView .R$layout:main)
126 | #+END_SRC scheme
127 | Note the /R/ syntax for accessing resources.
128 | and you'll see the UI from Eclipse.
129 | ** Examples
130 | *** SDK/LearningAndroid
131 | - KawaHello is a simple hello world application
132 | - LunarLander is a reimplementation of the SDK example
133 | - LearningAndroid-chapter{6,7,8,9,10} are implementations of the main
134 | projects for most of the chapters from Marko Garneta's "Learning
135 | Android"
136 |
137 | These were written while I was figuring out if Kawa can be used for
138 | Android development and how to work out various Android&Kawa-specific
139 | quirks. All examples try to mostly stay true to their source however
140 | badly designed that source was. As such this isn't a good place to
141 | look for good Scheme style or idiomatic Kawa.
142 |
143 | In general these are meant to be read, not necessarily run as such I
144 | don't always keep them up to date.
145 |
146 | You may need to update local.properties in each of the examples
147 | directory to change the path to the Android SDK.
148 |
149 | LearningAndroid examples need to a copy of jtwitter.jar and
150 | signpost-core-1.2.1.1.jar from
151 | http://www.winterwell.com/software/jtwitter.php in each of their libs
152 | directory.
153 | *** SpeedRead
154 | SpeedRead is an app for rapid sequential visual presentation (RSVP) of
155 | text. It flashes text to allow you to read more quickly. This is a
156 | working application. With some love it will one day make its way into
157 | the app market. It was designed for the ground up as a Kawa
158 | application and has much nicer style than the other examples. It's
159 | also a much more complex application than the other examples while
160 | still being quite small. Note all of the macros which make unpleasant
161 | repetitive code much nicer. One day these and other code will make
162 | their way into a standard library for Android Kawa.
163 | ** Troubleshooting the build system
164 | *** bad magic bits with dex
165 | You've somehow managed to install with 1.7. Delete your old install
166 | entirely, downgrade to 1.6 and reinstall.
167 | *** make-and-send fails
168 | If you see
169 | #+BEGIN_SRC
170 | INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES
171 | #+END_SRC
172 | after running make-and-send, you've got a copy of apk you're trying to
173 | send to the phone already installed but it was compiled on a different
174 | machine with a different certificate. You just have to uninstall
175 | it. Keep in mind that if you've never changed the name of a project
176 | you've left the default (kawa.android) in. You'll want to uninstall
177 | the old package with
178 | #+BEGIN_SRC
179 | adb uninstall kawa.android
180 | #+END_SRC
181 | and read the section above on creating projects for how to change the
182 | internal project name.
183 | *** unable to resolve project target 'android-number'
184 | You're compiling a project for an SDK version you don't actually have
185 | installed. The simplest solution is to just edit /project.properties/
186 | and change the SDK version.
187 | ** Troubleshooting kawa
188 | By far the most difficult and frustrating part of writing code with
189 | Kawa for Android is going to be dealing with Kawa's extremely
190 | unhelpful error messages. I've listed some of the common ones and what
191 | they mean.
192 | *** more than one possibly applicable method '' in ...
193 | A common error with a pretty unhelpful error message. Usually happens
194 | in code that looks like:
195 | #+BEGIN_SRC
196 | (make x)
197 | #+END_SRC
198 | Kawa is getting confused about the type of x, so you have to give it a
199 | hand by casting it explicitly.
200 | #+BEGIN_SRC
201 | (make (as String x))
202 | #+END_SRC
203 | *** no known slot '...' in java.lang.Object
204 | As above, Kawa can't figure out the type of the object you're trying
205 | to use and at some point ended up casting it to Object. Vou've
206 | got something like a function or let binding where you didn't specify
207 | a type. You can either specify one or cast as in the above section.
208 |
209 | ((lunarView:getThread):pause)
210 |
211 | This might also happen if you have a misspelled identifier.
212 | *** no possibly applicable method '/valueOf' in ...
213 | You've got code like
214 | #+BEGIN_SRC
215 | (make args ...)
216 | #+END_SRC
217 | and one of the arguments is of the wrong type.
218 | *** Unfortunately, has stopped.
219 | Run 'adb logcat' or 'bin/colorize-adb-logcat' and have a look at the
220 | RuntimeException. Right now there's no interactive debugger but one is
221 | in the pipeline.
222 |
--------------------------------------------------------------------------------
/libkawadroid/src/com/zeroxab/libkawadroid/misc.scm:
--------------------------------------------------------------------------------
1 | (require 'android-defs)
2 | (require 'srfi-1)
3 | (import (except (srfi :13 strings)
4 | string-hash))
5 | (require 'regex)
6 | (require 'syntax-utils)
7 | (require 'srfi-69)
8 |
9 | (provide 'libkawadroid)
10 |
11 | (define-alias Arrays java.util.Arrays)
12 | (define-alias Math java.lang.Math)
13 | (define-alias InterruptedException java.lang.InterruptedException)
14 | (define-alias Thread java.lang.Thread)
15 | (define-alias Timer java.util.Timer)
16 | (define-alias TimerTask java.util.TimerTask)
17 | (define-alias Runnable java.lang.Runnable)
18 | (define-alias BufferedReader java.io.BufferedReader)
19 | (define-alias StringBuilder java.lang.StringBuilder)
20 |
21 | (define-alias ScheduledThreadPoolExecutor java.util.concurrent.ScheduledThreadPoolExecutor)
22 |
23 | (define-alias Application android.app.Application)
24 | (define-alias Activity android.app.Activity)
25 | (define-alias Service android.app.Service)
26 |
27 | (define-alias Bitmap android.graphics.Bitmap)
28 | (define-alias Canvas android.graphics.Canvas)
29 | (define-alias Color android.graphics.Color)
30 | (define-alias Drawable android.graphics.drawable.Drawable)
31 |
32 | (define-alias Context android.content.Context)
33 | (define-alias Intent android.content.Intent)
34 | (define-alias Resources android.content.res.Resources)
35 | (define-alias SharedPreferences android.content.SharedPreferences)
36 | (define-alias ContentValues android.content.ContentValues)
37 |
38 | (define-alias Handler android.os.Handler)
39 | (define-alias Bundle android.os.Bundle)
40 | (define-alias IBinder android.os.IBinder)
41 | (define-alias PowerManager android.os.PowerManager)
42 | (define-alias WakeLock android.os.PowerManager$WakeLock)
43 | (define-alias Parcelable android.os.Parcelable)
44 |
45 | (define-alias KeyEvent android.view.KeyEvent)
46 | (define-alias OnClickListener android.view.View$OnClickListener)
47 | (define-alias SurfaceHolder android.view.SurfaceHolder)
48 | (define-alias Menu android.view.Menu)
49 | (define-alias MenuItem android.view.MenuItem)
50 | (define-alias MotionEvent android.view.MotionEvent)
51 | (define-alias OnGestureListener android.view.GestureDetector$OnGestureListener)
52 | (define-alias GestureDetector android.view.GestureDetector)
53 |
54 | (define-alias ListView android.widget.ListView)
55 | (define-alias SimpleCursorAdapter android.widget.SimpleCursorAdapter)
56 | (define-alias Toast android.widget.Toast)
57 | (define-alias ViewBinder android.widget.SimpleCursorAdapter$ViewBinder)
58 | (define-alias ArrayAdapter android.widget.ArrayAdapter)
59 | (define-alias SimpleAdapter android.widget.SimpleAdapter)
60 | (define-alias OnItemClickListener android.widget.AdapterView$OnItemClickListener)
61 | (define-alias ProgressBar android.widget.ProgressBar)
62 | (define-alias SeekBar android.widget.SeekBar)
63 | (define-alias OnSeekBarChangeListener android.widget.SeekBar$OnSeekBarChangeListener)
64 |
65 | (define-alias DateUtils android.text.format.DateUtils)
66 | (define-alias Editable android.text.Editable)
67 | (define-alias TextWatcher android.text.TextWatcher)
68 | (define-alias Spannable android.text.Spannable)
69 | (define-alias SpannableString android.text.SpannableString)
70 | (define-alias BackgroundColorSpan android.text.style.BackgroundColorSpan)
71 | (define-alias StyleSpan android.text.style.StyleSpan)
72 |
73 | (define-alias PreferenceActivity android.preference.PreferenceActivity)
74 | (define-alias PreferenceManager android.preference.PreferenceManager)
75 | (define-alias BaseColumns android.provider.BaseColumns)
76 |
77 | (define-alias HttpGet org.apache.http.client.methods.HttpGet)
78 | (define-alias BasicResponseHandler org.apache.http.impl.client.BasicResponseHandler)
79 | (define-alias DefaultHttpClient org.apache.http.impl.client.DefaultHttpClient)
80 | (define-alias HttpClient org.apache.http.client.HttpClient)
81 |
82 | (define-alias Uri android.net.Uri)
83 |
84 | (define-alias TypedValue android.util.TypedValue)
85 |
86 | (define-alias FVector gnu.lists.FVector)
87 |
88 | (define-namespace Log "class:android.util.Log")
89 |
90 | ;;; Manage tasks
91 |
92 | (define-syntax (async-task stx)
93 | ;; TODO should add in the ability to bind (this) at the callsite to
94 | ;; (this-parent) so that I don't need an ugly let
95 | (syntax-case stx ()
96 | ((_ paramsT progressT resultT . r)
97 | (letrec
98 | ((process
99 | (lambda (form)
100 | (syntax-case form (background cancel post pre progress publish-progress)
101 | (((background name stmt ...) . rest)
102 | ;; FIXME using object here instead of object1 seems to
103 | ;; change the object macro at the toplevel in the
104 | ;; interpreter, this looks like a bug
105 | (cons #`((doInBackground (object1 ::Object[])) (@java.lang.Override) ::Object
106 | (as resultT (let ((name (gnu.lists.FVector[paramsT] object1))) stmt ...)))
107 | (process #`rest)))
108 | (((cancel name stmt ...) . rest)
109 | (cons #`((onCancelled (object1 ::Object)) (@java.lang.Override) ::void
110 | (let ((name (as resultT object1))) stmt ...))
111 | (process #`rest)))
112 | (((post name stmt ...) . rest)
113 | (cons #`((onPostExecute (object1 ::Object)) (@java.lang.Override) ::void
114 | (let ((name (as resultT object1))) stmt ...))
115 | (process #`rest)))
116 | (((pre stmt ...) . rest)
117 | (cons #`(onPreExecute (@java.lang.Override) ::void stmt ...)
118 | (process #`rest)))
119 | (((progress stmt ...) . rest)
120 | (cons #`((onProgressUpdate (object1 ::Object[])) (@java.lang.Override) ::void
121 | (let ((name (gnu.lists.FVector[progressT] object1)))
122 | stmt ...))
123 | (process #`rest)))
124 | (((publish-progress stmt ...) . rest)
125 | (cons #`((publishProgress (object1 ::Object[])) (@java.lang.Override) ::void
126 | (let ((name (gnu.lists.FVector[progressT] object1)))
127 | stmt ...))
128 | (process #`rest)))
129 | (() '())))))
130 | #`(object (android.os.AsyncTask) #,@(process #`r))))))
131 |
132 | (define-syntax (with-that stx)
133 | (syntax-case stx ()
134 | ((_ stmts ...) (with-syntax ((that (datum->syntax stx 'that)))
135 | #'(let ((that (this))) stmts ...)))))
136 |
137 | (define-syntax (thread x)
138 | (syntax-case x ()
139 | ((_ stmts ...)
140 | #`(with-that (as Thread (object (Thread) ((run) ::void stmts ...)))))))
141 |
142 | (define-syntax (runnable x)
143 | (syntax-case x ()
144 | ((_ stmts ...)
145 | #`(with-that (as Runnable (object (Runnable) ((run) ::void stmts ...)))))))
146 |
147 | (define-syntax (timer-task x)
148 | (syntax-case x ()
149 | ((_ stmts ...)
150 | #`(with-that (as TimerTask (object (TimerTask) ((run) ::void stmts ...)))))))
151 |
152 | ;;; Listeners
153 |
154 | (define-syntax (on-item-click stx)
155 | (syntax-case stx ()
156 | ((_ obj stmts ...)
157 | (with-syntax ((adapter (datum->syntax stx 'adapter))
158 | (view (datum->syntax stx 'view))
159 | (position (datum->syntax stx 'position))
160 | (id (datum->syntax stx 'id)))
161 | #`(obj:setOnItemClickListener
162 | (with-that
163 | (as OnItemClickListener
164 | (object (OnItemClickListener)
165 | ((onItemClick adapter view position id) ::void
166 | stmts ...)))))))))
167 |
168 | (define-syntax (on-user-seek-bar-change stx)
169 | (syntax-case stx ()
170 | ((_ obj stmts ...)
171 | (with-syntax ((bar (datum->syntax stx 'bar))
172 | (position (datum->syntax stx 'position))
173 | (from-user (datum->syntax stx 'from-user)))
174 | #`(obj:setOnSeekBarChangeListener
175 | (with-that
176 | (as OnSeekBarChangeListener
177 | (object (OnSeekBarChangeListener)
178 | ((onProgressChanged seek-bar position from-user) ::void
179 | (when from-user stmts ...))
180 | ((onStartTrackingTouch seek-bar) ::void #f)
181 | ((onStopTrackingTouch seek-bar) ::void #f)))))))))
182 |
183 | ;;; Start activities
184 |
185 | (define-syntax (simple-start-activity stx)
186 | (syntax-case stx ()
187 | ((_ obj activity arguments)
188 | #`(let ((intent ::android.content.Intent (make obj activity)))
189 | ;; this may cause runtime errors if you're trying to put an
190 | ;; object that isn't supported by putExtra
191 | (with-compile-options warn-invoke-unknown-method: #f
192 | (for-each (lambda (a) (intent:putExtra (car a) (cdr a))) arguments))
193 | (obj:startActivity intent)))))
194 |
195 | ;;; Basic file chooser using an external file manager
196 |
197 | ;; FIXME This doesn't work for some reason, so we need to initialize it manually
198 | ;; FIXME (string-hash "*file-chooser-request*") ends up not delivering requests
199 | (define *file-chooser-request* 33)
200 | (define (file-chooser (obj ::Activity))
201 | ;; TODO, why doesn't Intent work?
202 | (let ((intent
203 | (make
204 | (as String android.content.Intent:ACTION_GET_CONTENT))))
205 | (intent:setType "*/*")
206 | (intent:addCategory android.content.Intent:CATEGORY_OPENABLE)
207 | (try-catch
208 | (obj:startActivityForResult (intent:createChooser intent "Select a book to read") *file-chooser-request*)
209 | (ex
210 | ((Toast:makeText obj "No file manager, install one from the play store" Toast:LENGTH_SHORT):show)))))
211 | (define (file-chooser-result f)
212 | (lambda ((obj ::Activity) (request ::int) (result ::int) (data ::Intent))
213 | (if (and (= request *file-chooser-request*) (= result obj:RESULT_OK))
214 | (begin (let ((uri ::Uri (data:getData)))
215 | (Log:i "speedread" (format #f "got back URI ~a ~a" (uri:toString) (uri:getPath)))
216 | (f uri))
217 | #t)
218 | #f)))
219 |
220 | ;;; Manage activity results
221 |
222 | (define (multiple-activity-results (obj ::Activity) . fs)
223 | (lambda ((request ::int) (result ::int) (data ::Intent))
224 | (Log:d "multiple-activity-results" (format #f "~a ~a ~a" request result data))
225 | (let loop ((fs fs))
226 | (if (null? fs)
227 | #f
228 | (let ((r ((car fs) obj request result data)))
229 | (if r #t (loop (cdr fs))))))))
230 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter8/src/com/zeroxab/learningandroid/yamba/Yamba.scm:
--------------------------------------------------------------------------------
1 | ;;; FIXME
2 | ;;; I don't know how to use require, so collections_utils.scm gets to
3 | ;;; be included here
4 |
5 | ;;; Returns a list of the elements of the given Enumeration.
6 | (define (Enumeration->list (enum :: java.util.Enumeration)) :: list
7 | (let loop ((ls '()))
8 | (if (enum:hasMoreElements)
9 | (loop (cons (enum:nextElement) ls))
10 | (reverse ls))))
11 |
12 | ;;; Returns a list of the elements of the given Iterator.
13 | (define (Iterator->list (iter :: java.util.Iterator)) :: list
14 | (let loop ((ls '()))
15 | (if (iter:hasNext)
16 | (loop (cons (iter:next) ls))
17 | (reverse ls))))
18 |
19 | ;;; Returns a list of the elements of the given Iterable.
20 | (define (Iterable->list (it :: java.lang.Iterable)) :: list
21 | (Iterator->list (it:iterator)))
22 |
23 | ;;; Returns a list of the elements of the given array.
24 | (define (Array->list (array :: Object)) :: list
25 | (when (*:isArray (array:getClass))
26 | (let* ((n :: int (java.lang.reflect.Array:getLength array))
27 | (result-vector :: vector (make-vector n)))
28 | (do ((i 0 (+ i 1)))
29 | ((= i n) (vector->list result-vector))
30 | (vector-set! result-vector i (array i))))))
31 |
32 | ;;; Converts the given object into a list.
33 | (define ->list
34 | (case-lambda
35 | ((l :: list) l)
36 | ((l :: java.lang.Iterable) (Iterable->list l))
37 | ((l :: java.util.Iterator) (Iterator->list l))
38 | ((l :: java.util.Enumeration) (Enumeration->list l))
39 | ((l :: Object) (Array->list l))))
40 |
41 | ;;; Map for an Enumeration
42 | (define (map-enumeration (f :: procedure)
43 | (enum :: java.util.Enumeration))
44 | :: list
45 | (let loop ((ls '()))
46 | (if (enum:hasMoreElements)
47 | (loop (cons (f (enum:nextElement)) ls))
48 | (reverse ls))))
49 |
50 | ;;; Map for an Iterator
51 | (define (map-iterator (f :: procedure)
52 | (iter :: java.util.Iterator))
53 | :: list
54 | (let loop ((ls '()))
55 | (if (iter:hasNext)
56 | (loop (cons (f (iter:next)) ls))
57 | (reverse ls))))
58 |
59 | ;;; Map for an Iterable
60 | (define (map-iterable (f :: procedure)
61 | (it :: java.lang.Iterable))
62 | :: list
63 | (map-iterator f (it:iterator)))
64 |
65 | ;;; Map for an Array
66 | (define (map-array (f :: procedure)
67 | (obj :: Object))
68 | :: list
69 | (when (*:isArray (obj:getClass))
70 | (let* ((n :: int (java.lang.reflect.Array:getLength obj))
71 | (result-vector :: vector (make-vector n)))
72 | (do ((i 0 (+ i 1)))
73 | ((= i n) (vector->list result-vector))
74 | (vector-set! result-vector i (f (obj i)))))))
75 |
76 | ;;; For-each for an Enumeration
77 | (define (for-each-enumeration (f :: procedure)
78 | (enum :: java.util.Enumeration))
79 | (let loop ()
80 | (when (enum:hasMoreElements)
81 | (f (enum:nextElement))
82 | (loop))))
83 |
84 | ;;; For-each for an Iterator
85 | (define (for-each-iterator (f :: procedure)
86 | (iter :: java.util.Iterator))
87 | (let loop ()
88 | (when (iter:hasNext)
89 | (f (iter:next))
90 | (loop))))
91 |
92 | ;;; For-each for an Iterable
93 | (define (for-each-iterable (f :: procedure)
94 | (it :: java.lang.Iterable))
95 | (for-each-iterator f (it:iterator)))
96 |
97 | ;;; For-each for an Array
98 | (define (for-each-array (f :: procedure)
99 | (obj :: Object))
100 | (when (*:isArray (obj:getClass))
101 | (let ((n :: int (java.lang.reflect.Array:getLength obj)))
102 | (do ((i 0 (+ i 1)))
103 | ((= i n))
104 | (f (obj i))))))
105 |
106 | ;;; A version of map which works with lists, Enumerations, Iterators,
107 | ;;; Iterables, and Arrays.
108 | (define better-map
109 | (case-lambda
110 | (((f :: procedure) (l :: list))
111 | (map f l))
112 | (((f :: procedure) (l :: java.util.Enumeration))
113 | (map-enumeration f l))
114 | (((f :: procedure) (l :: java.util.Iterator))
115 | (map-iterator f l))
116 | (((f :: procedure) (l :: java.lang.Iterable))
117 | (map-iterable f l))
118 | (((f :: procedure) (l :: Object))
119 | (map-array f l))
120 | (((f :: procedure) (l1 :: Object) (l2 :: Object) . rest)
121 | (apply map f (append (map ->list `(,l1 ,l2))
122 | (map ->list rest))))))
123 |
124 | ;;; A version of for-each which works with lists, Enumerations,
125 | ;;; Iterators, Iterables, and Arrays.
126 | (define better-for-each
127 | (case-lambda
128 | (((f :: procedure) (l :: list))
129 | (for-each f l))
130 | (((f :: procedure) (l :: java.util.Enumeration))
131 | (for-each-enumeration f l))
132 | (((f :: procedure) (l :: java.util.Iterator))
133 | (for-each-iterator f l))
134 | (((f :: procedure) (l :: java.lang.Iterable))
135 | (for-each-iterable f l))
136 | (((f :: procedure) (l :: Object))
137 | (for-each-array f l))
138 | (((f :: procedure) (l1 :: Object) (l2 :: Object) . rest)
139 | (apply for-each f (append (map ->list `(,l1 ,l2))
140 | (map ->list rest))))))
141 |
142 |
143 | ;;;;;;
144 |
145 | (require 'android-defs)
146 | (require 'srfi-1)
147 | (require 'syntax-utils)
148 |
149 | (define-namespace Log "class:android.util.Log")
150 |
151 | ;; from kawa/testsuite/classes1.scm
152 | (define-syntax (import-class form)
153 | (syntax-case form ()
154 | ((import-class fqcn)
155 | (let* ((cls :: java.lang.Class (eval (syntax fqcn)))
156 | (name (string->symbol (java.lang.Class:getSimpleName cls))))
157 | #`(define-alias #,(datum->syntax-object form name) fqcn)))))
158 |
159 | (define-alias Arrays java.util.Arrays)
160 | (define-alias Math java.lang.Math)
161 | (define-alias InterruptedException java.lang.InterruptedException)
162 | (define-alias Thread java.lang.Thread)
163 |
164 | (define-alias Application android.app.Application)
165 | (define-alias Activity android.app.Activity)
166 | (define-alias Service android.app.Service)
167 | (define-alias Bitmap android.graphics.Bitmap)
168 | (define-alias Canvas android.graphics.Canvas)
169 | (define-alias Color android.graphics.Color)
170 | (define-alias Drawable android.graphics.drawable.Drawable)
171 | (define-alias Resources android.content.res.Resources)
172 | (define-alias Context android.content.Context)
173 | (define-alias Intent android.content.Intent)
174 | (define-alias SharedPreferences android.content.SharedPreferences)
175 | (define-alias Handler android.os.Handler)
176 | (define-alias Bundle android.os.Bundle)
177 | (define-alias IBinder android.os.IBinder)
178 | (define-alias KeyEvent android.view.KeyEvent)
179 | (define-alias OnClickListener android.view.View$OnClickListener)
180 | (define-alias SurfaceHolder android.view.SurfaceHolder)
181 | (define-alias Menu android.view.Menu)
182 | (define-alias MenuItem android.view.MenuItem)
183 | (define-alias Toast android.widget.Toast)
184 | (define-alias Editable android.text.Editable)
185 | (define-alias TextWatcher android.text.TextWatcher)
186 | (define-alias PreferenceActivity android.preference.PreferenceActivity)
187 | (define-alias PreferenceManager android.preference.PreferenceManager)
188 |
189 | (define-alias FVector gnu.lists.FVector)
190 |
191 | (define-alias R com.zeroxab.learningandroid.yamba.R)
192 |
193 | (define-alias Twitter winterwell.jtwitter.Twitter)
194 |
195 | (define-syntax async-task
196 | (lambda (x)
197 | ;; TODO should add in the ability to bind (this) at the callsite to
198 | ;; (this-parent) so that I don't need an ugly let
199 | (syntax-case x ()
200 | ((async-task paramsT progressT resultT . r)
201 | (letrec
202 | ((process
203 | (lambda (form)
204 | (syntax-case form (background cancel post pre progress publish-progress)
205 | (((background name stmt ...) . rest)
206 | ;; FIXME using object here instead of object1 seems to
207 | ;; change the object macro at the toplevel in the
208 | ;; interpreter, this looks like a bug
209 | (cons #`((doInBackground (object1 ::Object[])) (@java.lang.Override) ::Object
210 | (as resultT (let ((name (gnu.lists.FVector[paramsT] object1))) stmt ...)))
211 | (process #`rest)))
212 | (((cancel name stmt ...) . rest)
213 | (cons #`((onCancelled (object1 ::Object)) (@java.lang.Override) ::void
214 | (let ((name (as resultT object1))) stmt ...))
215 | (process #`rest)))
216 | (((post name stmt ...) . rest)
217 | (cons #`((onPostExecute (object1 ::Object)) (@java.lang.Override) ::void
218 | (let ((name (as resultT object1))) stmt ...))
219 | (process #`rest)))
220 | (((pre stmt ...) . rest)
221 | (cons #`(onPreExecute (@java.lang.Override) ::void stmt ...)
222 | (process #`rest)))
223 | (((progress stmt ...) . rest)
224 | (cons #`((onProgressUpdate (object1 ::Object[])) (@java.lang.Override) ::void
225 | (let ((name (gnu.lists.FVector[progressT] object1)))
226 | stmt ...))
227 | (process #`rest)))
228 | (((publish-progress stmt ...) . rest)
229 | (cons #`((publishProgress (object1 ::Object[])) (@java.lang.Override) ::void
230 | (let ((name (gnu.lists.FVector[progressT] object1)))
231 | stmt ...))
232 | (process #`rest)))
233 | (() '())))))
234 | #`(object (android.os.AsyncTask) #,@(process #`r)))))))
235 |
236 | (define-syntax simple-thread
237 | (lambda (x)
238 | ;; TODO should add in the ability to bind (this) at the callsite to
239 | ;; (this-parent) so that I don't need an ugly let
240 | (syntax-case x ()
241 | ((simple-thread stmts ...)
242 | #`(as Thread (object (Thread) ((run) ::void
243 | stmts ...)))))))
244 |
245 | (define-simple-class PrefActivity (PreferenceActivity)
246 | ((onCreate (savedInstanceState ::Bundle))
247 | (invoke-special android.app.Activity (this) 'onCreate savedInstanceState)
248 | (addPreferencesFromResource R$xml:prefs)))
249 |
250 | (define-simple-class YambaApplication (Application)
251 | (twitter ::Twitter)
252 | (preferences ::SharedPreferences)
253 | (service-running? ::boolean)
254 | ((onCreate)
255 | (invoke-special android.app.Application (this) 'onCreate)
256 | (set! preferences (PreferenceManager:getDefaultSharedPreferences (this)))
257 | (preferences:registerOnSharedPreferenceChangeListener
258 | (lambda ((preferences ::SharedPreferences) (key ::String))
259 | (set! twitter #!null))))
260 | ((onTerminate)
261 | (invoke-special android.app.Application (this) 'onTerminate))
262 | ((get-twitter) ::Twitter
263 | (synchronized (this)
264 | (when (equal? twitter #!null)
265 | (set! twitter (Twitter:new (preferences:getString "username" "student")
266 | (preferences:getString "password" "password")))
267 | (twitter:setAPIRootUrl (preferences:getString "apiRoot" "http://yamba.marakana.com/api"))))
268 | twitter))
269 |
270 | (define-simple-class StatusActivity (Activity )
271 | (edit-text ::EditText)
272 | (update-button ::Button)
273 | (text-count ::TextView)
274 |
275 | ((onCreate (savedInstanceState ::Bundle))
276 | (invoke-special android.app.Activity (this) 'onCreate savedInstanceState)
277 | (setContentView R$layout:status)
278 | (set! edit-text (findViewById R$id:editText))
279 | (set! update-button (findViewById R$id:buttonUpdate))
280 | (update-button:setOnClickListener
281 | (lambda ((view ::View))
282 | ;; FIXME this is nasty
283 | (let* ((activity-this (this)))
284 | (*:execute
285 | (async-task
286 | String int String
287 | (background statuses
288 | (try-catch
289 | (begin (((as YambaApplication (getApplication)):get-twitter):setStatus (statuses 0))
290 | (statuses 0))
291 | (e winterwell.jtwitter.TwitterException
292 | (Log:e "Yamba-StatusActivity" "Failed to set twitter status!")
293 | (e:printStackTrace)
294 | "Ooops, failed to post status!")))
295 | (progress values #!null)
296 | (post result ((Toast:makeText activity-this (as result) Toast:LENGTH_LONG):show)))
297 | ((edit-text:getText):toString))
298 | (Log:d "Yamba-StatusActivity" "Clicked!"))))
299 | (set! text-count (findViewById R$id:textCount))
300 | (text-count:setText (140:toString))
301 | (text-count:setTextColor Color:GREEN)
302 | (edit-text:addTextChangedListener (this)))
303 |
304 | ((afterTextChanged (status-text ::Editable))
305 | (let ((count (- 140 (status-text:length))))
306 | (text-count:setText (format #f "~a" count))
307 | (text-count:setTextColor (cond ((< count 0) Color:RED)
308 | ((< count 10) Color:YELLOW)
309 | (else Color:GREEN)))))
310 | ((beforeTextChanged sequence start count after) #f)
311 | ((onTextChanged sequence start before count) #f)
312 |
313 | ((onCreateOptionsMenu (menu ::Menu))
314 | ((getMenuInflater):inflate R$menu:menu menu)
315 | #t)
316 | ((onOptionsItemSelected (item ::MenuItem))
317 | (cond ((equal? (item:getItemId) R$id:itemPrefs)
318 | (startActivity (make (this) PrefActivity)))
319 | ((equal? (item:getItemId) R$id:itemServiceStart)
320 | (startService (make (this) UpdaterService)))
321 | ((equal? (item:getItemId) R$id:itemServiceStop)
322 | (stopService (make (this) UpdaterService)))
323 | (else #f))
324 | #t))
325 |
326 | (define update-delay 10000) ;; 10 seconds
327 |
328 | (define-simple-class UpdaterService (Service)
329 | (run-flag ::boolean)
330 | (updater ::Thread)
331 | ((onBind (intent ::Intent)) #!null)
332 | ((onCreate) (invoke-special android.app.Service (this) 'onCreate)
333 | (Log:d "Yamba-UpdaterService" "Created")
334 | (set! updater
335 | (simple-thread
336 | (let loop ()
337 | (when run-flag
338 | (Log:d "Yamba-UpdaterService" "Running")
339 | (try-catch (begin (Log:d "Yamba-UpdaterService" "Updated Ran")
340 | (better-for-each (lambda (status) (Log:d "Yamba-UpdaterService" status))
341 | (((as YambaApplication (getApplication)):get-twitter):getFriendsTimeline)))
342 | (e java.lang.InterruptedException
343 | (Log:e "Yamba-UpdaterService" "Failed!")
344 | (set! run-flag #f)))
345 | (Thread:sleep update-delay)
346 | (loop)))))
347 | (set! run-flag #f))
348 | ((onStartCommand (intent ::Intent) (flags ::int) (startId ::int))
349 | (invoke-special android.app.Service (this) 'onStartCommand intent flags startId)
350 | (set! (as YambaApplication (getApplication)):service-running? #t)
351 | (*:start updater)
352 | (set! run-flag #t)
353 | (Log:d "Yamba-UpdaterService" "Started")
354 | Service:START_STICKY)
355 | ((onDestroy)
356 | (set! run-flag #f)
357 | (set! (as YambaApplication (getApplication)):service-running? #f)
358 | (*:interrupt updater)
359 | (Log:d "Yamba-UpdaterService" "Destroyed")))
360 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter9/src/com/zeroxab/learningandroid/yamba/Yamba.scm:
--------------------------------------------------------------------------------
1 | (require 'android-defs)
2 | (require 'srfi-1)
3 | (require 'syntax-utils)
4 | (require )
5 |
6 | (define-namespace Log "class:android.util.Log")
7 |
8 | ;; from kawa/testsuite/classes1.scm
9 | (define-syntax (import-class form)
10 | (syntax-case form ()
11 | ((import-class fqcn)
12 | (let* ((cls :: java.lang.Class (eval (syntax fqcn)))
13 | (name (string->symbol (java.lang.Class:getSimpleName cls))))
14 | #`(define-alias #,(datum->syntax-object form name) fqcn)))))
15 |
16 | (define-alias Arrays java.util.Arrays)
17 | (define-alias Math java.lang.Math)
18 | (define-alias InterruptedException java.lang.InterruptedException)
19 | (define-alias Thread java.lang.Thread)
20 |
21 | (define-alias Application android.app.Application)
22 | (define-alias Activity android.app.Activity)
23 | (define-alias Service android.app.Service)
24 | (define-alias Bitmap android.graphics.Bitmap)
25 | (define-alias Canvas android.graphics.Canvas)
26 | (define-alias Color android.graphics.Color)
27 | (define-alias Drawable android.graphics.drawable.Drawable)
28 | (define-alias Context android.content.Context)
29 | (define-alias Intent android.content.Intent)
30 | (define-alias Resources android.content.res.Resources)
31 | (define-alias SharedPreferences android.content.SharedPreferences)
32 | (define-alias ContentValues android.content.ContentValues)
33 | (define-alias Handler android.os.Handler)
34 | (define-alias Bundle android.os.Bundle)
35 | (define-alias IBinder android.os.IBinder)
36 | (define-alias KeyEvent android.view.KeyEvent)
37 | (define-alias OnClickListener android.view.View$OnClickListener)
38 | (define-alias SurfaceHolder android.view.SurfaceHolder)
39 | (define-alias Menu android.view.Menu)
40 | (define-alias MenuItem android.view.MenuItem)
41 | (define-alias Toast android.widget.Toast)
42 | (define-alias Editable android.text.Editable)
43 | (define-alias TextWatcher android.text.TextWatcher)
44 | (define-alias PreferenceActivity android.preference.PreferenceActivity)
45 | (define-alias PreferenceManager android.preference.PreferenceManager)
46 | (define-alias BaseColumns android.provider.BaseColumns)
47 | (define-alias Cursor android.database.Cursor)
48 | (define-alias SQLiteDatabase android.database.sqlite.SQLiteDatabase)
49 | (define-alias SQLiteOpenHelper android.database.sqlite.SQLiteOpenHelper)
50 |
51 | (define-alias FVector gnu.lists.FVector)
52 |
53 | (define-alias R com.zeroxab.learningandroid.yamba.R)
54 |
55 | (define-alias Twitter winterwell.jtwitter.Twitter)
56 |
57 | (define update-delay 10000) ;; 10 seconds
58 |
59 | (define-syntax async-task
60 | (lambda (x)
61 | ;; TODO should add in the ability to bind (this) at the callsite to
62 | ;; (this-parent) so that I don't need an ugly let
63 | (syntax-case x ()
64 | ((async-task paramsT progressT resultT . r)
65 | (letrec
66 | ((process
67 | (lambda (form)
68 | (syntax-case form (background cancel post pre progress publish-progress)
69 | (((background name stmt ...) . rest)
70 | ;; FIXME using object here instead of object1 seems to
71 | ;; change the object macro at the toplevel in the
72 | ;; interpreter, this looks like a bug
73 | (cons #`((doInBackground (object1 ::Object[])) (@java.lang.Override) ::Object
74 | (as resultT (let ((name (gnu.lists.FVector[paramsT] object1))) stmt ...)))
75 | (process #`rest)))
76 | (((cancel name stmt ...) . rest)
77 | (cons #`((onCancelled (object1 ::Object)) (@java.lang.Override) ::void
78 | (let ((name (as resultT object1))) stmt ...))
79 | (process #`rest)))
80 | (((post name stmt ...) . rest)
81 | (cons #`((onPostExecute (object1 ::Object)) (@java.lang.Override) ::void
82 | (let ((name (as resultT object1))) stmt ...))
83 | (process #`rest)))
84 | (((pre stmt ...) . rest)
85 | (cons #`(onPreExecute (@java.lang.Override) ::void stmt ...)
86 | (process #`rest)))
87 | (((progress stmt ...) . rest)
88 | (cons #`((onProgressUpdate (object1 ::Object[])) (@java.lang.Override) ::void
89 | (let ((name (gnu.lists.FVector[progressT] object1)))
90 | stmt ...))
91 | (process #`rest)))
92 | (((publish-progress stmt ...) . rest)
93 | (cons #`((publishProgress (object1 ::Object[])) (@java.lang.Override) ::void
94 | (let ((name (gnu.lists.FVector[progressT] object1)))
95 | stmt ...))
96 | (process #`rest)))
97 | (() '())))))
98 | #`(object (android.os.AsyncTask) #,@(process #`r)))))))
99 |
100 | (define-syntax simple-thread
101 | (lambda (x)
102 | ;; TODO should add in the ability to bind (this) at the callsite to
103 | ;; (this-parent) so that I don't need an ugly let
104 | (syntax-case x ()
105 | ((simple-thread stmts ...)
106 | #`(as Thread (object (Thread) ((run) ::void
107 | stmts ...)))))))
108 |
109 | (define-simple-class PrefActivity (PreferenceActivity)
110 | ((onCreate (savedInstanceState ::Bundle))
111 | (invoke-special android.app.Activity (this) 'onCreate savedInstanceState)
112 | (addPreferencesFromResource R$xml:prefs)))
113 |
114 | (define-simple-class YambaApplication (Application)
115 | (twitter ::Twitter)
116 | (preferences ::SharedPreferences)
117 | (service-running? ::boolean)
118 | (status-data ::StatusData)
119 | ((onCreate)
120 | (invoke-special android.app.Application (this) 'onCreate)
121 | (set! preferences (PreferenceManager:getDefaultSharedPreferences (this)))
122 | (set! status-data (make StatusData (this)))
123 | (preferences:registerOnSharedPreferenceChangeListener
124 | (lambda ((preferences ::SharedPreferences) (key ::String))
125 | (set! twitter #!null))))
126 | ((onTerminate)
127 | (invoke-special android.app.Application (this) 'onTerminate))
128 | ((get-twitter) ::Twitter
129 | (synchronized
130 | (this)
131 | (when (equal? twitter #!null)
132 | (set! twitter (Twitter:new (preferences:getString "username" "student")
133 | (preferences:getString "password" "password")))
134 | (twitter:setAPIRootUrl (preferences:getString "apiRoot" "http://yamba.marakana.com/api"))))
135 | twitter)
136 | ((get-status-data) ::StatusData
137 | status-data)
138 | ((fetch-status-updates) ::int
139 | (Log:d "Yamba" "Fetching status")
140 | (let ((twitter (get-twitter)))
141 | (if (equal? twitter #!null)
142 | (begin (Log:e "Yamba" "Twitter not initialized!") 0)
143 | (try-catch
144 | (let* ((latest-status-at
145 | ::long
146 | ((get-status-data):get-latest-status-created-at-time))
147 | (nr
148 | (count
149 | (lambda (a) (equal? #t a))
150 | (->list
151 | (better-map
152 | (lambda (status ::)
153 | (let* ((values (make ContentValues))
154 | (created-at
155 | (java.lang.Long ((status:getCreatedAt):getTime))))
156 | (values:clear)
157 | (values:put StatusData:C_ID status:id)
158 | (values:put StatusData:C_CREATED_AT created-at)
159 | ;; (values:put StatusData:C_SOURCE status:source)
160 | (values:put StatusData:C_TEXT status:text)
161 | (values:put StatusData:C_USER (status:getUser):name)
162 | ((get-status-data):insert-or-ignore values)
163 | (< latest-status-at created-at)))
164 | (twitter:getFriendsTimeline))))))
165 | (Log:d "Yamba added status update" nr)
166 | nr)
167 | (e android.database.SQLException ;; java.lang.RuntimeException
168 | (Log:e "Yamba-UpdaterService" e)
169 | (Log:e "Yamba-UpdaterService" "Runtime!")
170 | 0))))))
171 |
172 | (define-simple-class StatusActivity (Activity )
173 | (edit-text ::EditText)
174 | (update-button ::Button)
175 | (text-count ::TextView)
176 | ((onCreate (savedInstanceState ::Bundle))
177 | (invoke-special android.app.Activity (this) 'onCreate savedInstanceState)
178 | (setContentView R$layout:status)
179 | (set! edit-text (findViewById R$id:editText))
180 | (set! update-button (findViewById R$id:buttonUpdate))
181 | (update-button:setOnClickListener
182 | (lambda ((view ::View))
183 | ;; FIXME this is nasty
184 | (let* ((activity-this (this)))
185 | (*:execute
186 | (async-task
187 | String int String
188 | (background statuses
189 | (try-catch
190 | (begin (((as YambaApplication (getApplication)):get-twitter):setStatus (statuses 0))
191 | (statuses 0))
192 | (e winterwell.jtwitter.TwitterException
193 | (Log:e "Yamba-StatusActivity" "Failed to set twitter status!")
194 | (e:printStackTrace)
195 | "Ooops, failed to post status!")))
196 | (progress values #!null)
197 | (post result ((Toast:makeText activity-this (as result) Toast:LENGTH_LONG):show)))
198 | ((edit-text:getText):toString))
199 | (Log:d "Yamba-StatusActivity" "Clicked!"))))
200 | (set! text-count (findViewById R$id:textCount))
201 | (text-count:setText (140:toString))
202 | (text-count:setTextColor Color:GREEN)
203 | (edit-text:addTextChangedListener (this)))
204 | ((afterTextChanged (status-text ::Editable))
205 | (let ((count (- 140 (status-text:length))))
206 | (text-count:setText (format #f "~a" count))
207 | (text-count:setTextColor (cond ((< count 0) Color:RED)
208 | ((< count 10) Color:YELLOW)
209 | (else Color:GREEN)))))
210 | ((beforeTextChanged sequence start count after) #f)
211 | ((onTextChanged sequence start before count) #f)
212 | ((onCreateOptionsMenu (menu ::Menu))
213 | ((getMenuInflater):inflate R$menu:menu menu)
214 | #t)
215 | ((onOptionsItemSelected (item ::MenuItem))
216 | (cond ((equal? (item:getItemId) R$id:itemPrefs)
217 | (startActivity (make (this) PrefActivity)))
218 | ((equal? (item:getItemId) R$id:itemServiceStart)
219 | (startService (make (this) UpdaterService)))
220 | ((equal? (item:getItemId) R$id:itemServiceStop)
221 | (stopService (make (this) UpdaterService)))
222 | (else #f))
223 | #t))
224 |
225 | (define-simple-class UpdaterService (Service)
226 | (updater ::Thread)
227 | (running? ::boolean)
228 | ((onBind (intent ::Intent)) #!null)
229 | ((onCreate) (invoke-special android.app.Service (this) 'onCreate)
230 | (Log:d "Yamba-UpdaterService" "Created")
231 | (set! updater
232 | (simple-thread
233 | (try-catch
234 | (let loop ()
235 | (when running?
236 | (Log:d "Yamba-UpdaterService" "Running")
237 | (when (> ((as YambaApplication (getApplication)):fetch-status-updates) 0)
238 | (Log:d "UpdateService" "New status"))
239 | (Thread:sleep update-delay)
240 | (loop)))
241 | (e java.lang.InterruptedException
242 | (Log:e "Yamba-UpdaterService" e)
243 | (Log:e "Yamba-UpdaterService" "Failed!")
244 | #f)))))
245 | ((onStartCommand (intent ::Intent) (flags ::int) (startId ::int))
246 | (invoke-special android.app.Service (this) 'onStartCommand intent flags startId)
247 | (unless running?
248 | (set! (as YambaApplication (getApplication)):service-running? #t)
249 | (set! running? #t)
250 | (*:start updater)
251 | (Log:d "Yamba-UpdaterService" "Started"))
252 | Service:START_STICKY)
253 | ((onDestroy)
254 | (set! (as YambaApplication (getApplication)):service-running? #f)
255 | (when running?
256 | (set! running? #f)
257 | (*:interrupt updater)
258 | (Log:d "Yamba-UpdaterService" "Destroyed"))))
259 |
260 | (define-simple-class dbHelper (SQLiteOpenHelper)
261 | ((*init* (context_ ::Context))
262 | (invoke-special android.database.sqlite.SQLiteOpenHelper
263 | (this) '*init* context_ StatusData:DATABASE
264 | #!null StatusData:VERSION))
265 | ((onCreate (db ::SQLiteDatabase))
266 | (let ((sql (string-append "create table "
267 | StatusData:TABLE " ("
268 | StatusData:C_ID " int primary key, "
269 | StatusData:C_CREATED_AT " int, "
270 | StatusData:C_USER " text, "
271 | StatusData:C_TEXT " text)")))
272 | (*:execSQL db sql)
273 | (Log:d "Yamba-DB" (string-append "onCreated sql: " sql))))
274 | ((onUpgrade (db ::SQLiteDatabase) (oldVersion ::int) (newVersion ::int))
275 | ;; instead of an alter table we just drop and recreate
276 | (*:execSQL db (string-append "drop table if exists " StatusData:TABLE))
277 | (Log:d "Yamba-DB" "onUpdated")
278 | (onCreate db)))
279 |
280 | (define-simple-class StatusData ()
281 | (DATABASE ::String allocation: 'static access: 'final init: "timeline.db")
282 | (VERSION ::int allocation: 'static access: 'final init: 1)
283 | (TABLE ::String allocation: 'static access: 'final init: "timeline")
284 | (C_ID ::String allocation: 'static access: 'final init: BaseColumns:_ID)
285 | (C_CREATED_AT ::String allocation: 'static access: 'final init: "created_at")
286 | (C_TEXT ::String allocation: 'static access: 'final init: "text")
287 | (C_USER ::String allocation: 'static access: 'final init: "user")
288 | (C_SOURCE ::String allocation: 'static access: 'final init: "source")
289 | ;; (GET_ALL_ORDER_BY ::String allocation: 'static access: 'final
290 | ;; init: C_CREATED_AT + " DESC")
291 | ;; (MAX_CREATED_AT_COLUMNS ::String allocation: 'static access: 'final
292 | ;; init: "max(" + C_CREATED_AT + ")")
293 | (db-helper ::dbHelper allocation: 'static access: '(private final))
294 | ((*init* (context_ ::Context))
295 | (set! db-helper (make dbHelper context_)))
296 | ((insert-or-ignore (values ::ContentValues))
297 | (Log:d "StatusData insert of ignore" values)
298 | (let ((db ::SQLiteDatabase (db-helper:getWritableDatabase)))
299 | (try-finally
300 | (try-catch (db:insertWithOnConflict TABLE #!null values
301 | SQLiteDatabase:CONFLICT_IGNORE)
302 | (e android.database.SQLException
303 | (Log:e "Yamba-Updater SQL" e)
304 | #f))
305 | (db:close))))
306 | ((get-status-updates)
307 | (let ((db ::SQLiteDatabase (db-helper:getReadableDatabase)))
308 | (try-finally
309 | ((db-helper:getReadableDatabase):query
310 | TABLE #!null #!null #!null #!null #!null
311 | (string-append C_CREATED_AT " DESC"))
312 | (db:close))))
313 | ((get-latest-status-created-at-time)
314 | (let ((db ::SQLiteDatabase (db-helper:getReadableDatabase)))
315 | (try-finally
316 | (let ((cursor ::Cursor
317 | (db:query TABLE
318 | (String[] (string-append "max(" C_CREATED_AT ")"))
319 | #!null #!null #!null #!null #!null)))
320 | (try-finally
321 | (if (cursor:moveToNext) (cursor:getLong 0) java.lang.Long:MIN_VALUE)
322 | (cursor:close)))
323 | (db:close))))
324 | ((get-status-text-by-id (id ::long))
325 | (let ((db ::SQLiteDatabase (db-helper:getReadableDatabase)))
326 | (try-finally
327 | (let ((cursor ::Cursor (db:query TABLE
328 | (String[] C_TEXT)
329 | (string-append C_ID "=" id)
330 | #!null #!null #!null #!null)))
331 | (try-finally
332 | (if (cursor:moveToNext) (cursor:getString 0) #!null)
333 | (cursor:close)))
334 | (db:close)))))
335 |
--------------------------------------------------------------------------------
/LearningAndroid-chapter10/src/com/zeroxab/learningandroid/yamba/Yamba.scm:
--------------------------------------------------------------------------------
1 | (require 'android-defs)
2 | (require 'srfi-1)
3 | (require 'syntax-utils)
4 | (require )
5 |
6 | (define-namespace Log "class:android.util.Log")
7 |
8 | ;; from kawa/testsuite/classes1.scm
9 | (define-syntax (import-class form)
10 | (syntax-case form ()
11 | ((import-class fqcn)
12 | (let* ((cls :: java.lang.Class (eval (syntax fqcn)))
13 | (name (string->symbol (java.lang.Class:getSimpleName cls))))
14 | #`(define-alias #,(datum->syntax-object form name) fqcn)))))
15 |
16 | (define-alias Arrays java.util.Arrays)
17 | (define-alias Math java.lang.Math)
18 | (define-alias InterruptedException java.lang.InterruptedException)
19 | (define-alias Thread java.lang.Thread)
20 |
21 | (define-alias Application android.app.Application)
22 | (define-alias Activity android.app.Activity)
23 | (define-alias Service android.app.Service)
24 |
25 | (define-alias Bitmap android.graphics.Bitmap)
26 | (define-alias Canvas android.graphics.Canvas)
27 | (define-alias Color android.graphics.Color)
28 | (define-alias Drawable android.graphics.drawable.Drawable)
29 |
30 | (define-alias Context android.content.Context)
31 | (define-alias Intent android.content.Intent)
32 | (define-alias Resources android.content.res.Resources)
33 | (define-alias SharedPreferences android.content.SharedPreferences)
34 | (define-alias ContentValues android.content.ContentValues)
35 |
36 | (define-alias Handler android.os.Handler)
37 | (define-alias Bundle android.os.Bundle)
38 | (define-alias IBinder android.os.IBinder)
39 |
40 | (define-alias KeyEvent android.view.KeyEvent)
41 | (define-alias OnClickListener android.view.View$OnClickListener)
42 | (define-alias SurfaceHolder android.view.SurfaceHolder)
43 | (define-alias Menu android.view.Menu)
44 | (define-alias MenuItem android.view.MenuItem)
45 |
46 | (define-alias ListView android.widget.ListView)
47 | (define-alias SimpleCursorAdapter android.widget.SimpleCursorAdapter)
48 | (define-alias Toast android.widget.Toast)
49 | (define-alias ViewBinder android.widget.SimpleCursorAdapter$ViewBinder)
50 |
51 | (define-alias DateUtils android.text.format.DateUtils)
52 | (define-alias Editable android.text.Editable)
53 | (define-alias TextWatcher android.text.TextWatcher)
54 |
55 | (define-alias PreferenceActivity android.preference.PreferenceActivity)
56 | (define-alias PreferenceManager android.preference.PreferenceManager)
57 | (define-alias BaseColumns android.provider.BaseColumns)
58 |
59 | (define-alias Cursor android.database.Cursor)
60 | (define-alias SQLiteDatabase android.database.sqlite.SQLiteDatabase)
61 | (define-alias SQLiteOpenHelper android.database.sqlite.SQLiteOpenHelper)
62 |
63 | (define-alias FVector gnu.lists.FVector)
64 |
65 | (define-alias R com.zeroxab.learningandroid.yamba.R)
66 |
67 | (define-alias Twitter winterwell.jtwitter.Twitter)
68 |
69 | (define update-delay 10000) ;; 10 seconds
70 |
71 | (define-syntax async-task
72 | (lambda (x)
73 | ;; TODO should add in the ability to bind (this) at the callsite to
74 | ;; (this-parent) so that I don't need an ugly let
75 | (syntax-case x ()
76 | ((async-task paramsT progressT resultT . r)
77 | (letrec
78 | ((process
79 | (lambda (form)
80 | (syntax-case form (background cancel post pre progress publish-progress)
81 | (((background name stmt ...) . rest)
82 | ;; FIXME using object here instead of object1 seems to
83 | ;; change the object macro at the toplevel in the
84 | ;; interpreter, this looks like a bug
85 | (cons #`((doInBackground (object1 ::Object[])) (@java.lang.Override) ::Object
86 | (as resultT (let ((name (gnu.lists.FVector[paramsT] object1))) stmt ...)))
87 | (process #`rest)))
88 | (((cancel name stmt ...) . rest)
89 | (cons #`((onCancelled (object1 ::Object)) (@java.lang.Override) ::void
90 | (let ((name (as resultT object1))) stmt ...))
91 | (process #`rest)))
92 | (((post name stmt ...) . rest)
93 | (cons #`((onPostExecute (object1 ::Object)) (@java.lang.Override) ::void
94 | (let ((name (as resultT object1))) stmt ...))
95 | (process #`rest)))
96 | (((pre stmt ...) . rest)
97 | (cons #`(onPreExecute (@java.lang.Override) ::void stmt ...)
98 | (process #`rest)))
99 | (((progress stmt ...) . rest)
100 | (cons #`((onProgressUpdate (object1 ::Object[])) (@java.lang.Override) ::void
101 | (let ((name (gnu.lists.FVector[progressT] object1)))
102 | stmt ...))
103 | (process #`rest)))
104 | (((publish-progress stmt ...) . rest)
105 | (cons #`((publishProgress (object1 ::Object[])) (@java.lang.Override) ::void
106 | (let ((name (gnu.lists.FVector[progressT] object1)))
107 | stmt ...))
108 | (process #`rest)))
109 | (() '())))))
110 | #`(object (android.os.AsyncTask)
111 | #,(process #`r)))))))
112 |
113 | (define-syntax simple-thread
114 | (lambda (x)
115 | ;; TODO should add in the ability to bind (this) at the callsite to
116 | ;; (this-parent) so that I don't need an ugly let
117 | (syntax-case x ()
118 | ((simple-thread stmts ...)
119 | #`(as Thread (object (Thread) ((run) ::void
120 | stmts ...)))))))
121 |
122 | (define-simple-class PrefActivity (PreferenceActivity)
123 | ((onCreate (savedInstanceState ::Bundle))
124 | (invoke-special android.app.Activity (this) 'onCreate savedInstanceState)
125 | (addPreferencesFromResource R$xml:prefs)))
126 |
127 | (define-simple-class YambaApplication (Application)
128 | (twitter ::Twitter)
129 | (preferences ::SharedPreferences)
130 | (service-running? ::boolean)
131 | (status-data ::StatusData)
132 | ((onCreate)
133 | (invoke-special android.app.Application (this) 'onCreate)
134 | (set! preferences (PreferenceManager:getDefaultSharedPreferences (this)))
135 | (set! status-data (make StatusData (this)))
136 | (preferences:registerOnSharedPreferenceChangeListener
137 | (lambda ((preferences ::SharedPreferences) (key ::String))
138 | (set! twitter #!null))))
139 | ((onTerminate)
140 | (invoke-special android.app.Application (this) 'onTerminate))
141 | ((get-twitter) ::Twitter
142 | (synchronized
143 | (this)
144 | (when (equal? twitter #!null)
145 | (set! twitter (Twitter:new (preferences:getString "username" "student")
146 | (preferences:getString "password" "password")))
147 | (twitter:setAPIRootUrl (preferences:getString "apiRoot" "http://yamba.marakana.com/api"))))
148 | twitter)
149 | ((get-status-data) ::StatusData
150 | status-data)
151 | ((fetch-status-updates) ::int
152 | (Log:d "Yamba" "Fetching status")
153 | (let ((twitter (get-twitter)))
154 | (if (equal? twitter #!null)
155 | (begin (Log:e "Yamba" "Twitter not initialized!") 0)
156 | (try-catch
157 | (let* ((latest-status-at
158 | ::long
159 | ((get-status-data):get-latest-status-created-at-time))
160 | (nr
161 | (count
162 | (lambda (a) (equal? #t a))
163 | (->list
164 | (better-map
165 | (lambda (status ::)
166 | (let* ((values (make ContentValues))
167 | (created-at
168 | (java.lang.Long ((status:getCreatedAt):getTime))))
169 | (values:clear)
170 | (values:put StatusData:C_ID status:id)
171 | (values:put StatusData:C_CREATED_AT created-at)
172 | ;; (values:put StatusData:C_SOURCE status:source)
173 | (values:put StatusData:C_TEXT status:text)
174 | (values:put StatusData:C_USER (status:getUser):name)
175 | ((get-status-data):insert-or-ignore values)
176 | (< latest-status-at created-at)))
177 | (twitter:getFriendsTimeline))))))
178 | (Log:d "Yamba added status update" nr)
179 | nr)
180 | (e android.database.SQLException ;; java.lang.RuntimeException
181 | (Log:e "Yamba-UpdaterService" e)
182 | (Log:e "Yamba-UpdaterService" "Runtime!")
183 | 0))))))
184 |
185 | (define-simple-class StatusActivity (BaseActivity )
186 | (edit-text ::EditText)
187 | (update-button ::Button)
188 | (text-count ::TextView)
189 | ((onCreate (savedInstanceState ::Bundle))
190 | (invoke-special Activity (this) 'onCreate savedInstanceState)
191 | (invoke-special Activity (this) 'setContentView R$layout:status)
192 | (set! edit-text
193 | (invoke-special Activity (this) 'findViewById R$id:editText))
194 | (set! update-button
195 | (invoke-special Activity (this) 'findViewById R$id:buttonUpdate))
196 | (update-button:setOnClickListener
197 | (lambda ((view ::View))
198 | ;; FIXME this is nasty
199 | (let* ((activity-this (this)) (application (this):yamba))
200 | (*:execute
201 | (async-task
202 | String int String
203 | (background statuses
204 | (try-catch
205 | (begin
206 | ((application:get-twitter):setStatus (statuses 0))
207 | (statuses 0))
208 | (e winterwell.jtwitter.TwitterException
209 | (Log:e "Yamba-StatusActivity" "Failed to set twitter status!")
210 | (e:printStackTrace)
211 | "Ooops, failed to post status!")))
212 | (progress values #!null)
213 | (post result ((Toast:makeText activity-this (as result) Toast:LENGTH_LONG):show)))
214 | ((edit-text:getText):toString))
215 | (Log:d "Yamba-StatusActivity" "Clicked!"))))
216 | (set! text-count (invoke-special Activity (this) 'findViewById R$id:textCount))
217 | (text-count:setText (140:toString))
218 | (text-count:setTextColor Color:GREEN)
219 | (edit-text:addTextChangedListener (this)))
220 | ((afterTextChanged (status-text ::Editable))
221 | (let ((count (- 140 (status-text:length))))
222 | (text-count:setText (format #f "~a" count))
223 | (text-count:setTextColor (cond ((< count 0) Color:RED)
224 | ((< count 10) Color:YELLOW)
225 | (else Color:GREEN)))))
226 | ((beforeTextChanged sequence start count after) #f)
227 | ((onTextChanged sequence start before count) #f))
228 |
229 | (define-simple-class UpdaterService (Service)
230 | (updater ::Thread)
231 | (running? ::boolean)
232 | ((onBind (intent ::Intent)) #!null)
233 | ((onCreate) (invoke-special android.app.Service (this) 'onCreate)
234 | (Log:d "Yamba-UpdaterService" "Created")
235 | (set! updater
236 | (simple-thread
237 | (try-catch
238 | (let loop ()
239 | (when running?
240 | (Log:d "Yamba-UpdaterService" "Running")
241 | (when (> ((as YambaApplication (getApplication)):fetch-status-updates) 0)
242 | (Log:d "UpdateService" "New status"))
243 | (Thread:sleep update-delay)
244 | (loop)))
245 | (e java.lang.InterruptedException #f)))))
246 | ((onStartCommand (intent ::Intent) (flags ::int) (startId ::int))
247 | (invoke-special android.app.Service (this) 'onStartCommand intent flags startId)
248 | (unless running?
249 | (set! (as YambaApplication (getApplication)):service-running? #t)
250 | (set! running? #t)
251 | (*:start updater)
252 | (Log:d "Yamba-UpdaterService" "Started"))
253 | Service:START_STICKY)
254 | ((onDestroy)
255 | (set! (as YambaApplication (getApplication)):service-running? #f)
256 | (when running?
257 | (set! running? #f)
258 | (*:interrupt updater)
259 | (Log:d "Yamba-UpdaterService" "Destroyed"))))
260 |
261 | (define-simple-class dbHelper (SQLiteOpenHelper)
262 | ((*init* (context_ ::Context))
263 | (invoke-special android.database.sqlite.SQLiteOpenHelper
264 | (this) '*init* context_ StatusData:DATABASE
265 | #!null StatusData:VERSION))
266 | ((onCreate (db ::SQLiteDatabase))
267 | (let ((sql (string-append "create table "
268 | StatusData:TABLE " ("
269 | StatusData:C_ID " int primary key, "
270 | StatusData:C_CREATED_AT " int, "
271 | StatusData:C_USER " text, "
272 | StatusData:C_TEXT " text)")))
273 | (*:execSQL db sql)
274 | (Log:d "Yamba-DB" (string-append "onCreated sql: " sql))))
275 | ((onUpgrade (db ::SQLiteDatabase) (oldVersion ::int) (newVersion ::int))
276 | ;; instead of an alter table we just drop and recreate
277 | (*:execSQL db (string-append "drop table if exists " StatusData:TABLE))
278 | (Log:d "Yamba-DB" "onUpdated")
279 | (onCreate db)))
280 |
281 | (define-simple-class StatusData ()
282 | (DATABASE ::String allocation: 'static access: 'final init: "timeline.db")
283 | (VERSION ::int allocation: 'static access: 'final init: 1)
284 | (TABLE ::String allocation: 'static access: 'final init: "timeline")
285 | (C_ID ::String allocation: 'static access: 'final init: BaseColumns:_ID)
286 | (C_CREATED_AT ::String allocation: 'static access: 'final init: "created_at")
287 | (C_TEXT ::String allocation: 'static access: 'final init: "text")
288 | (C_USER ::String allocation: 'static access: 'final init: "user")
289 | (C_SOURCE ::String allocation: 'static access: 'final init: "source")
290 | ;; (GET_ALL_ORDER_BY ::String allocation: 'static access: 'final
291 | ;; init: C_CREATED_AT + " DESC")
292 | ;; (MAX_CREATED_AT_COLUMNS ::String allocation: 'static access: 'final
293 | ;; init: "max(" + C_CREATED_AT + ")")
294 | (db-helper ::dbHelper allocation: 'static access: '(private final))
295 | ((*init* (context_ ::Context))
296 | (set! db-helper (make dbHelper context_)))
297 | ((close) (db-helper:close))
298 | ((delete)
299 | (let ((db ::SQLiteDatabase (db-helper:getWritableDatabase)))
300 | (db:delete TABLE #!null [])
301 | (db:close)))
302 | ((insert-or-ignore (values ::ContentValues))
303 | (Log:d "StatusData insert of ignore" values)
304 | (let ((db ::SQLiteDatabase (db-helper:getWritableDatabase)))
305 | (try-finally
306 | (try-catch (db:insertWithOnConflict TABLE #!null values
307 | SQLiteDatabase:CONFLICT_IGNORE)
308 | (e android.database.SQLException
309 | (Log:e "Yamba-Updater SQL" e)
310 | #f))
311 | (db:close))))
312 | ((get-status-updates)
313 | ((db-helper:getReadableDatabase):query
314 | TABLE #!null #!null #!null #!null #!null
315 | (string-append C_CREATED_AT " DESC")))
316 | ((get-latest-status-created-at-time)
317 | (let ((db ::SQLiteDatabase (db-helper:getReadableDatabase)))
318 | (try-finally
319 | (let ((cursor ::Cursor
320 | (db:query TABLE
321 | (String[] (string-append "max(" C_CREATED_AT ")"))
322 | #!null #!null #!null #!null #!null)))
323 | (try-finally
324 | (if (cursor:moveToNext) (cursor:getLong 0) java.lang.Long:MIN_VALUE)
325 | (cursor:close)))
326 | (db:close))))
327 | ((get-status-text-by-id (id ::long))
328 | (let ((db ::SQLiteDatabase (db-helper:getReadableDatabase)))
329 | (try-finally
330 | (let ((cursor ::Cursor (db:query TABLE
331 | (String[] C_TEXT)
332 | (string-append C_ID "=" id)
333 | #!null #!null #!null #!null)))
334 | (try-finally
335 | (if (cursor:moveToNext) (cursor:getString 0) #!null)
336 | (cursor:close)))
337 | (db:close)))))
338 |
339 | (define (for-each-cursor! (f ::procedure) (cursor ::Cursor))
340 | (let loop () (when (cursor:moveToNext) (f cursor) (loop))))
341 |
342 | (define-simple-class TimelineActivity (BaseActivity)
343 | (cursor ::Cursor)
344 | (listTimeline ::ListView)
345 | (adapter ::SimpleCursorAdapter)
346 | ((onCreate (savedInstanceState ::Bundle))
347 | (invoke-special BaseActivity (this) 'onCreate savedInstanceState)
348 | (invoke-special Activity (this) 'setContentView R$layout:timeline)
349 | (when (equal? #!null ((this):yamba:preferences:getString "username" #!null))
350 | (invoke-special Activity (this) 'startActivity
351 | (make (this) PrefActivity))
352 | ((Toast:makeText (this) R$string:msgSetupPrefs Toast:LENGTH_LONG):show))
353 | (set! listTimeline (invoke-special Activity (this) 'findViewById R$id:listTimeline)))
354 | ((onDestroy)
355 | (invoke-special BaseActivity (this) 'onDestroy)
356 | (((this):yamba:get-status-data):close))
357 | ((onResume)
358 | (invoke-special BaseActivity (this) 'onResume)
359 | (set! cursor (((this):yamba:get-status-data):get-status-updates))
360 | (invoke-special Activity (this) 'startManagingCursor cursor)
361 | (set! adapter (make SimpleCursorAdapter
362 | (this) R$layout:row cursor
363 | (String[] StatusData:C_CREATED_AT
364 | StatusData:C_USER
365 | StatusData:C_TEXT)
366 | (int[] R$id:textCreatedAt R$id:textUser R$id:textText)))
367 | (adapter:setViewBinder
368 | (lambda ((view ::View) (cursor ::Cursor) (columnIndex ::int))
369 | (if (not (equal? (view:getId) R$id:textCreatedAt))
370 | #f
371 | (begin
372 | ((as TextView view):setText
373 | (DateUtils:getRelativeTimeSpanString
374 | (view:getContext) (cursor:getLong columnIndex)))
375 | #t))))
376 | (listTimeline:setAdapter adapter)))
377 |
378 | (define-class BaseActivity (Activity)
379 | interface: #f
380 | (yamba ::YambaApplication)
381 | ((onCreate (savedInstanceState ::Bundle))
382 | (invoke-special android.app.Activity (this) 'onCreate savedInstanceState)
383 | (set! yamba (as YambaApplication (getApplication))))
384 | ((onCreateOptionsMenu (menu ::Menu))
385 | ((getMenuInflater):inflate R$menu:menu menu)
386 | #t)
387 | ((onOptionsItemSelected (item ::MenuItem))
388 | (cond ((equal? (item:getItemId) R$id:itemPrefs)
389 | (startActivity (make (this) PrefActivity)))
390 | ((equal? (item:getItemId) R$id:itemToggleService)
391 | (if yamba:service-running?
392 | (stopService (make (this) UpdaterService))
393 | (startService (make (this) UpdaterService))))
394 | ((equal? (item:getItemId) R$id:itemPurge)
395 | ((yamba:get-status-data):delete)
396 | ((Toast:makeText (this) R$string:msgAllDataPurged Toast:LENGTH_LONG):show))
397 | ((equal? (item:getItemId) R$id:itemTimeline)
398 | (startActivity
399 | (((make (this) TimelineActivity):addFlags
400 | Intent:FLAG_ACTIVITY_SINGLE_TOP):addFlags
401 | Intent:FLAG_ACTIVITY_REORDER_TO_FRONT)))
402 | ((equal? (item:getItemId) R$id:itemStatus)
403 | (startActivity
404 | ((make (this) StatusActivity):addFlags
405 | Intent:FLAG_ACTIVITY_REORDER_TO_FRONT))))
406 | #t)
407 | ((onMenuOpened (featureId ::int) (menu ::Menu))
408 | (let ((toggleItem (menu:findItem R$id:itemToggleService)))
409 | (if yamba:service-running?
410 | (begin (toggleItem:setTitle R$string:titleServiceStop)
411 | (toggleItem:setIcon android.R$drawable:ic_media_pause))
412 | (begin (toggleItem:setTitle R$string:titleServiceStart)
413 | (toggleItem:setIcon android.R$drawable:ic_media_play)))
414 | #t))
415 | ((onDestroy)
416 | (invoke-special Activity (this) 'onDestroy))
417 | ((onResume)
418 | (invoke-special Activity (this) 'onResume)))
419 |
--------------------------------------------------------------------------------