fdroid/build (#6)
Fix gradle warns for F-Droid issues bot Reviewed-on: narayana/conversations-classic#6 Reviewed-by: kosyak <kosyak@narayana.im> Co-authored-by: Sergei Poljanski <me@asxp.io> Co-committed-by: Sergei Poljanski <me@asxp.io>
This commit is contained in:
parent
1301f43eba
commit
37aa0160b6
55
build.gradle
55
build.gradle
|
@ -18,20 +18,13 @@ apply plugin: 'org.jetbrains.kotlin.android'
|
|||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
maven { url='https://jitpack.io'}
|
||||
jcenter()
|
||||
}
|
||||
|
||||
configurations {
|
||||
playstoreImplementation
|
||||
freeImplementation
|
||||
conversationsFreeImplementation
|
||||
conversationsPlaystorImplementation
|
||||
conversationsPlaystoreImplementation
|
||||
quicksyPlaystoreImplementation
|
||||
quicksyPlaystoreImplementation
|
||||
quicksyFreeImplementation
|
||||
quicksyImplementation
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
@ -39,13 +32,6 @@ dependencies {
|
|||
|
||||
implementation 'androidx.viewpager:viewpager:1.0.0'
|
||||
|
||||
playstoreImplementation('com.google.firebase:firebase-messaging:23.3.1') {
|
||||
exclude group: 'com.google.firebase', module: 'firebase-core'
|
||||
exclude group: 'com.google.firebase', module: 'firebase-analytics'
|
||||
exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
|
||||
}
|
||||
conversationsPlaystoreImplementation("com.android.installreferrer:installreferrer:2.2")
|
||||
quicksyPlaystoreImplementation 'com.google.android.gms:play-services-auth-api-phone:18.0.1'
|
||||
implementation 'com.github.open-keychain.open-keychain:openpgp-api:v5.7.1'
|
||||
implementation("com.github.CanHub:Android-Image-Cropper:2.2.0")
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
|
@ -90,6 +76,7 @@ dependencies {
|
|||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation "androidx.recyclerview:recyclerview:1.2.1"
|
||||
implementation 'com.github.bumptech.glide:glide:4.15.1'
|
||||
// https://mvnrepository.com/artifact/info.androidhive/imagefilters
|
||||
implementation 'info.androidhive:imagefilters:1.0.7'
|
||||
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
|
||||
|
||||
|
@ -154,58 +141,22 @@ android {
|
|||
flavorDimensions += "distribution"
|
||||
|
||||
productFlavors {
|
||||
|
||||
quicksy {
|
||||
dimension "mode"
|
||||
applicationId = "im.quicksy.client"
|
||||
resValue "string", "applicationId", applicationId
|
||||
|
||||
def appName = "Quicksy"
|
||||
resValue "string", "app_name", appName
|
||||
buildConfigField "String", "APP_NAME", "\"$appName\""
|
||||
}
|
||||
|
||||
conversations {
|
||||
dimension "mode"
|
||||
}
|
||||
|
||||
playstore {
|
||||
dimension "distribution"
|
||||
versionNameSuffix "+playstore"
|
||||
}
|
||||
free {
|
||||
dimension "distribution"
|
||||
versionNameSuffix "+free"
|
||||
//versionNameSuffix "+free"
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
quicksyFree {
|
||||
java {
|
||||
srcDir 'src/quicksyFree/java'
|
||||
}
|
||||
}
|
||||
quicksyPlaystore {
|
||||
java {
|
||||
srcDir 'src/quicksyPlaystore/java'
|
||||
}
|
||||
res {
|
||||
srcDir 'src/quicksyPlaystore/res'
|
||||
}
|
||||
}
|
||||
conversationsFree {
|
||||
java {
|
||||
srcDir 'src/conversationsFree/java'
|
||||
}
|
||||
}
|
||||
conversationsPlaystore {
|
||||
java {
|
||||
srcDir 'src/conversationsPlaystore/java'
|
||||
}
|
||||
res {
|
||||
srcDir 'src/conversationsPlaystore/res'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,8 @@
|
|||
#Sun Dec 17 21:30:13 CET 2023
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=38f66cd6eef217b4c35855bb11ea4e9fbc53594ccccb5fb82dfd317ef8c2c5a3
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
320
gradlew
vendored
320
gradlew
vendored
|
@ -1,79 +1,126 @@
|
|||
#!/usr/bin/env bash
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
MAX_FD=maximum
|
||||
|
||||
warn ( ) {
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
} >&2
|
||||
|
||||
die ( ) {
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
@ -82,83 +129,120 @@ Please set the JAVA_HOME variable in your environment to match the
|
|||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
|
66
gradlew.bat
vendored
66
gradlew.bat
vendored
|
@ -1,4 +1,20 @@
|
|||
@if "%DEBUG%" == "" @echo off
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
|
@ -8,20 +24,24 @@
|
|||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
@ -35,7 +55,7 @@ goto fail
|
|||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
|
@ -45,44 +65,26 @@ echo location of your Java installation.
|
|||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
package eu.siacs.conversations.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.RemoteException;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.installreferrer.api.InstallReferrerClient;
|
||||
import com.android.installreferrer.api.InstallReferrerStateListener;
|
||||
import com.android.installreferrer.api.ReferrerDetails;
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.ui.WelcomeActivity;
|
||||
|
||||
public class InstallReferrerUtils implements InstallReferrerStateListener {
|
||||
|
||||
private static final String PROCESSED_INSTALL_REFERRER = "processed_install_referrer";
|
||||
|
||||
|
||||
private final WelcomeActivity welcomeActivity;
|
||||
private final InstallReferrerClient installReferrerClient;
|
||||
|
||||
|
||||
public InstallReferrerUtils(WelcomeActivity welcomeActivity) {
|
||||
this.welcomeActivity = welcomeActivity;
|
||||
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(welcomeActivity);
|
||||
if (preferences.getBoolean(PROCESSED_INSTALL_REFERRER, false)) {
|
||||
Log.d(Config.LOGTAG, "install referrer already processed");
|
||||
this.installReferrerClient = null;
|
||||
return;
|
||||
}
|
||||
this.installReferrerClient = InstallReferrerClient.newBuilder(welcomeActivity).build();
|
||||
try {
|
||||
this.installReferrerClient.startConnection(this);
|
||||
} catch (SecurityException e) {
|
||||
Log.e(Config.LOGTAG, "unable to start connection to InstallReferrerClient", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void markInstallReferrerExecuted(final Activity context) {
|
||||
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
preferences.edit().putBoolean(PROCESSED_INSTALL_REFERRER, true).apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstallReferrerSetupFinished(int responseCode) {
|
||||
if (responseCode == InstallReferrerClient.InstallReferrerResponse.OK) {
|
||||
try {
|
||||
final ReferrerDetails referrerDetails = installReferrerClient.getInstallReferrer();
|
||||
final String referrer = referrerDetails.getInstallReferrer();
|
||||
if (Strings.isNullOrEmpty(referrer)) {
|
||||
return;
|
||||
}
|
||||
welcomeActivity.onInstallReferrerDiscovered(Uri.parse(referrer));
|
||||
} catch (final RemoteException | IllegalArgumentException e) {
|
||||
Log.d(Config.LOGTAG, "unable to get install referrer", e);
|
||||
}
|
||||
} else {
|
||||
Log.d(Config.LOGTAG, "unable to setup install referrer client. code=" + responseCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInstallReferrerServiceDisconnected() {
|
||||
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application android:icon="@mipmap/new_launcher">
|
||||
|
||||
<meta-data
|
||||
android:name="firebase_analytics_collection_deactivated"
|
||||
android:value="true" />
|
||||
<meta-data
|
||||
android:name="google_analytics_adid_collection_enabled"
|
||||
android:value="false" />
|
||||
|
||||
<receiver
|
||||
android:name=".services.MaintenanceReceiver"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.CHANGE_CONFIGURATION">
|
||||
<intent-filter>
|
||||
<action android:name="eu.siacs.conversations.RENEW_INSTANCE_ID" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<service
|
||||
android:name=".services.PushMessageReceiver"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
</manifest>
|
|
@ -1,10 +0,0 @@
|
|||
package eu.siacs.conversations.services;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public class EmojiInitializationService {
|
||||
|
||||
public static void execute(final Context context) {
|
||||
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
package eu.siacs.conversations.services;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.firebase.installations.FirebaseInstallations;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.utils.Compatibility;
|
||||
|
||||
public class MaintenanceReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.d(Config.LOGTAG, "received intent in maintenance receiver");
|
||||
if ("eu.siacs.conversations.RENEW_INSTANCE_ID".equals(intent.getAction())) {
|
||||
renewInstanceToken(context);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void renewInstanceToken(final Context context) {
|
||||
FirebaseInstallations.getInstance().delete().addOnSuccessListener(unused -> {
|
||||
final Intent intent = new Intent(context, XmppConnectionService.class);
|
||||
intent.setAction(XmppConnectionService.ACTION_FCM_TOKEN_REFRESH);
|
||||
Compatibility.startService(context, intent);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
package eu.siacs.conversations.services;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
import com.google.android.gms.common.GoogleApiAvailabilityLight;
|
||||
import com.google.firebase.messaging.FirebaseMessaging;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.utils.PhoneHelper;
|
||||
import eu.siacs.conversations.xml.Element;
|
||||
import eu.siacs.conversations.xml.Namespace;
|
||||
import eu.siacs.conversations.xmpp.Jid;
|
||||
import eu.siacs.conversations.xmpp.XmppConnection;
|
||||
import eu.siacs.conversations.xmpp.forms.Data;
|
||||
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
|
||||
|
||||
public class PushManagementService {
|
||||
|
||||
protected final XmppConnectionService mXmppConnectionService;
|
||||
|
||||
PushManagementService(XmppConnectionService service) {
|
||||
this.mXmppConnectionService = service;
|
||||
}
|
||||
|
||||
private static Data findResponseData(IqPacket response) {
|
||||
final Element command = response.findChild("command", Namespace.COMMANDS);
|
||||
final Element x = command == null ? null : command.findChild("x", Namespace.DATA);
|
||||
return x == null ? null : Data.parse(x);
|
||||
}
|
||||
|
||||
private Jid getAppServer() {
|
||||
return Jid.of(mXmppConnectionService.getString(R.string.app_server));
|
||||
}
|
||||
|
||||
void registerPushTokenOnServer(final Account account) {
|
||||
Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": has push support");
|
||||
retrieveFcmInstanceToken(token -> {
|
||||
final String androidId = PhoneHelper.getAndroidId(mXmppConnectionService);
|
||||
final IqPacket packet = mXmppConnectionService.getIqGenerator().pushTokenToAppServer(getAppServer(), token, androidId);
|
||||
mXmppConnectionService.sendIqPacket(account, packet, (a, response) -> {
|
||||
final Data data = findResponseData(response);
|
||||
if (response.getType() == IqPacket.TYPE.RESULT && data != null) {
|
||||
try {
|
||||
String node = data.getValue("node");
|
||||
String secret = data.getValue("secret");
|
||||
Jid jid = Jid.of(data.getValue("jid"));
|
||||
if (node != null && secret != null) {
|
||||
enablePushOnServer(a, jid, node, secret);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": failed to enable push. invalid response from app server " + response);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void enablePushOnServer(final Account account, final Jid appServer, final String node, final String secret) {
|
||||
final IqPacket enable = mXmppConnectionService.getIqGenerator().enablePush(appServer, node, secret);
|
||||
mXmppConnectionService.sendIqPacket(account, enable, (a, p) -> {
|
||||
if (p.getType() == IqPacket.TYPE.RESULT) {
|
||||
Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": successfully enabled push on server");
|
||||
} else if (p.getType() == IqPacket.TYPE.ERROR) {
|
||||
Log.d(Config.LOGTAG, a.getJid().asBareJid() + ": enabling push on server failed");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void retrieveFcmInstanceToken(final OnGcmInstanceTokenRetrieved instanceTokenRetrieved) {
|
||||
final FirebaseMessaging firebaseMessaging;
|
||||
try {
|
||||
firebaseMessaging = FirebaseMessaging.getInstance();
|
||||
} catch (IllegalStateException e) {
|
||||
Log.d(Config.LOGTAG, "unable to get firebase instance token ", e);
|
||||
return;
|
||||
}
|
||||
firebaseMessaging.getToken().addOnCompleteListener(task -> {
|
||||
if (!task.isSuccessful()) {
|
||||
Log.d(Config.LOGTAG, "unable to get Firebase instance token", task.getException());
|
||||
}
|
||||
final String result;
|
||||
try {
|
||||
result = task.getResult();
|
||||
} catch (Exception e) {
|
||||
Log.d(Config.LOGTAG, "unable to get Firebase instance token due to bug in library ", e);
|
||||
return;
|
||||
}
|
||||
if (result != null) {
|
||||
instanceTokenRetrieved.onGcmInstanceTokenRetrieved(result);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
public boolean available(Account account) {
|
||||
final XmppConnection connection = account.getXmppConnection();
|
||||
return connection != null
|
||||
&& connection.getFeatures().sm()
|
||||
&& connection.getFeatures().push()
|
||||
&& playServicesAvailable();
|
||||
}
|
||||
|
||||
private boolean playServicesAvailable() {
|
||||
return GoogleApiAvailabilityLight.getInstance().isGooglePlayServicesAvailable(mXmppConnectionService) == ConnectionResult.SUCCESS;
|
||||
}
|
||||
|
||||
public boolean isStub() {
|
||||
return false;
|
||||
}
|
||||
|
||||
interface OnGcmInstanceTokenRetrieved {
|
||||
void onGcmInstanceTokenRetrieved(String token);
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
package eu.siacs.conversations.services;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.firebase.messaging.FirebaseMessagingService;
|
||||
import com.google.firebase.messaging.RemoteMessage;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.utils.Compatibility;
|
||||
|
||||
public class PushMessageReceiver extends FirebaseMessagingService {
|
||||
|
||||
@Override
|
||||
public void onMessageReceived(RemoteMessage message) {
|
||||
if (!EventReceiver.hasEnabledAccounts(this)) {
|
||||
Log.d(Config.LOGTAG,"PushMessageReceiver ignored message because no accounts are enabled");
|
||||
return;
|
||||
}
|
||||
final Map<String, String> data = message.getData();
|
||||
final Intent intent = new Intent(this, XmppConnectionService.class);
|
||||
intent.setAction(XmppConnectionService.ACTION_FCM_MESSAGE_RECEIVED);
|
||||
intent.putExtra("account", data.get("account"));
|
||||
Compatibility.startService(this, intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNewToken(String token) {
|
||||
if (!EventReceiver.hasEnabledAccounts(this)) {
|
||||
Log.d(Config.LOGTAG,"PushMessageReceiver ignored new token because no accounts are enabled");
|
||||
return;
|
||||
}
|
||||
final Intent intent = new Intent(this, XmppConnectionService.class);
|
||||
intent.setAction(XmppConnectionService.ACTION_FCM_TOKEN_REFRESH);
|
||||
Compatibility.startService(this, intent);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission
|
||||
android:name="android.permission.REQUEST_INSTALL_PACKAGES"
|
||||
tools:node="remove" />
|
||||
|
||||
<application
|
||||
android:icon="@mipmap/new_launcher"
|
||||
tools:ignore="GoogleAppIndexingWarning"
|
||||
tools:replace="android:icon">
|
||||
|
||||
<activity
|
||||
android:name=".ui.EnterPhoneNumberActivity"
|
||||
android:label="@string/verify_your_phone_number"
|
||||
android:launchMode="singleTop" />
|
||||
|
||||
<activity
|
||||
android:name=".ui.ChooseCountryActivity"
|
||||
android:label="@string/choose_a_country"
|
||||
android:launchMode="singleTop" />
|
||||
|
||||
<activity
|
||||
android:name=".ui.VerifyActivity"
|
||||
android:label="@string/verify_your_phone_number"
|
||||
android:launchMode="singleTask" />
|
||||
|
||||
<activity
|
||||
android:name=".ui.TosActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask" />
|
||||
|
||||
<activity
|
||||
android:name=".ui.EnterNameActivity"
|
||||
android:label="@string/enter_your_name"
|
||||
android:launchMode="singleTask" />
|
||||
|
||||
<receiver
|
||||
android:name=".services.SMSReceiver"
|
||||
android:exported="true"
|
||||
android:permission="com.google.android.gms.auth.api.phone.permission.SEND">
|
||||
<intent-filter>
|
||||
<action android:name="com.google.android.gms.auth.api.phone.SMS_RETRIEVED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
</application>
|
||||
</manifest>
|
|
@ -1,14 +0,0 @@
|
|||
Quicksy ist ein Ableger des beliebten Jabber/XMPP-Clients Conversations mit automatischer Kontaktsuche.
|
||||
|
||||
Du meldest dich mit deiner Telefonnummer an und Quicksy schlägt dir automatisch — basierend auf den Telefonnummern in deinem Adressbuch — mögliche Kontakte vor.
|
||||
|
||||
Unter der Oberfläche ist Quicksy ein vollwertiger Jabber-Client, mit dem du mit jedem Benutzer auf jedem öffentlich zugänglichen Server kommunizieren kannst. Ebenso können Benutzer auf Quicksy von außen kontaktiert werden, indem du einfach +telefonnummer@quicksy.im zu deiner Kontaktliste hinzufügst.
|
||||
|
||||
Abgesehen von der Kontaktsynchronisation ist die Benutzeroberfläche bewusst so nah wie möglich an Conversations gehalten. Dies ermöglicht es den Nutzern, von Quicksy zu Conversations zu wechseln, ohne die Funktionsweise der App neu erlernen zu müssen.
|
||||
|
||||
Die vorgeschlagenen Kontakte bestehen aus anderen Quicksy-Benutzern und normalen Jabber/XMPP-Benutzern, die ihre Jabber-ID in das Quicksy-Verzeichnis (https://quicksy.im/#get-listed) eingegeben haben.
|
||||
|
||||
HINWEIS: Für den Eintrag (https://quicksy.im/enter/) deiner Jabber-ID in das Quicksy-
|
||||
Verzeichnis einzutragen, ist eine einmalige Registrierungsgebühr erforderlich.
|
||||
|
||||
Lies die Datenschutzrichtlinien (https://quicksy.im/#privacy) für weitere Informationen.
|
|
@ -1 +0,0 @@
|
|||
Jabber/XMPP mit einfacher Anmeldung und leichter Erkennung
|
|
@ -1,14 +0,0 @@
|
|||
Quicksy is a spin off of the popular Jabber/XMPP client Conversations with automatic contact discovery.
|
||||
|
||||
You sign up with your phone number and Quicksy will automatically—based on the phone numbers in your address book—suggest possible contacts to you.
|
||||
|
||||
Under the hood Quicksy is a full-fledged Jabber client that lets you communicate with any user on any publicly federating server. Likewise users on Quicksy can be contacted from the outside simply by adding +phonenumber@quicksy.im to your contact list.
|
||||
|
||||
Aside from the contact sync the user interface is deliberately as close to Conversations as possible. This allows users to eventually migrate from Quicksy to Conversations without having to relearn how the app works.
|
||||
|
||||
Suggested contacts consists of other Quicksy users and regular Jabber/XMPP users who have entered their Jabber ID into the Quicksy Directory (https://quicksy.im/#get-listed).
|
||||
|
||||
NOTE: To enter (https://quicksy.im/enter/) your Jabber ID in the Quicksy
|
||||
Directory an one time registration fee is required.
|
||||
|
||||
Read the Privacy Policy (https://quicksy.im/#privacy) for more info.
|
Binary file not shown.
Before Width: | Height: | Size: 34 KiB |
|
@ -1 +0,0 @@
|
|||
Jabber/XMPP with Easy Entry and Easy Discovery
|
|
@ -1 +0,0 @@
|
|||
Jabber/XMPP kun Facila Eniro kaj Facila Malkovro
|
|
@ -1,14 +0,0 @@
|
|||
Quicksy é unha aplicación derivada do coñecido cliente Conversations para Jabber/XMPP co engadido do descubremento automático dos contactos.
|
||||
|
||||
Accedes co teu número de móbil e Quicksy suxerirá automáticamente posibles contactos en función dos números da libreta de enderezos.
|
||||
|
||||
Por debaixo estarás desfrutando dun completo cliente Jabber que che permite comunicarte con calquera usuaria doutros servidores federados. Do mesmo xeito, as persoas que usan Quicksy poden ser contactadas simplemente engadindo +numerodemobil@quicksy.im á túa lista de contactos.
|
||||
|
||||
Fóra da sincronización de contactos o resto da interface é o máis semellante posible a Conversations. Deste xeito as usuarias poden migrar de Quicksy a Conversations sen maiores dificultades e sen ter que volver a aprender a usar a aplicación.
|
||||
|
||||
Os contactos suxeridos proveñen doutras usuarias de Quicksy e usuarias regulares de Jabber/XMPP que engadiron o seu ID de Jabber ao Directorio Quicksy (https://quicksy.im/#get-listed).
|
||||
|
||||
NOTA: Para engadir (https://quicksy.im/enter/) o teu ID de Jabber ao Directorio
|
||||
Quicksy requírese facer unha pequena aportación só unha vez.
|
||||
|
||||
Le a Política de Privacidade (https://quicksy.im/#privacy) para ter máis información.
|
|
@ -1 +0,0 @@
|
|||
Jabber/XMPP Fácil de usar e Atopar os teus contactos
|
|
@ -1,14 +0,0 @@
|
|||
Quicksy è uno spin off del popolare client Jabber/XMPP Conversations con ricerca automatica dei contatti.
|
||||
|
||||
Ti registri con il numero di telefono e Quicksy ti proporrà automaticamente, in base ai numeri di telefono nella tua rubrica, i possibili contatti.
|
||||
|
||||
Sotto il cofano Quicksy è un vero e proprio client Jabber che ti consente di comunicare con qualsiasi utente su qualsiasi server federato pubblicamente. Allo stesso modo gli utenti su Quicksy possono essere contattati dall'esterno semplicemente aggiungendo +numeroditelefono@quicksy.im al tuo elenco di contatti.
|
||||
|
||||
A parte la sincronizzazione dei contatti, l'interfaccia utente è deliberatamente il più possibile simile a quella di Conversations. Ciò permette agli utenti eventualmente di migrare da Quicksy a Conversations senza il bisogno di imparare di nuovo come funziona l'app.
|
||||
|
||||
I contatti proposti consistono in altri utenti di Quicksy e utenti regolari di Jabber/XMPP che hanno inserito il loro ID Jabber nella Directory di Quicksy (https://quicksy.im/#get-listed).
|
||||
|
||||
NOTA: per inserire (https://quicksy.im/enter/) il tuo ID Jabber nella Directory
|
||||
di Quicksy è richiesto un pagamento una tantum per la registrazione.
|
||||
|
||||
Leggi l'informativa sulla privacy (https://quicksy.im/#privacy) per maggiori informazioni.
|
|
@ -1 +0,0 @@
|
|||
Jabber/XMPP con Easy Entry e Easy Discovery
|
|
@ -1,14 +0,0 @@
|
|||
Quicksy este un derivat al popularului client Jabber/XMPP Conversations cu descoperire automată a contactelor.
|
||||
|
||||
Vă înscrieți cu numărul de telefon, iar Quicksy vă va sugera automat, pe baza numerelor de telefon din agenda dvs., posibile contacte.
|
||||
|
||||
Sub capota Quicksy este un client Jabber complet care vă permite să comunicați cu orice utilizator de pe orice server public federat. De asemenea, utilizatorii de pe Quicksy pot fi contactați din exterior prin simpla adăugare a +numărdetelefon@quicksy.im la lista dvs. de contacte.
|
||||
|
||||
În afară de sincronizarea contactelor, interfața utilizatorului este în mod deliberat cât mai apropiată de Conversations. Acest lucru permite utilizatorilor să migreze în cele din urmă de la Quicksy la Conversations fără a fi nevoiți să învețe din nou cum funcționează aplicația.
|
||||
|
||||
Contactele sugerate constau din alți utilizatori Quicksy și utilizatori obișnuiți de Jabber/XMPP care și-au introdus adresa XMPP în Directorul Quicksy (https://quicksy.im/#get-listed).
|
||||
|
||||
NOTĂ: Pentru a vă introduce (https://quicksy.im/enter/) adresa XMPP în Directorul
|
||||
Quicksy este necesară o taxă de înregistrare unică.
|
||||
|
||||
Citiți Politica de confidențialitate (https://quicksy.im/#privacy) pentru mai multe informații.
|
|
@ -1 +0,0 @@
|
|||
Jabber/XMPP cu acces și descoperire facilă
|
|
@ -1,14 +0,0 @@
|
|||
Quicksy є відгалуженням Conversations — популярного клієнта Jabber/XMPP, з автоматичним пошуком контактів.
|
||||
|
||||
Реєструйтеся за допомогою свого номера телефону, і Quicksy автоматично — за номерами телефонів у Вашій адресній книзі — запропонує Вам можливі контакти.
|
||||
|
||||
Під капотом Quicksy — це повноцінний клієнт Jabber, який дозволяє вам спілкуватися з будь-яким користувачем на будь-якому загальнодоступному сервері. Так само з користувачами Quicksy можна зв’язатися ззовні, просто додавши +phonenumber@quicksy.im до свого списку контактів.
|
||||
|
||||
Окрім синхронізації контактів, інтерфейс користувача навмисно максимально наближений до Conversations. Це дозволяє користувачам зрештою перейти з Quicksy на Conversations без необхідності перевчатися.
|
||||
|
||||
Пропоновані контакти складаються з інших користувачів Quicksy і звичайних користувачів Jabber/XMPP, які ввели свій Jabber ID у каталог Quicksy (https://quicksy.im/#get-listed).
|
||||
|
||||
ПРИМІТКА. Щоб ввести (https://quicksy.im/enter/) свій Jabber ID у каталог Quicksy,
|
||||
потрібно сплатити одноразовий реєстраційний внесок.
|
||||
|
||||
Для отримання додаткової інформації прочитайте Політику конфіденційності (https://quicksy.im/#privacy).
|
|
@ -1 +0,0 @@
|
|||
Jabber/XMPP із простим входом і легким пошуком
|
|
@ -1,13 +0,0 @@
|
|||
Quicksy 是流行的 Jabber/XMPP 客户端 Conversations 的衍生品,具有自动发现联系人的功能。
|
||||
|
||||
您只需用电话号码注册,Quicksy 就会自动—根据您通讯录中的电话号码—向您推荐可能的联系人。
|
||||
|
||||
从本质上讲,Quicksy 是成熟的 Jabber 客户端,可让您与任何公共联合服务器上的任何用户进行交流。同样,只需将 +phonenumber@quicksy.im 添加到您的联系人列表中,即可从外部联系 Quicksy 上的用户。
|
||||
|
||||
除了联系人同步之外,用户界面尽可能地接近 Conversations。让用户最终可以从 Quicksy 迁移到 Conversations,而无需重新了解应用程序的工作方式。
|
||||
|
||||
建议的联系人包括其他 Quicksy 用户和在 Quicksy 目录(https://quicksy.im/#get-listed)中输入 Jabber ID 的普通 Jabber/XMPP 用户。
|
||||
|
||||
注意:要在 Quicksy 目录中输入(https://quicksy.im/enter/)您的 Jabber ID 需要缴纳一次性注册费。
|
||||
|
||||
请阅读隐私政策(https://quicksy.im/#privacy)了解更多信息。
|
|
@ -1 +0,0 @@
|
|||
Jabber/XMPP 轻松进入和易于发现
|
|
@ -1,90 +0,0 @@
|
|||
package eu.siacs.conversations.android;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.provider.ContactsContract;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.utils.PhoneNumberUtilWrapper;
|
||||
import io.michaelrocks.libphonenumber.android.NumberParseException;
|
||||
|
||||
public class PhoneNumberContact extends AbstractPhoneContact {
|
||||
|
||||
private final String phoneNumber;
|
||||
|
||||
public String getPhoneNumber() {
|
||||
return phoneNumber;
|
||||
}
|
||||
|
||||
private PhoneNumberContact(Context context, Cursor cursor) throws IllegalArgumentException {
|
||||
super(cursor);
|
||||
try {
|
||||
this.phoneNumber = PhoneNumberUtilWrapper.normalize(context, cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)));
|
||||
} catch (NumberParseException | NullPointerException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static ImmutableMap<String, PhoneNumberContact> load(Context context) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context.checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
|
||||
return ImmutableMap.of();
|
||||
}
|
||||
final String[] PROJECTION = new String[]{ContactsContract.Data._ID,
|
||||
ContactsContract.Data.DISPLAY_NAME,
|
||||
ContactsContract.Data.PHOTO_URI,
|
||||
ContactsContract.Data.LOOKUP_KEY,
|
||||
ContactsContract.CommonDataKinds.Phone.NUMBER};
|
||||
final HashMap<String, PhoneNumberContact> contacts = new HashMap<>();
|
||||
try (final Cursor cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, PROJECTION, null, null, null)){
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
try {
|
||||
final PhoneNumberContact contact = new PhoneNumberContact(context, cursor);
|
||||
final PhoneNumberContact preexisting = contacts.get(contact.getPhoneNumber());
|
||||
if (preexisting == null || preexisting.rating() < contact.rating()) {
|
||||
contacts.put(contact.getPhoneNumber(), contact);
|
||||
}
|
||||
} catch (final IllegalArgumentException ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
return ImmutableMap.of();
|
||||
}
|
||||
return ImmutableMap.copyOf(contacts);
|
||||
}
|
||||
|
||||
public static PhoneNumberContact findByUriOrNumber(Collection<PhoneNumberContact> haystack, Uri uri, String number) {
|
||||
final PhoneNumberContact byUri = findByUri(haystack, uri);
|
||||
return byUri != null || number == null ? byUri : findByNumber(haystack, number);
|
||||
}
|
||||
|
||||
public static PhoneNumberContact findByUri(Collection<PhoneNumberContact> haystack, Uri needle) {
|
||||
for (PhoneNumberContact contact : haystack) {
|
||||
if (needle.equals(contact.getLookupUri())) {
|
||||
return contact;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static PhoneNumberContact findByNumber(Collection<PhoneNumberContact> haystack, String needle) {
|
||||
for (PhoneNumberContact contact : haystack) {
|
||||
if (needle.equals(contact.getPhoneNumber())) {
|
||||
return contact;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
package eu.siacs.conversations.entities;
|
||||
|
||||
import android.util.Base64;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.hash.Hashing;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import eu.siacs.conversations.android.PhoneNumberContact;
|
||||
import eu.siacs.conversations.xml.Element;
|
||||
import eu.siacs.conversations.xmpp.Jid;
|
||||
|
||||
public class Entry implements Comparable<Entry> {
|
||||
private final List<Jid> jids;
|
||||
private final String number;
|
||||
|
||||
private Entry(String number, List<Jid> jids) {
|
||||
this.number = number;
|
||||
this.jids = jids;
|
||||
}
|
||||
|
||||
public static Entry of(Element element) {
|
||||
final String number = element.getAttribute("number");
|
||||
final List<Jid> jids = new ArrayList<>();
|
||||
for (Element jidElement : element.getChildren()) {
|
||||
String content = jidElement.getContent();
|
||||
if (content != null) {
|
||||
jids.add(Jid.of(content));
|
||||
}
|
||||
}
|
||||
return new Entry(number, jids);
|
||||
}
|
||||
|
||||
public static List<Entry> ofPhoneBook(Element phoneBook) {
|
||||
List<Entry> entries = new ArrayList<>();
|
||||
for (Element entry : phoneBook.getChildren()) {
|
||||
if ("entry".equals(entry.getName())) {
|
||||
entries.add(of(entry));
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
public static String statusQuo(final Collection<PhoneNumberContact> phoneNumberContacts, Collection<Contact> systemContacts) {
|
||||
return statusQuo(ofPhoneNumberContactsAndContacts(phoneNumberContacts, systemContacts));
|
||||
}
|
||||
|
||||
private static String statusQuo(final List<Entry> entries) {
|
||||
Collections.sort(entries);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for(Entry entry : entries) {
|
||||
if (builder.length() != 0) {
|
||||
builder.append('\u001d');
|
||||
}
|
||||
builder.append(entry.getNumber());
|
||||
List<Jid> jids = entry.getJids();
|
||||
Collections.sort(jids);
|
||||
for(Jid jid : jids) {
|
||||
builder.append('\u001e');
|
||||
builder.append(jid.asBareJid().toEscapedString());
|
||||
}
|
||||
}
|
||||
@SuppressWarnings("deprecation")
|
||||
final byte[] sha1 = Hashing.sha1().hashString(builder.toString(), Charsets.UTF_8).asBytes();
|
||||
return new String(Base64.encode(sha1, Base64.DEFAULT)).trim();
|
||||
}
|
||||
|
||||
private static List<Entry> ofPhoneNumberContactsAndContacts(final Collection<PhoneNumberContact> phoneNumberContacts, Collection<Contact> systemContacts) {
|
||||
final ArrayList<Entry> entries = new ArrayList<>();
|
||||
for(Contact contact : systemContacts) {
|
||||
final PhoneNumberContact phoneNumberContact = PhoneNumberContact.findByUri(phoneNumberContacts, contact.getSystemAccount());
|
||||
if (phoneNumberContact != null && phoneNumberContact.getPhoneNumber() != null) {
|
||||
Entry entry = findOrCreateByPhoneNumber(entries, phoneNumberContact.getPhoneNumber());
|
||||
entry.jids.add(contact.getJid().asBareJid());
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
private static Entry findOrCreateByPhoneNumber(final List<Entry> entries, String number) {
|
||||
for(Entry entry : entries) {
|
||||
if (entry.number.equals(number)) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
Entry entry = new Entry(number, new ArrayList<>());
|
||||
entries.add(entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
public List<Jid> getJids() {
|
||||
return jids;
|
||||
}
|
||||
|
||||
public String getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Entry o) {
|
||||
return number.compareTo(o.number);
|
||||
}
|
||||
}
|
|
@ -1,510 +0,0 @@
|
|||
package eu.siacs.conversations.services;
|
||||
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.ConnectException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
import javax.net.ssl.SSLPeerUnverifiedException;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.android.PhoneNumberContact;
|
||||
import eu.siacs.conversations.crypto.sasl.Plain;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.entities.Contact;
|
||||
import eu.siacs.conversations.entities.Entry;
|
||||
import eu.siacs.conversations.http.HttpConnectionManager;
|
||||
import eu.siacs.conversations.utils.AccountUtils;
|
||||
import eu.siacs.conversations.utils.CryptoHelper;
|
||||
import eu.siacs.conversations.utils.PhoneNumberUtilWrapper;
|
||||
import eu.siacs.conversations.utils.SerialSingleThreadExecutor;
|
||||
import eu.siacs.conversations.utils.SmsRetrieverWrapper;
|
||||
import eu.siacs.conversations.xml.Element;
|
||||
import eu.siacs.conversations.xml.Namespace;
|
||||
import eu.siacs.conversations.xmpp.Jid;
|
||||
import eu.siacs.conversations.xmpp.stanzas.IqPacket;
|
||||
import io.michaelrocks.libphonenumber.android.Phonenumber;
|
||||
|
||||
public class QuickConversationsService extends AbstractQuickConversationsService {
|
||||
|
||||
|
||||
public static final int API_ERROR_OTHER = -1;
|
||||
public static final int API_ERROR_UNKNOWN_HOST = -2;
|
||||
public static final int API_ERROR_CONNECT = -3;
|
||||
public static final int API_ERROR_SSL_HANDSHAKE = -4;
|
||||
public static final int API_ERROR_AIRPLANE_MODE = -5;
|
||||
public static final int API_ERROR_SSL_CERTIFICATE = -6;
|
||||
public static final int API_ERROR_SSL_GENERAL = -7;
|
||||
public static final int API_ERROR_TIMEOUT = -8;
|
||||
|
||||
private static final String API_DOMAIN = "api." + Config.QUICKSY_DOMAIN;
|
||||
|
||||
private static final String BASE_URL = "https://" + API_DOMAIN;
|
||||
|
||||
private static final String INSTALLATION_ID = "eu.siacs.conversations.installation-id";
|
||||
|
||||
private final Set<OnVerificationRequested> mOnVerificationRequested = Collections.newSetFromMap(new WeakHashMap<>());
|
||||
private final Set<OnVerification> mOnVerification = Collections.newSetFromMap(new WeakHashMap<>());
|
||||
|
||||
private final AtomicBoolean mVerificationInProgress = new AtomicBoolean(false);
|
||||
private final AtomicBoolean mVerificationRequestInProgress = new AtomicBoolean( |