Skip to content

Commit

Permalink
Merge pull request #104 from TheLastProject/updates
Browse files Browse the repository at this point in the history
Update dependencies + minor fixes
  • Loading branch information
TheLastProject authored Apr 30, 2024
2 parents 329fb23 + c79a7c5 commit 6aafd11
Show file tree
Hide file tree
Showing 19 changed files with 273 additions and 179 deletions.
45 changes: 17 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,45 +8,34 @@ Simply hold your phone to your ear to answer an incoming call. When the app dete

No ads, no unnecessary permissions and no unnecessary battery drain. Easy to enable and disable. Doesn't replace your incoming call screen, so you don't need to learn anything new.

[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Get it on F-Droid"
height="80">](https://f-droid.org/packages/me.hackerchick.raisetoanswer/)
[<img src="https://gitlab.com/IzzyOnDroid/repo/-/raw/master/assets/IzzyOnDroid.png"
alt="Get it on IzzyOnDroid"
height="80">](https://apt.izzysoft.de/fdroid/index/apk/me.hackerchick.raisetoanswer)
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png"
alt="Get it on Google Play"
height="80">](https://play.google.com/store/apps/details?id=me.hackerchick.raisetoanswer)

<a href="https://hosted.weblate.org/engage/raisetoanswer/">
<img src="https://hosted.weblate.org/widgets/raisetoanswer/-/open-graph.png" alt="Translation status" />
</a>

![Screenshot](fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png)

## How to build

First, clone the repository:
Building can either be done through Android Studio (not reproducible!) or the build.sh script in this repository (reproducible with OpenJDK 17). This script can also sign the build.

Build without signing:
```
git clone https://github.com/TheLastProject/RaiseToAnswer
./build.sh
```

Then, open Android Studio and hit build.

## Debugging
Sensors are complicated. If the app isn't working as you expect it to, please help me by giving some debug logging.

First, tap the menu in the top right.
![Debug screen 1](debug1.png)

Then, choose "Enable test mode".
![Debug screen 2](debug2.png)

Put the phone down in the resting position, and tap "Start Test". Then, answer or decline the phone as seems natural to you.
![Debug screen 3](debug3.png)

After having tried to answer or decline, press "End Test".
![Debug screen 4](debug4.png)
Build with signing:
```
KEYSTORE=/path/to/keystore KEYSTORE_ALIAS=raisetoanswer ./build.sh
```

If the issue appeared, press "Report Issue". This will open your email application and allow you to send debug logging to me.
![Debug screen 5](debug5.png)
### Translations

Please add any information you can think of to the email but don't remove any of the existing text.
<a href="https://hosted.weblate.org/engage/raisetoanswer/">
<img src="https://hosted.weblate.org/widgets/raisetoanswer/-/open-graph.png" alt="Translation status" />
</a>

## License

Expand Down
16 changes: 8 additions & 8 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'

android {
compileSdkVersion 30
buildToolsVersion '30.0.3'

defaultConfig {
applicationId "me.hackerchick.raisetoanswer"
minSdkVersion 26
compileSdk 34
//noinspection ExpiredTargetSdkVersion
targetSdkVersion 30
versionCode 32
versionName "3.6.5"
Expand All @@ -31,16 +30,17 @@ android {
kotlinOptions {
jvmTarget = "1.8"
}
namespace 'me.hackerchick.raisetoanswer'
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.core:core-ktx:1.13.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.3'
}
4 changes: 2 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="me.hackerchick.raisetoanswer">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<uses-feature android:name="android.hardware.sensor.accelerometer" />
<uses-feature android:name="android.hardware.sensor.proximity" />
Expand Down
11 changes: 11 additions & 0 deletions app/src/main/java/me/hackerchick/raisetoanswer/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class MainActivity : AppCompatActivity() {
permissions: Array<String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
PERMISSION_REQUEST_READ_PHONE_STATE -> {
if (!grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
Expand Down Expand Up @@ -142,6 +143,16 @@ class MainActivity : AppCompatActivity() {
}

private fun startApp() {
// Create notification channel
// We don't want to use it yet, but Android will ask the user for permission to show
// notifications the moment the channel gets created. This way we prevent Android from
// randomly asking about notification permission during the first incoming call
//
// Note: if it gets denied, that's fine, we only use this to tell users we're listening
// to Android sensors during incoming calls, as required by Android itself. We'd rather
// not bother users with such trivialities but alas.
Util.createIncomingCallForegroundServiceNotificationChannel(this)

ActivityCompat.requestPermissions(
this, arrayOf(
Manifest.permission.READ_PHONE_STATE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,12 @@ class RaiseToAnswerSensorEventListener : Service(), SensorEventListener {

val pendingIntent: PendingIntent =
Intent(this, MainActivity::class.java).let { notificationIntent ->
PendingIntent.getActivity(this, 0, notificationIntent, 0)
PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE)
}

val channel = NotificationChannel("incoming_call", getString(R.string.incoming_call_service), NotificationManager.IMPORTANCE_LOW)
val service = this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
service.createNotificationChannel(channel)
val channel = Util.createIncomingCallForegroundServiceNotificationChannel(this)

val notification: Notification = Notification.Builder(this, "incoming_call")
val notification: Notification = Notification.Builder(this, channel.id)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentText(getText(R.string.raise_to_answer_is_listening_to_sensor_data))
.setContentIntent(pendingIntent)
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/me/hackerchick/raisetoanswer/Util.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package me.hackerchick.raisetoanswer

import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
Expand Down Expand Up @@ -184,5 +186,13 @@ class Util {
serviceIntent = null
}
}

fun createIncomingCallForegroundServiceNotificationChannel(context: Context): NotificationChannel {
val channel = NotificationChannel("incoming_call", context.getString(R.string.incoming_call_service), NotificationManager.IMPORTANCE_LOW)
val service = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
service.createNotificationChannel(channel)

return channel
}
}
}
6 changes: 3 additions & 3 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<resources>
<string name="app_name">Raise To Answer</string>
<string name="permissions_needed">App can\'t work without these permission, sorry…</string>
<string name="permissions_needed">App can\'t work without this permission, sorry…</string>
<string name="raise_to_answer_header">Raise To Answer</string>
<string name="incoming_call_service">Incoming call service</string>
<string name="raise_to_answer_is_listening_to_sensor_data">Raise To Answer is listening to sensor data</string>
Expand All @@ -13,7 +13,7 @@
<string name="test_started">Test started</string>
<string name="enable_at_least_one_feature">Please enable at least one feature</string>
<string name="select_behaviour">Other settings</string>
<string name="behaviour_beep">Beep on incoming calls</string>
<string name="behaviour_beep">Beep when about to answer incoming call</string>
<string name="raise_enabled_key" translatable="false">raise_enabled_key</string>
<string name="flip_over_enabled_key" translatable="false">flip_over_enabled_key</string>
<string name="beep_behaviour_enabled_key" translatable="false">beep_behaviour_enabled_key</string>
Expand All @@ -26,7 +26,7 @@
<string name="missing_support_magnetometer">Your device lacks a magnetometer, declining or limiting answering to an up-right angle is not supported.</string>
<string name="missing_support_android_9">Your device is running a version of Android before 9, declining calls is not supported.</string>
<string name="debug_log_copied_to_clipboard">Debug log copied to clipboard</string>
<string name="behaviour_vibrate">Vibrate on incoming calls</string>
<string name="behaviour_vibrate">Vibrate when about to answer incoming call</string>
<string name="enable_test_mode">Enable test mode</string>
<string name="disable_test_mode">Disable test mode</string>
<string name="start_test">Start Test</string>
Expand Down
10 changes: 5 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext.kotlin_version = '1.4.32'
ext.kotlin_version = '1.9.22'
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.0.2'
classpath 'com.android.tools.build:gradle:8.3.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

// NOTE: Do not place your application dependencies here; they belong
Expand All @@ -18,10 +18,10 @@ buildscript {
allprojects {
repositories {
google()
jcenter()
mavenCentral()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}
}
49 changes: 49 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'

### build.sh
### Builds Raise to Answer reproducibly

if [ -z "${ANDROID_SDK_ROOT:-}" ]; then
echo "ANDROID_SDK_ROOT is not set, setting to $HOME/Android/Sdk";
export ANDROID_SDK_ROOT=$HOME/Android/Sdk
fi

if [ -z "${JAVA_HOME:-}" ]; then
echo "JAVA_HOME is not set, setting to Java 17"
if [ -f "/etc/debian_version" ]; then
echo "Debian-based distro, Java 17 is /usr/lib/jvm/java-17-openjdk-amd64"
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
else
echo "Not Debian-based, assuming Fedora and setting Java 17 as /usr/lib/jvm/java-17-openjdk"
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
fi
fi

echo "Starting build"
./gradlew clean assembleRelease

echo "Build finished (unsigned)"
echo "Your build is at app/build/outputs/apk/release/app-release-unsigned.apk"

if [ -z "${KEYSTORE:-}" ]; then
echo "KEYSTORE not set, skipping signing..."
else
if [ -z "${KEYSTORE_ALIAS:-}" ]; then
echo "KEYSTORE_ALIAS is not set, setting to raisetoanswer"
KEYSTORE_ALIAS=raisetoanswer
fi

apksigner_version="$(ls -1 "$HOME/Android/Sdk/build-tools/" | tail -n 1)"
cp app/build/outputs/apk/release/app-release-unsigned.apk app/build/outputs/apk/release/app-release.apk
"$HOME/Android/Sdk/build-tools/$apksigner_version/apksigner" sign -v --ks "$KEYSTORE" --ks-key-alias "$KEYSTORE_ALIAS" app/build/outputs/apk/release/app-release.apk

echo "Build finished (signed)"
echo "Your build is at app/build/outputs/apk/release/app-release.apk"
fi

pushd app/build/outputs/apk/release/
sha256sum -- *.apk > SHA256SUMS
popd

Binary file removed debug1.png
Binary file not shown.
Binary file removed debug2.png
Binary file not shown.
Binary file removed debug3.png
Binary file not shown.
Binary file removed debug4.png
Binary file not shown.
Binary file removed debug5.png
Binary file not shown.
3 changes: 3 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@ android.useAndroidX=true
android.enableJetifier=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
5 changes: 2 additions & 3 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#Mon Aug 02 18:50:31 CEST 2021
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit 6aafd11

Please sign in to comment.