Compare commits
No commits in common. "master" and "1.2" have entirely different histories.
10
.gitignore
vendored
|
@ -1,8 +1,14 @@
|
|||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
/versions.properties
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
|
|
1
.idea/.name
generated
|
@ -1 +0,0 @@
|
|||
Emaily
|
229
.idea/codeStyleSettings.xml
generated
|
@ -1,229 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectCodeStyleSettingsManager">
|
||||
<option name="PER_PROJECT_SETTINGS">
|
||||
<value>
|
||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
|
||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
|
||||
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
|
||||
<value />
|
||||
</option>
|
||||
<option name="IMPORT_LAYOUT_TABLE">
|
||||
<value>
|
||||
<package name="android" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="com" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="junit" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="net" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="org" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="java" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="javax" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="" withSubpackages="true" static="false" />
|
||||
<emptyLine />
|
||||
<package name="" withSubpackages="true" static="true" />
|
||||
<emptyLine />
|
||||
</value>
|
||||
</option>
|
||||
<option name="RIGHT_MARGIN" value="100" />
|
||||
<AndroidXmlCodeStyleSettings>
|
||||
<option name="USE_CUSTOM_SETTINGS" value="true" />
|
||||
</AndroidXmlCodeStyleSettings>
|
||||
<Objective-C-extensions>
|
||||
<option name="GENERATE_INSTANCE_VARIABLES_FOR_PROPERTIES" value="ASK" />
|
||||
<option name="RELEASE_STYLE" value="IVAR" />
|
||||
<option name="TYPE_QUALIFIERS_PLACEMENT" value="BEFORE" />
|
||||
<file>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
||||
</file>
|
||||
<class>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
||||
</class>
|
||||
<extensions>
|
||||
<pair source="cpp" header="h" />
|
||||
<pair source="c" header="h" />
|
||||
</extensions>
|
||||
</Objective-C-extensions>
|
||||
<XML>
|
||||
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
|
||||
</XML>
|
||||
<codeStyleSettings language="XML">
|
||||
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_NAMESPACE>Namespace:</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_NAMESPACE>Namespace:</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:name</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>name</NAME>
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_width</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_height</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:layout_.*</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:width</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:height</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</value>
|
||||
</option>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Erik's Code Style" />
|
||||
</component>
|
||||
</project>
|
116
.idea/codeStyles/Project.xml
generated
Normal file
|
@ -0,0 +1,116 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<codeStyleSettings language="XML">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
|
@ -0,0 +1,5 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Erik's Code Style" />
|
||||
</state>
|
||||
</component>
|
22
.idea/compiler.xml
generated
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<option name="DEFAULT_COMPILER" value="Javac" />
|
||||
<resourceExtensions />
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.java" />
|
||||
<entry name="!?*.form" />
|
||||
<entry name="!?*.class" />
|
||||
<entry name="!?*.groovy" />
|
||||
<entry name="!?*.scala" />
|
||||
<entry name="!?*.flex" />
|
||||
<entry name="!?*.kt" />
|
||||
<entry name="!?*.clj" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="false">
|
||||
<processorPath useClasspath="true" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
8
.idea/copyright/Erik_C__Thauvin.xml
generated
|
@ -1,8 +0,0 @@
|
|||
<component name="CopyrightManager">
|
||||
<copyright>
|
||||
<option name="allowReplaceKeyword" value="Erik C. Thauvin" />
|
||||
<option name="keyword" value="Copyright (c)" />
|
||||
<option name="myName" value="Erik C. Thauvin" />
|
||||
<option name="notice" value="@(#)&#36;file.fileName Copyright (c) 2011-&#36;today.year Erik C. Thauvin (http://erik.thauvin.net/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the authors nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." />
|
||||
</copyright>
|
||||
</component>
|
6
.idea/copyright/Erik_s_Copyright_Notice.xml
generated
Normal file
|
@ -0,0 +1,6 @@
|
|||
<component name="CopyrightManager">
|
||||
<copyright>
|
||||
<option name="notice" value="&#36;file.fileName Copyright (c) 2011-&#36;today.year, Erik C. Thauvin (erik@thauvin.net) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of this project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." />
|
||||
<option name="myName" value="Erik's Copyright Notice" />
|
||||
</copyright>
|
||||
</component>
|
10
.idea/copyright/profiles_settings.xml
generated
|
@ -1,11 +1,3 @@
|
|||
<component name="CopyrightManager">
|
||||
<settings default="Erik C. Thauvin">
|
||||
<module2copyright>
|
||||
<element module="Java Source" copyright="Erik C. Thauvin" />
|
||||
</module2copyright>
|
||||
<LanguageOptions name="JAVA">
|
||||
<option name="fileTypeOverride" value="3" />
|
||||
<option name="addBlankAfter" value="false" />
|
||||
</LanguageOptions>
|
||||
</settings>
|
||||
<settings default="Erik's Copyright Notice" />
|
||||
</component>
|
3
.idea/gradle.xml
generated
|
@ -1,8 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="PLATFORM" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="1.8" />
|
||||
|
@ -12,6 +14,7 @@
|
|||
<option value="$PROJECT_DIR$/app" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
|
|
41
.idea/inspectionProfiles/Project_Default.xml
generated
|
@ -1,41 +0,0 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<option name="myLocal" value="true" />
|
||||
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="TOP_LEVEL_CLASS_OPTIONS">
|
||||
<value>
|
||||
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||
<option name="REQUIRED_TAGS" value="" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="INNER_CLASS_OPTIONS">
|
||||
<value>
|
||||
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||
<option name="REQUIRED_TAGS" value="" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="METHOD_OPTIONS">
|
||||
<value>
|
||||
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="FIELD_OPTIONS">
|
||||
<value>
|
||||
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||
<option name="REQUIRED_TAGS" value="" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="IGNORE_DEPRECATED" value="false" />
|
||||
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
|
||||
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
|
||||
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
|
||||
<option name="myAdditionalJavadocTags" value="created" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false">
|
||||
<option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
|
||||
<option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
7
.idea/inspectionProfiles/profiles_settings.xml
generated
|
@ -1,7 +0,0 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="PROJECT_PROFILE" value="Project Default" />
|
||||
<option name="USE_PROJECT_PROFILE" value="true" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
30
.idea/jarRepositories.xml
generated
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="BintrayJCenter" />
|
||||
<option name="name" value="BintrayJCenter" />
|
||||
<option name="url" value="https://jcenter.bintray.com/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="Google" />
|
||||
<option name="name" value="Google" />
|
||||
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="MavenLocal" />
|
||||
<option name="name" value="MavenLocal" />
|
||||
<option name="url" value="file:$PROJECT_DIR$/../../maven/repository/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
39
.idea/misc.xml
generated
|
@ -1,43 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
</component>
|
||||
<component name="NullableNotNullManager">
|
||||
<option name="myDefaultNullable" value="org.jetbrains.annotations.Nullable" />
|
||||
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
||||
<option name="myNullables">
|
||||
<value>
|
||||
<list size="4">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
|
||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
|
||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
<option name="myNotNulls">
|
||||
<value>
|
||||
<list size="4">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
|
||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
|
||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
|
||||
<OptionsSetting value="true" id="Add" />
|
||||
<OptionsSetting value="true" id="Remove" />
|
||||
<OptionsSetting value="true" id="Checkout" />
|
||||
<OptionsSetting value="true" id="Update" />
|
||||
<OptionsSetting value="true" id="Status" />
|
||||
<OptionsSetting value="true" id="Edit" />
|
||||
<ConfirmationsSetting value="0" id="Add" />
|
||||
<ConfirmationsSetting value="0" id="Remove" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
|
4
.idea/modules.xml
generated
|
@ -2,8 +2,8 @@
|
|||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/Emaily.iml" filepath="$PROJECT_DIR$/Emaily.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/Emaily.iml" filepath="$PROJECT_DIR$/.idea/modules/Emaily.iml" group="Emaily" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/app/app.iml" filepath="$PROJECT_DIR$/.idea/modules/app/app.iml" group="Emaily/app" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
3
.idea/scopes/Java_Source.xml
generated
|
@ -1,3 +0,0 @@
|
|||
<component name="DependencyValidationManager">
|
||||
<scope name="Java Source" pattern="file[app]:src/main/java//*.java" />
|
||||
</component>
|
2
.idea/vcs.xml
generated
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
19
Emaily.iml
|
@ -1,19 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id="Emaily" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="java-gradle" name="Java-Gradle">
|
||||
<configuration>
|
||||
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
|
||||
<option name="BUILDABLE" value="false" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
27
LICENSE.TXT
Normal file
|
@ -0,0 +1,27 @@
|
|||
Copyright (c) 2011-2020, Erik C. Thauvin (erik@thauvin.net)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of this project nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
11
README.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Emaily for Android
|
||||
|
||||
> "_A simple app that makes things easier, and helps us to save some time._" — AndroidZoom
|
||||
|
||||
<p align="center">
|
||||
<a href="https://play.google.com/store/apps/details?id=net.thauvin.erik.android.emaily&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1"><img alt="Get it on Google Play" src="help/images/google-play-badge-sm.png"/></a>
|
||||
</p>
|
||||
|
||||
Emaily makes it easy to share shortened links from your phone.
|
||||
|
||||
No copy/paste required. Long URLs are squeezed into fewer characters using the [is.gd](https://is.gd/) or [bit.ly](https://bit.ly) services.
|
106
app/app.iml
|
@ -1,106 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="Emaily" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
<option name="GRADLE_PROJECT_PATH" value=":app" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
|
||||
<option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
|
||||
<afterSyncTasks>
|
||||
<task>generateDebugAndroidTestSources</task>
|
||||
<task>generateDebugSources</task>
|
||||
</afterSyncTasks>
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
|
||||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
|
||||
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" name="gson-2.1" level="project" />
|
||||
<orderEntry type="library" exported="" name="protobuf-java-2.2.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="google-http-client-1.7.0-beta" level="project" />
|
||||
<orderEntry type="library" exported="" name="google-api-client-1.7.0-beta" level="project" />
|
||||
<orderEntry type="library" exported="" name="bitlyj-2.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="google-http-client-android2-1.7.0-beta" level="project" />
|
||||
<orderEntry type="library" exported="" name="google-oauth-client-1.7.0-beta" level="project" />
|
||||
<orderEntry type="library" exported="" name="jsr305-1.3.9" level="project" />
|
||||
<orderEntry type="library" exported="" name="google-api-client-android2-1.7.0-beta" level="project" />
|
||||
<orderEntry type="library" exported="" name="jackson-core-asl-1.9.4" level="project" />
|
||||
<orderEntry type="library" exported="" name="google-api-urlshortener-v1-rev2-java-1.4.0-beta" level="project" />
|
||||
<orderEntry type="library" exported="" name="guava-11.0.1" level="project" />
|
||||
<orderEntry type="library" exported="" name="google-http-client-android3-1.7.0-beta" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-annotations-23.1.0" level="project" />
|
||||
</component>
|
||||
</module>
|
|
@ -1,41 +1,34 @@
|
|||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'versionPlugin'
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "23.0.1"
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion "29.0.3"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "net.thauvin.erik.android.emaily"
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 23
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 29
|
||||
versionCode 2
|
||||
versionName "1.1b10"
|
||||
versionName "1.2.0-beta"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
exclude 'META-INF/LICENSE'
|
||||
exclude 'META-INF/NOTICE'
|
||||
exclude 'META-INF/ASL2.0'
|
||||
}
|
||||
|
||||
versionPlugin {
|
||||
buildTypesMatcher = 'release'
|
||||
supportBuildNumber = false
|
||||
|
||||
fileNameFormat = '$projectName'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
//compile 'com.android.support:appcompat-v7:22.0.0'
|
||||
compile 'com.android.support:support-annotations:23.1.0'
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
|
||||
implementation 'net.thauvin.erik:bitly-shorten:0.9.3'
|
||||
implementation 'net.thauvin.erik:isgd-shorten:0.9.1'
|
||||
|
||||
testImplementation 'junit:junit:4.13'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||
}
|
||||
|
|
77
app/proguard-rules.pro
vendored
|
@ -1,82 +1,21 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in C:\Users\erik\AppData\Local\Android\android-sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
-optimizationpasses 5
|
||||
-dontusemixedcaseclassnames
|
||||
-dontskipnonpubliclibraryclasses
|
||||
-dontpreverify
|
||||
-verbose
|
||||
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||
|
||||
-keep public class * extends android.app.Activity
|
||||
-keep public class * extends android.app.Application
|
||||
-keep public class * extends android.app.Service
|
||||
-keep public class * extends android.content.BroadcastReceiver
|
||||
-keep public class * extends android.content.ContentProvider
|
||||
-keep public class * extends android.app.backup.BackupAgentHelper
|
||||
-keep public class * extends android.preference.Preference
|
||||
-keep public class com.android.vending.licensing.ILicensingService
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
public <init>(android.content.Context, android.util.AttributeSet);
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
public <init>(android.content.Context, android.util.AttributeSet, int);
|
||||
}
|
||||
|
||||
-keepclassmembers class * extends android.app.Activity {
|
||||
public void *(android.view.View);
|
||||
}
|
||||
|
||||
-keepclassmembers enum * {
|
||||
public static **[] values();
|
||||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
|
||||
-keep class * implements android.os.Parcelable {
|
||||
public static final android.os.Parcelable$Creator *;
|
||||
}
|
||||
|
||||
# Needed by google-http-client to keep generic types and @Key annotations accessed via reflection
|
||||
|
||||
-keepclassmembers class * {
|
||||
@com.google.api.client.util.Key <fields>;
|
||||
}
|
||||
|
||||
# Needed just to be safe in terms of keeping Google API service model classes
|
||||
|
||||
-keep class com.google.api.services.*.model.*
|
||||
|
||||
-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault
|
||||
|
||||
# Needed by Guava
|
||||
|
||||
-dontwarn sun.misc.Unsafe
|
||||
|
||||
# See https://groups.google.com/forum/#!topic/guava-discuss/YCZzeCiIVoI
|
||||
-dontwarn com.google.common.collect.MinMaxPriorityQueue
|
||||
|
||||
# Emaily
|
||||
-keep class com.google.api.client.googleapis.json.*
|
||||
-dontwarn org.apache.commons.codec.binary.StringUtils
|
||||
-dontwarn org.apache.commons.codec.binary.Base64
|
||||
-dontwarn com.google.api.client.http.apache.*
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package net.thauvin.erik.android.emaily;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
assertEquals("net.thauvin.erik.android.emaily", appContext.getPackageName());
|
||||
}
|
||||
}
|
|
@ -2,36 +2,38 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="net.thauvin.erik.android.emaily">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
|
||||
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/icon"
|
||||
android:fullBackupContent="@xml/mybackupscheme"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Emaily">
|
||||
<activity
|
||||
android:name="net.thauvin.erik.android.emaily.Emaily"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND"/>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="text/plain"/>
|
||||
<data android:mimeType="text/plain" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".EmailyPrefs"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -1,35 +1,33 @@
|
|||
/*
|
||||
* @(#)BitlyCredsDialog.java
|
||||
* BitlyCredsDialog.java
|
||||
*
|
||||
* Copyright (c) 2011-2015 Erik C. Thauvin (http://erik.thauvin.net/)
|
||||
* Copyright (c) 2011-2020, Erik C. Thauvin (erik@thauvin.net)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the authors nor the names of its contributors may be
|
||||
* Neither the name of this project nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.thauvin.erik.android.emaily;
|
||||
|
||||
|
@ -44,19 +42,16 @@ import android.util.AttributeSet;
|
|||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* The <code>BitlyCredsDialog</code> class implements a bit.ly credential dialog.
|
||||
*
|
||||
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
|
||||
* @created March 28, 2012
|
||||
* @since 1.0
|
||||
*/
|
||||
public class BitlyCredsDialog extends DialogPreference
|
||||
{
|
||||
private final Context context;
|
||||
private EditText username;
|
||||
private EditText apikey;
|
||||
|
||||
public BitlyCredsDialog(Context context, AttributeSet attrs)
|
||||
|
@ -67,17 +62,15 @@ public class BitlyCredsDialog extends DialogPreference
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void onBindDialogView(@NonNull View view)
|
||||
protected void onBindDialogView(View view)
|
||||
{
|
||||
super.onBindDialogView(view);
|
||||
|
||||
final SharedPreferences sharedPrefs = getSharedPreferences();
|
||||
username = (EditText) view.findViewById(R.id.bitly_username_edit);
|
||||
apikey = (EditText) view.findViewById(R.id.bitly_apikey_edit);
|
||||
final TextView textFld = (TextView) view.findViewById(R.id.bitly_text_fld);
|
||||
apikey = view.findViewById(R.id.bitly_accesstoken_edittext);
|
||||
final TextView textFld = view.findViewById(R.id.bitly_needtoken_textview);
|
||||
|
||||
username.setText(sharedPrefs.getString(context.getString(R.string.prefs_key_bitly_username), ""));
|
||||
apikey.setText(sharedPrefs.getString(context.getString(R.string.prefs_key_bitly_apikey), ""));
|
||||
apikey.setText(sharedPrefs.getString(context.getString(R.string.prefs_key_bitly_apitoken), ""));
|
||||
|
||||
textFld.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
|
@ -99,9 +92,9 @@ public class BitlyCredsDialog extends DialogPreference
|
|||
{
|
||||
final SharedPreferences sharedPrefs = getSharedPreferences();
|
||||
final Editor editor = sharedPrefs.edit();
|
||||
editor.putString(context.getString(R.string.prefs_key_bitly_username), username.getText().toString());
|
||||
editor.putString(context.getString(R.string.prefs_key_bitly_apikey), apikey.getText().toString());
|
||||
editor.commit();
|
||||
|
||||
editor.putString(context.getString(R.string.prefs_key_bitly_apitoken), apikey.getText().toString());
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,95 +1,64 @@
|
|||
/*
|
||||
* @(#)Emaily.java
|
||||
* Emaily.java
|
||||
*
|
||||
* Copyright (c) 2011-2015 Erik C. Thauvin (http://erik.thauvin.net/)
|
||||
* Copyright (c) 2011-2020, Erik C. Thauvin (erik@thauvin.net)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the authors nor the names of its contributors may be
|
||||
* Neither the name of this project nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.thauvin.erik.android.emaily;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.AccountManagerCallback;
|
||||
import android.accounts.AccountManagerFuture;
|
||||
import android.accounts.OperationCanceledException;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.ClipboardManager;
|
||||
import android.text.Html;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.api.client.googleapis.extensions.android2.auth.GoogleAccountManager;
|
||||
import com.google.api.client.googleapis.json.GoogleJsonError;
|
||||
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
|
||||
import com.google.api.client.http.HttpTransport;
|
||||
import com.google.api.client.http.javanet.NetHttpTransport;
|
||||
import com.google.api.client.http.json.JsonHttpRequest;
|
||||
import com.google.api.client.http.json.JsonHttpRequestInitializer;
|
||||
import com.google.api.client.json.JsonFactory;
|
||||
import com.google.api.client.json.jackson.JacksonFactory;
|
||||
import com.google.api.services.urlshortener.Urlshortener;
|
||||
import com.google.api.services.urlshortener.UrlshortenerRequest;
|
||||
import com.google.api.services.urlshortener.model.Url;
|
||||
import net.thauvin.erik.bitly.Bitlinks;
|
||||
import net.thauvin.erik.isgd.Isgd;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Date;
|
||||
|
||||
import static com.rosaloves.bitlyj.Bitly.as;
|
||||
import static com.rosaloves.bitlyj.Bitly.shorten;
|
||||
|
||||
/**
|
||||
* The <code>Emaily</code> class implements a URL shortener intent.
|
||||
*
|
||||
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
|
||||
* @created Oct 11, 2011
|
||||
* @since 1.0
|
||||
*/
|
||||
public class Emaily extends Activity
|
||||
{
|
||||
private static final String ACCOUNT_TYPE = "com.google";
|
||||
private static final String OAUTH_URL = "oauth2:https://www.googleapis.com/auth/urlshortener";
|
||||
|
||||
public class Emaily extends Activity {
|
||||
private String appName;
|
||||
private SharedPreferences sharedPrefs;
|
||||
|
||||
|
@ -97,218 +66,34 @@ public class Emaily extends Activity
|
|||
* Validates a string.
|
||||
*
|
||||
* @param s The string to validate.
|
||||
* @return returns <code>true</code> if the string is not empty or null, <code>false</code> otherwise.
|
||||
* @return returns <code>true</code> if the string is not empty or null, <code>false</code>
|
||||
* otherwise.
|
||||
*/
|
||||
public static boolean isValid(String s)
|
||||
{
|
||||
public static boolean isValid(String s) {
|
||||
return (s != null) && (!s.trim().isEmpty());
|
||||
}
|
||||
|
||||
@SuppressLint("CommitPrefEdits")
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
final Intent intent = getIntent();
|
||||
|
||||
appName = getString(R.string.app_name);
|
||||
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
if (Intent.ACTION_SEND.equals(intent.getAction()))
|
||||
{
|
||||
final boolean isGoogl = getBoolPref(R.string.prefs_key_googl_enabled, true);
|
||||
|
||||
if (isGoogl)
|
||||
{
|
||||
final String account = getPref(R.string.prefs_key_googl_account);
|
||||
|
||||
if (isValid(account))
|
||||
{
|
||||
startEmailyTask(intent, new Account(account, ACCOUNT_TYPE), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(this, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
|
||||
builder.setTitle(R.string.dialog_accounts_title);
|
||||
|
||||
final Account[] accounts = AccountManager.get(this).getAccountsByType(ACCOUNT_TYPE);
|
||||
final int size = accounts.length;
|
||||
if (size > 0)
|
||||
{
|
||||
if (size == 1)
|
||||
{
|
||||
startEmailyTask(intent, accounts[0], false);
|
||||
}
|
||||
else
|
||||
{
|
||||
final CharSequence[] names = new CharSequence[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
names[i] = accounts[i].name;
|
||||
}
|
||||
|
||||
builder.setSingleChoiceItems(names, 0, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
dialog.dismiss();
|
||||
|
||||
final Editor editor = sharedPrefs.edit();
|
||||
editor.putString(getString(R.string.prefs_key_googl_account), names[which].toString());
|
||||
editor.putLong(getString(R.string.prefs_key_googl_token_expiry), 0L);
|
||||
editor.commit();
|
||||
|
||||
startEmailyTask(intent, accounts[which], false);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
builder.create().show();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//noinspection ConstantConditions
|
||||
startEmailyTask(intent, isGoogl, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//noinspection ConstantConditions
|
||||
startEmailyTask(intent, isGoogl, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Emaily.this.finish();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the task.
|
||||
* Returns the value of the specified shared reference based on the specified string id.
|
||||
*
|
||||
* @param intent The original intent.
|
||||
* @param isGoogl The goo.gl flag.
|
||||
* @param isRetry The retry flag.
|
||||
* @param id The string id.
|
||||
* @param defaultValue The default value, used if the preference is empty.
|
||||
* @return The preference value.
|
||||
*/
|
||||
private void startEmailyTask(final Intent intent, final boolean isGoogl, final boolean isRetry)
|
||||
{
|
||||
final EmailyTask task;
|
||||
|
||||
if (isGoogl)
|
||||
{
|
||||
//noinspection ConstantConditions
|
||||
task = new EmailyTask(getPref(R.string.prefs_key_googl_account), getPref(R.string.prefs_key_googl_token), isGoogl,
|
||||
getBoolPref(R.string.prefs_key_html_chkbox), isRetry);
|
||||
}
|
||||
else
|
||||
{
|
||||
//noinspection ConstantConditions
|
||||
task = new EmailyTask(getPref(R.string.prefs_key_bitly_username), getPref(R.string.prefs_key_bitly_apikey), isGoogl,
|
||||
getBoolPref(R.string.prefs_key_html_chkbox), isRetry);
|
||||
}
|
||||
|
||||
task.execute(intent);
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private boolean getBoolPref(int id, boolean defaultValue) {
|
||||
return sharedPrefs.getBoolean(getString(id), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the task.
|
||||
*
|
||||
* @param intent The original intent.
|
||||
* @param account The account.
|
||||
* @param isRetry The retry flag.
|
||||
*/
|
||||
private void startEmailyTask(final Intent intent, final Account account, final boolean isRetry)
|
||||
{
|
||||
final GoogleAccountManager googleAccountManager = new GoogleAccountManager(Emaily.this);
|
||||
|
||||
final long expiry = sharedPrefs.getLong(getString(R.string.prefs_key_googl_token_expiry), 0L);
|
||||
final long now = System.currentTimeMillis();
|
||||
final long maxLife = (60L * 55L) * 1000L; // 55 minutes
|
||||
|
||||
Log.d(appName, "Token Expires: " + new Date(expiry));
|
||||
|
||||
if (expiry >= (now + maxLife) || expiry <= now)
|
||||
{
|
||||
final String token = getPref(R.string.prefs_key_googl_token);
|
||||
if (isValid(token))
|
||||
{
|
||||
googleAccountManager.manager.invalidateAuthToken(ACCOUNT_TYPE, token);
|
||||
|
||||
Log.d(appName, "Token Invalidated: " + token);
|
||||
}
|
||||
}
|
||||
|
||||
googleAccountManager.manager.getAuthToken(account, OAUTH_URL, null, Emaily.this, new AccountManagerCallback<Bundle>()
|
||||
{
|
||||
@SuppressLint("CommitPrefEdits")
|
||||
@Override
|
||||
public void run(AccountManagerFuture<Bundle> future)
|
||||
{
|
||||
try
|
||||
{
|
||||
final String token = future.getResult().getString(AccountManager.KEY_AUTHTOKEN);
|
||||
final Editor editor = sharedPrefs.edit();
|
||||
final long now = System.currentTimeMillis();
|
||||
|
||||
final long expires;
|
||||
if (expiry < now)
|
||||
{
|
||||
expires = now + maxLife;
|
||||
}
|
||||
else
|
||||
{
|
||||
expires = expiry;
|
||||
}
|
||||
|
||||
editor.putLong(getString(R.string.prefs_key_googl_token_expiry), expires);
|
||||
editor.putString(getString(R.string.prefs_key_googl_token), token);
|
||||
editor.commit();
|
||||
|
||||
Log.d(appName, account.toString());
|
||||
Log.d(appName, "Token: " + token);
|
||||
Log.d(appName, "Expires: " + new Date(expires));
|
||||
|
||||
startEmailyTask(intent, true, isRetry);
|
||||
|
||||
}
|
||||
catch (OperationCanceledException e)
|
||||
{
|
||||
Log.e(appName, "Auth token request has been canceled.", e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.e(appName, "Exception while requesting the auth token.", e);
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retries the task.
|
||||
*
|
||||
* @param intent The original intent.
|
||||
*/
|
||||
@SuppressLint("CommitPrefEdits")
|
||||
private void retry(final Intent intent)
|
||||
{
|
||||
sharedPrefs.edit().putLong(getString(R.string.prefs_key_googl_token_expiry), 0L).commit();
|
||||
|
||||
startEmailyTask(intent, new Account(getPref(R.string.prefs_key_googl_account), ACCOUNT_TYPE), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified shared reference based on the specified string id. The default value is an empty string.
|
||||
* Returns the value of the specified shared reference based on the specified string id. The
|
||||
* default value is an empty string.
|
||||
*
|
||||
* @param id The string id.
|
||||
* @return The preference value.
|
||||
*/
|
||||
private String getPref(int id)
|
||||
{
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private String getPref(int id) {
|
||||
return getPref(id, "");
|
||||
}
|
||||
|
||||
|
@ -319,385 +104,254 @@ public class Emaily extends Activity
|
|||
* @param defaultValue The default value, used if the preference is empty.
|
||||
* @return The preference value.
|
||||
*/
|
||||
private String getPref(int id, String defaultValue)
|
||||
{
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private String getPref(int id, String defaultValue) {
|
||||
return sharedPrefs.getString(getString(id), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified shared reference based on the specified string id. The default value is <code>false</code>.
|
||||
*
|
||||
* @param id The string id.
|
||||
* @return The preference value.
|
||||
*/
|
||||
private boolean getBoolPref(int id)
|
||||
{
|
||||
return getBoolPref(id, false);
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
final Intent intent = getIntent();
|
||||
|
||||
appName = getString(R.string.app_name);
|
||||
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
if (Intent.ACTION_SEND.equals(intent.getAction())) {
|
||||
final boolean isGd = getBoolPref(R.string.prefs_key_isgd_enabled, true);
|
||||
startEmailyTask(intent, isGd);
|
||||
} else {
|
||||
Emaily.this.finish();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the specified shared reference based on the specified string id.
|
||||
* Starts the task.
|
||||
*
|
||||
* @param id The string id.
|
||||
* @param defaultValue The default value, used if the preference is empty.
|
||||
* @return The preference value.
|
||||
* @param intent The original intent.
|
||||
* @param isGd The is.gd flag.
|
||||
*/
|
||||
private boolean getBoolPref(int id, boolean defaultValue)
|
||||
{
|
||||
return sharedPrefs.getBoolean(getString(id), defaultValue);
|
||||
private void startEmailyTask(final Intent intent, final boolean isGd) {
|
||||
final EmailyTask task;
|
||||
|
||||
if (isGd) {
|
||||
//noinspection ConstantConditions
|
||||
task = new EmailyTask("", isGd);
|
||||
} else {
|
||||
//noinspection ConstantConditions
|
||||
task = new EmailyTask(getPref(R.string.prefs_key_bitly_apitoken), isGd);
|
||||
}
|
||||
|
||||
task.execute(intent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The <code>EmailyResult</code> class.
|
||||
*/
|
||||
private static class EmailyResult {
|
||||
private final Intent intent;
|
||||
private int code = 0;
|
||||
private String message;
|
||||
|
||||
public EmailyResult(Intent intent) {
|
||||
this.intent = intent;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public Intent getIntent() {
|
||||
return intent;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
if (isValid(message)) {
|
||||
return message;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasError() {
|
||||
return code != 0;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>EmailyTask</code> class.
|
||||
*/
|
||||
private class EmailyTask extends AsyncTask<Intent, Void, EmailyResult>
|
||||
{
|
||||
private final ProgressDialog dialog = new ProgressDialog(Emaily.this, AlertDialog.THEME_DEVICE_DEFAULT_DARK);
|
||||
private final String username;
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
private class EmailyTask extends AsyncTask<Intent, Void, EmailyResult> {
|
||||
private final ProgressDialog dialog =
|
||||
new ProgressDialog(Emaily.this, AlertDialog.THEME_DEVICE_DEFAULT_DARK);
|
||||
private final boolean isGd;
|
||||
private final String keytoken;
|
||||
private final boolean isGoogl;
|
||||
private final boolean isHtml;
|
||||
private final boolean isRetry;
|
||||
|
||||
public EmailyTask(String username, String keytoken, boolean isGoogl, boolean isHtml, boolean isRetry)
|
||||
{
|
||||
this.username = username;
|
||||
public EmailyTask(String keytoken, boolean isGd) {
|
||||
this.keytoken = keytoken;
|
||||
this.isGoogl = isGoogl;
|
||||
this.isHtml = isHtml;
|
||||
this.isRetry = isRetry;
|
||||
this.isGd = isGd;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EmailyResult doInBackground(Intent... intent)
|
||||
{
|
||||
protected EmailyResult doInBackground(Intent... intent) {
|
||||
final EmailyResult result = new EmailyResult(intent[0]);
|
||||
|
||||
final Intent emailIntent = new Intent(Intent.ACTION_SEND);
|
||||
|
||||
if (isHtml)
|
||||
{
|
||||
emailIntent.setType("text/html");
|
||||
}
|
||||
else
|
||||
{
|
||||
emailIntent.setType("text/plain");
|
||||
}
|
||||
|
||||
|
||||
final Bundle extras = intent[0].getExtras();
|
||||
final String pageUrl;
|
||||
final String pageTitle;
|
||||
|
||||
emailIntent.setType("text/plain");
|
||||
|
||||
if (extras != null) {
|
||||
pageUrl = extras.getString(Intent.EXTRA_TEXT);
|
||||
pageTitle = extras.getString(Intent.EXTRA_SUBJECT);
|
||||
} else {
|
||||
pageTitle = null;
|
||||
pageUrl = null;
|
||||
}
|
||||
|
||||
final String pageUrl = extras.getString(Intent.EXTRA_TEXT);
|
||||
final String pageTitle = extras.getString(Intent.EXTRA_SUBJECT);
|
||||
final StringBuilder textBefore = new StringBuilder();
|
||||
|
||||
if (isValid(pageTitle))
|
||||
{
|
||||
if (isValid(pageTitle)) {
|
||||
emailIntent.putExtra(Intent.EXTRA_SUBJECT, pageTitle);
|
||||
}
|
||||
|
||||
final boolean hasCredentials = isValid(username) && isValid(keytoken);
|
||||
final StringBuilder shortUrl = new StringBuilder();
|
||||
|
||||
if (isValid(pageUrl))
|
||||
{
|
||||
final HttpTransport transport = new NetHttpTransport();
|
||||
final JsonFactory jsonFactory = new JacksonFactory();
|
||||
|
||||
String version = "";
|
||||
|
||||
try
|
||||
{
|
||||
version = '/' + getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
|
||||
}
|
||||
catch (NameNotFoundException ignore)
|
||||
{
|
||||
// Do nothing;
|
||||
}
|
||||
|
||||
final Url toInsert = new Url();
|
||||
|
||||
if (isValid(pageUrl)) {
|
||||
final String[] splits = pageUrl.split("\\s");
|
||||
|
||||
for (String item : splits)
|
||||
{
|
||||
try
|
||||
{
|
||||
for (String item : splits) {
|
||||
try {
|
||||
new URL(item.trim());
|
||||
|
||||
if (isGoogl || !hasCredentials)
|
||||
{
|
||||
Log.d(appName, "goo.gl -> " + item);
|
||||
|
||||
final Urlshortener shortener = Urlshortener.builder(transport, jsonFactory).setApplicationName(appName + version)
|
||||
.setJsonHttpRequestInitializer(new JsonHttpRequestInitializer()
|
||||
{
|
||||
@Override
|
||||
public void initialize(JsonHttpRequest request) throws IOException
|
||||
{
|
||||
UrlshortenerRequest shortnerRequest = (UrlshortenerRequest) request;
|
||||
|
||||
shortnerRequest.setKey(getString(R.string.secret_apikey));
|
||||
|
||||
if (isValid(keytoken))
|
||||
{
|
||||
shortnerRequest.setOauthToken(keytoken);
|
||||
|
||||
}
|
||||
shortnerRequest.put("client_id", getString(R.string.secret_client_id));
|
||||
shortnerRequest.put("client_secret", getString(R.string.secret_client_secret));
|
||||
}
|
||||
}).build();
|
||||
|
||||
toInsert.setLongUrl(item.trim());
|
||||
|
||||
try
|
||||
{
|
||||
final Url shortened = shortener.url().insert(toInsert).execute();
|
||||
|
||||
shortUrl.append(shortened.getId());
|
||||
}
|
||||
catch (GoogleJsonResponseException e)
|
||||
{
|
||||
try {
|
||||
if (isGd) {
|
||||
Log.d(appName, "is.gd --> " + item);
|
||||
shortUrl.append(Isgd.shorten(item));
|
||||
} else {
|
||||
if (Emaily.isValid(keytoken)) {
|
||||
final Bitlinks bitlinks = new Bitlinks(keytoken);
|
||||
shortUrl.append(bitlinks.shorten(item));
|
||||
if (!bitlinks.getLastCallResponse().isSuccessful()) {
|
||||
result.setCode(R.string.alert_error);
|
||||
|
||||
final GoogleJsonError err = e.getDetails();
|
||||
|
||||
result.setMessage(err.message);
|
||||
|
||||
if (err.code == 401)
|
||||
{
|
||||
if (!isRetry)
|
||||
{
|
||||
result.setRetry(true);
|
||||
result.setMessage(String.format(
|
||||
getString(R.string.alert_http_status_code),
|
||||
bitlinks.getLastCallResponse().getResultCode()));
|
||||
}
|
||||
} else {
|
||||
shortUrl.append(item);
|
||||
result.setCode(R.string.alert_notoken);
|
||||
}
|
||||
}
|
||||
|
||||
Log.e(appName, "Exception while shortening '" + item + "' via goo.gl.", e);
|
||||
}
|
||||
catch (UnknownHostException e)
|
||||
{
|
||||
result.setCode(R.string.alert_nohost);
|
||||
result.setMessage(e.getMessage());
|
||||
|
||||
Log.e(appName, "UnknownHostException while shortening '" + item + "' via goo.gl.", e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
result.setCode(R.string.alert_error);
|
||||
result.setMessage(e.getMessage());
|
||||
|
||||
Log.e(appName, "IOException while shortening '" + item + "' via goo.gl.", e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.d(appName, "bit.ly -> " + item);
|
||||
|
||||
try
|
||||
{
|
||||
shortUrl.append(as(username, keytoken).call(shorten(item.trim())).getShortUrl());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
} catch (Exception e) {
|
||||
final Throwable cause = e.getCause();
|
||||
|
||||
if (cause != null && cause instanceof UnknownHostException)
|
||||
{
|
||||
if (cause instanceof UnknownHostException) {
|
||||
result.setCode(R.string.alert_nohost);
|
||||
result.setMessage(cause.getMessage());
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
result.setCode(R.string.alert_error);
|
||||
if (cause != null) {
|
||||
result.setMessage(cause.getMessage());
|
||||
} else {
|
||||
result.setMessage(e.getMessage());
|
||||
}
|
||||
|
||||
Log.e(appName, "Exception while shortening '" + item + "' via bit.ly.", e);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
} catch (MalformedURLException mue) {
|
||||
Log.d(appName, "Attempted to process an invalid URL --> " + item, mue);
|
||||
|
||||
break;
|
||||
}
|
||||
catch (MalformedURLException mue)
|
||||
{
|
||||
Log.d(appName, "Attempted to process an invalid URL: " + item, mue);
|
||||
|
||||
if (textBefore.length() > 0)
|
||||
{
|
||||
if (textBefore.length() > 0) {
|
||||
textBefore.append(" ");
|
||||
}
|
||||
|
||||
textBefore.append(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.setCode(R.string.alert_nocreds);
|
||||
} else {
|
||||
result.setCode(R.string.alert_nourl);
|
||||
}
|
||||
|
||||
if (!result.isRetry())
|
||||
{
|
||||
if (shortUrl.length() > 0)
|
||||
{
|
||||
if (isHtml)
|
||||
{
|
||||
emailIntent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml("<a href=\"" + shortUrl + "\">" + shortUrl + "</a>"));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (shortUrl.length() > 0) {
|
||||
emailIntent.putExtra(Intent.EXTRA_TEXT, shortUrl.toString());
|
||||
}
|
||||
|
||||
if (!isValid(pageTitle) && textBefore.length() > 0)
|
||||
{
|
||||
if (!isValid(pageTitle) && textBefore.length() > 0) {
|
||||
emailIntent.putExtra(Intent.EXTRA_SUBJECT, textBefore.toString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (extras != null) {
|
||||
final CharSequence chars = extras.getCharSequence(Intent.EXTRA_TEXT);
|
||||
|
||||
if (chars.length() > 0)
|
||||
{
|
||||
if (chars != null && chars.length() > 0) {
|
||||
emailIntent.putExtra(Intent.EXTRA_TEXT, chars);
|
||||
}
|
||||
else if (isValid(pageUrl))
|
||||
{
|
||||
} else if (isValid(pageUrl)) {
|
||||
emailIntent.putExtra(Intent.EXTRA_TEXT, pageUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.d(appName, "EXTRA_TXT --> " + emailIntent.getStringExtra(Intent.EXTRA_TEXT));
|
||||
Log.d(appName, "EXTRA_SUBJECT --> " + emailIntent.getStringExtra(Intent.EXTRA_SUBJECT));
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
startActivity(emailIntent);
|
||||
}
|
||||
catch (android.content.ActivityNotFoundException ignore)
|
||||
{
|
||||
if (!result.hasError() && shortUrl.length() > 0)
|
||||
{
|
||||
} catch (android.content.ActivityNotFoundException ignore) {
|
||||
if (!result.hasError() && shortUrl.length() > 0) {
|
||||
@SuppressWarnings("deprecation")
|
||||
final ClipboardManager clip = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
final ClipboardManager clip =
|
||||
(ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
if (clip != null) {
|
||||
//noinspection deprecation
|
||||
clip.setText(shortUrl);
|
||||
|
||||
}
|
||||
result.setCode(R.string.alert_notfound_clip);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
} else {
|
||||
result.setCode(R.string.alert_notfound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(EmailyResult result)
|
||||
{
|
||||
if (this.dialog.isShowing())
|
||||
{
|
||||
protected void onPreExecute() {
|
||||
this.dialog.setMessage(getString(R.string.progress_msg));
|
||||
this.dialog.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(EmailyResult result) {
|
||||
if (this.dialog.isShowing()) {
|
||||
this.dialog.dismiss();
|
||||
}
|
||||
|
||||
if (result.isRetry())
|
||||
{
|
||||
Emaily.this.retry(result.getIntent());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (result.hasError())
|
||||
{
|
||||
Toast.makeText(
|
||||
getApplicationContext(),
|
||||
getString(result.getCode(), result.getMessage(), isGoogl ? getString(R.string.prefs_googl_title)
|
||||
: getString(R.string.prefs_bitly_title)), Toast.LENGTH_LONG).show();
|
||||
|
||||
if (result.hasError()) {
|
||||
final String msg = getString(result.getCode(),
|
||||
result.getMessage(),
|
||||
isGd ? getString(R.string.prefs_isgd_title)
|
||||
: getString(R.string.prefs_bitly_title));
|
||||
Log.d(appName, "Toast --> " + msg);
|
||||
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
Emaily.this.finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute()
|
||||
{
|
||||
if (isRetry)
|
||||
{
|
||||
this.dialog.setMessage(getString(R.string.progress_msg_retry));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.dialog.setMessage(getString(R.string.progress_msg));
|
||||
}
|
||||
|
||||
this.dialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The <code>EmailyResult</code> class.
|
||||
*/
|
||||
private class EmailyResult
|
||||
{
|
||||
private final Intent intent;
|
||||
private int code = 0;
|
||||
private String message;
|
||||
private boolean retry = false;
|
||||
|
||||
public EmailyResult(Intent intent)
|
||||
{
|
||||
this.intent = intent;
|
||||
}
|
||||
|
||||
public int getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code)
|
||||
{
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMessage()
|
||||
{
|
||||
if (isValid(message))
|
||||
{
|
||||
return message;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public void setMessage(String message)
|
||||
{
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public Intent getIntent()
|
||||
{
|
||||
return intent;
|
||||
}
|
||||
|
||||
public boolean hasError()
|
||||
{
|
||||
return code != 0;
|
||||
}
|
||||
|
||||
public boolean isRetry()
|
||||
{
|
||||
return retry;
|
||||
}
|
||||
|
||||
public void setRetry(boolean retry)
|
||||
{
|
||||
this.retry = retry;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,40 +1,36 @@
|
|||
/*
|
||||
* @(#)EmailyPrefs.java
|
||||
* EmailyPrefs.java
|
||||
*
|
||||
* Copyright (c) 2011-2015 Erik C. Thauvin (http://erik.thauvin.net/)
|
||||
* Copyright (c) 2011-2020, Erik C. Thauvin (erik@thauvin.net)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the authors nor the names of its contributors may be
|
||||
* Neither the name of this project nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.thauvin.erik.android.emaily;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.SharedPreferences.Editor;
|
||||
|
@ -43,128 +39,104 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
|||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.preference.SwitchPreference;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* The <code>EmailyPrefs</code> class implements a preferences screen.
|
||||
*
|
||||
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
|
||||
* @created Oct 11, 2011
|
||||
* @since 1.0
|
||||
*/
|
||||
@SuppressLint("ExportedPreferenceActivity")
|
||||
@SuppressWarnings("deprecation")
|
||||
public class EmailyPrefs extends PreferenceActivity implements OnSharedPreferenceChangeListener
|
||||
{
|
||||
public class EmailyPrefs extends PreferenceActivity implements OnSharedPreferenceChangeListener {
|
||||
private BitlyCredsDialog bitlyCreds;
|
||||
private SwitchPreference isgdBox;
|
||||
private SharedPreferences sharedPrefs;
|
||||
|
||||
private CheckBoxPreference googlBox;
|
||||
private BitlyCredsDialog bitlyCreds;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
addPreferencesFromResource(R.xml.prefs);
|
||||
|
||||
sharedPrefs = getPreferenceScreen().getSharedPreferences();
|
||||
|
||||
googlBox = (CheckBoxPreference) findPreference(getString(R.string.prefs_key_googl_chkbox));
|
||||
isgdBox = (SwitchPreference) findPreference(getString(R.string.prefs_key_isgd_chkbox));
|
||||
bitlyCreds = (BitlyCredsDialog) findPreference(getString(R.string.prefs_key_bitly_creds));
|
||||
|
||||
setSummary(bitlyCreds, getString(R.string.prefs_key_bitly_username), getString(R.string.prefs_bitly_creds_summary));
|
||||
setSummary(googlBox, getString(R.string.prefs_key_googl_account), "");
|
||||
setBitlyCredsSummary();
|
||||
|
||||
if (googlBox.isChecked())
|
||||
{
|
||||
if (isgdBox.isChecked()) {
|
||||
bitlyCreds.setEnabled(false);
|
||||
}
|
||||
|
||||
final Preference version = findPreference(getString(R.string.prefs_key_version));
|
||||
final PreferenceScreen feedback = (PreferenceScreen) findPreference(getString(R.string.prefs_key_feedback));
|
||||
try
|
||||
{
|
||||
final String vNumber = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
|
||||
final PreferenceScreen feedback =
|
||||
(PreferenceScreen) findPreference(getString(R.string.prefs_key_feedback));
|
||||
try {
|
||||
final String vNumber =
|
||||
getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
|
||||
|
||||
version.setTitle(getString(R.string.prefs_version_title) + ' ' + vNumber);
|
||||
|
||||
feedback.getIntent().setData(
|
||||
Uri.parse(getString(R.string.prefs_feedback_url)
|
||||
+ "?subject="
|
||||
+ getString(R.string.prefs_feedback_subject, getString(R.string.app_name), vNumber,
|
||||
getString(R.string.prefs_feedback_title).toLowerCase(Locale.getDefault()), Build.MANUFACTURER,
|
||||
Build.PRODUCT, Build.VERSION.RELEASE)));
|
||||
+ getString(R.string.prefs_feedback_subject,
|
||||
getString(R.string.app_name),
|
||||
vNumber,
|
||||
getString(R.string.prefs_feedback_title)
|
||||
.toLowerCase(Locale.getDefault()),
|
||||
Build.MANUFACTURER,
|
||||
Build.PRODUCT,
|
||||
Build.VERSION.RELEASE)));
|
||||
|
||||
}
|
||||
catch (NameNotFoundException ignore)
|
||||
{
|
||||
} catch (NameNotFoundException ignore) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
sharedPrefs.registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause()
|
||||
{
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
sharedPrefs.unregisterOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@SuppressLint("CommitPrefEdits")
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
|
||||
{
|
||||
if (key.equals(getString(R.string.prefs_key_bitly_username)))
|
||||
{
|
||||
setSummary(bitlyCreds, key, getString(R.string.prefs_bitly_creds_summary));
|
||||
}
|
||||
else if (key.equals(getString(R.string.prefs_key_googl_chkbox)))
|
||||
{
|
||||
final boolean checked = googlBox.isChecked();
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
if (key.equals(getString(R.string.prefs_key_bitly_apitoken))) {
|
||||
setBitlyCredsSummary();
|
||||
} else if (key.equals(getString(R.string.prefs_key_isgd_chkbox))) {
|
||||
final boolean checked = isgdBox.isChecked();
|
||||
|
||||
bitlyCreds.setEnabled(!checked);
|
||||
|
||||
final Editor editor = sharedPrefs.edit();
|
||||
editor.putBoolean(getString(R.string.prefs_key_googl_enabled), checked);
|
||||
|
||||
if (!checked)
|
||||
{
|
||||
editor.putString(getString(R.string.prefs_key_googl_account), "");
|
||||
editor.putLong(getString(R.string.prefs_key_googl_token_expiry), 0L);
|
||||
googlBox.setSummary("");
|
||||
}
|
||||
|
||||
editor.commit();
|
||||
editor.putBoolean(getString(R.string.prefs_key_isgd_enabled), checked);
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a preference's summary.
|
||||
*
|
||||
* @param editPref The preference.
|
||||
* @param key The preference key.
|
||||
* @param defValue The default value.
|
||||
* Sets the bit.ly credentials summary.
|
||||
*/
|
||||
private void setSummary(Preference editPref, String key, String defValue)
|
||||
{
|
||||
final String value = sharedPrefs.getString(key, defValue);
|
||||
|
||||
if (Emaily.isValid(value))
|
||||
{
|
||||
editPref.setSummary(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
editPref.setSummary(defValue);
|
||||
private void setBitlyCredsSummary() {
|
||||
if (Emaily.isValid(sharedPrefs.getString(getString(R.string.prefs_key_bitly_apitoken), ""))) {
|
||||
bitlyCreds.setSummary(getString(R.string.prefs_bitly_creds_summary_edit));
|
||||
} else {
|
||||
bitlyCreds.setSummary(getString(R.string.prefs_bitly_creds_summary_default));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,62 +5,30 @@
|
|||
android:orientation="vertical"
|
||||
android:paddingTop="20dip">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bit_username_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="20dip"
|
||||
android:layout_marginRight="20dip"
|
||||
android:gravity="start"
|
||||
android:text="@string/prefs_bitly_creds_username"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/bitly_username_edit"
|
||||
android:id="@+id/bitly_accesstoken_edittext"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="20dip"
|
||||
android:layout_marginRight="20dip"
|
||||
android:autofillHints=""
|
||||
android:gravity="fill_horizontal"
|
||||
android:inputType="text"
|
||||
android:key="@string/prefs_key_bitly_username"
|
||||
android:hint="@string/prefs_bitly_creds_apitoken_hint"
|
||||
android:inputType="textPassword"
|
||||
android:key="@string/prefs_key_bitly_apitoken"
|
||||
android:scrollHorizontally="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"/>
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bitly_apikey_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="20dip"
|
||||
android:layout_marginRight="20dip"
|
||||
android:gravity="start"
|
||||
android:text="@string/prefs_bitly_creds_apikey"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/bitly_apikey_edit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="20dip"
|
||||
android:layout_marginRight="20dip"
|
||||
android:gravity="fill_horizontal"
|
||||
android:inputType="text"
|
||||
android:key="@string/prefs_key_bitly_apikey"
|
||||
android:scrollHorizontally="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bitly_text_fld"
|
||||
android:id="@+id/bitly_needtoken_textview"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_marginBottom="20dip"
|
||||
android:layout_marginTop="20dip"
|
||||
android:gravity="center"
|
||||
android:text="@string/prefs_bitly_creds_noapi"
|
||||
android:textColor="#eda712"
|
||||
android:layout_marginBottom="20dip"
|
||||
android:clickable="true"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium">
|
||||
</TextView>
|
||||
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:text="@string/prefs_bitly_creds_needtoken"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textColor="#eda712" />
|
||||
</LinearLayout>
|
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 1.6 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 2.2 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 5.6 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 16 KiB |
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="Emaily" parent="@android:style/Theme.Holo" />
|
||||
|
||||
</resources>
|
|
@ -1,6 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="Emaily" parent="@android:style/Theme.Material" />
|
||||
|
||||
</resources>
|
4
app/src/main/res/values/ic_launcher_background.xml
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#DC0000</color>
|
||||
</resources>
|
|
@ -1,49 +1,44 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="alert_error">Sorry. An error was returned by %2$s while shortening the url: %1$s</string>
|
||||
<string name="alert_nocreds">Please provide your credentials to shorten urls.</string>
|
||||
<string name="alert_nohost">Sorry. Could not connect to %1$s.</string>
|
||||
<string name="alert_http_status_code">HTTP Status Code %d</string>
|
||||
<string name="alert_nohost">Sorry. Could not connect to %2$s: %1$s</string>
|
||||
<string name="alert_notfound">Sorry. No applications can perform this action.</string>
|
||||
<string name="alert_notfound_clip">Sorry. No applications can perform this action. The shortened url has been copied to the clipboard.</string>
|
||||
<string name="alert_notoken">Please specify a valid API access token.</string>
|
||||
<string name="alert_nourl">Could not find a URL to shorten.</string>
|
||||
<string name="app_name">Emaily</string>
|
||||
<string name="dialog_accounts_title">Select a Google account to shorten with</string>
|
||||
<string name="prefs_about_title">About</string>
|
||||
<string name="prefs_bitly_creds_apikey">API Key</string>
|
||||
<string name="prefs_author_url">https://m.thauvin.net/android/</string>
|
||||
<string name="prefs_bitly_creds_apitoken_hint">Enter access token…</string>
|
||||
<string name="prefs_bitly_creds_cancel">Cancel</string>
|
||||
<string name="prefs_bitly_creds_dialog_title">Bit.ly API Credentials</string>
|
||||
<string name="prefs_bitly_creds_noapi"><u>Need an API key?</u></string>
|
||||
<string name="prefs_bitly_creds_dialog_title">Bitly API Access Token</string>
|
||||
<string name="prefs_bitly_creds_needtoken"><u>Need an Access Token?</u></string>
|
||||
<string name="prefs_bitly_creds_ok">OK</string>
|
||||
<string name="prefs_bitly_creds_summary">Enter your credentials…</string>
|
||||
<string name="prefs_bitly_creds_title">API Credentials</string>
|
||||
<string name="prefs_bitly_creds_url">http://bitly.com/a/your_api_key/</string>
|
||||
<string name="prefs_bitly_creds_username">Username</string>
|
||||
<string name="prefs_bitly_creds_summary_default">Enter your access token…</string>
|
||||
<string name="prefs_bitly_creds_summary_edit">Click to edit or change…</string>
|
||||
<string name="prefs_bitly_creds_title">API Access Token</string>
|
||||
<string name="prefs_bitly_creds_url">https://bitly.is/accesstoken</string>
|
||||
<string name="prefs_bitly_title">bit.ly</string>
|
||||
<string name="prefs_copyright">© 2012–15 Erik C. Thauvin</string>
|
||||
<string name="prefs_copyright">© 2012–20 Erik C. Thauvin</string>
|
||||
<string name="prefs_feedback_subject">%1$s %2$s %3$s (%4$s %5$s, %6$s)</string>
|
||||
<string name="prefs_feedback_summary">Send email, please check Help first…</string>
|
||||
<string name="prefs_feedback_title">Feedback</string>
|
||||
<string name="prefs_feedback_url">mailto:erik@thauvin.net</string>
|
||||
<string name="prefs_googl_chkbox_title">Use as shorterner?</string>
|
||||
<string name="prefs_googl_title">goo.gl</string>
|
||||
<string name="prefs_help_summary">Learn how to use…</string>
|
||||
<string name="prefs_help_title">Help</string>
|
||||
<string name="prefs_help_url">http://m.thauvin.net/android/Emaily/help/</string>
|
||||
<string name="prefs_html_title">HTML</string>
|
||||
<string name="prefs_html_chkbox_title">Send email as HTML?</string>
|
||||
<string name="prefs_key_bitly_apikey">prefs_bitly_apikey</string>
|
||||
<string name="prefs_isgd_chkbox_title">Use as shorterner?</string>
|
||||
<string name="prefs_isgd_title">is.gd</string>
|
||||
<string name="prefs_key_bitly_apitoken">prefs_bitly_apitoken</string>
|
||||
<string name="prefs_key_bitly_creds">prefs_bitly_creds</string>
|
||||
<string name="prefs_key_bitly_username">prefs_bitly_username</string>
|
||||
<string name="prefs_key_feedback">prefs_feedback</string>
|
||||
<string name="prefs_key_googl_account">prefs_googl_account</string>
|
||||
<string name="prefs_key_googl_chkbox">prefs_googl_chkbox</string>
|
||||
<string name="prefs_key_googl_enabled">prefs_google_enabled</string>
|
||||
<string name="prefs_key_googl_token">prefs_googl_token</string>
|
||||
<string name="prefs_key_googl_token_expiry">prefs_gool_token_expiry</string>
|
||||
<string name="prefs_key_html_chkbox">prefs_html_chkbox</string>
|
||||
<string name="prefs_key_isgd_chkbox">prefs_isgd_chkbox</string>
|
||||
<string name="prefs_key_isgd_enabled">prefs_isgd_enabled</string>
|
||||
<string name="prefs_key_privacy">prefs_privacy</string>
|
||||
<string name="prefs_key_version">prefs_version</string>
|
||||
<string name="prefs_privacy_title">Privacy Policy</string>
|
||||
<string name="prefs_privacy_url">https://mobile.thauvin.net/apps-privacy.shtml</string>
|
||||
<string name="prefs_version_title">Version</string>
|
||||
<string name="progress_msg">Shortening url…</string>
|
||||
<string name="progress_msg_retry">Retrying…</string>
|
||||
|
||||
</resources>
|
6
app/src/main/res/xml/mybackupscheme.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<full-backup-content>
|
||||
<include
|
||||
domain="sharedpref"
|
||||
path="." />
|
||||
</full-backup-content>
|
|
@ -1,11 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<PreferenceCategory android:title="@string/prefs_googl_title">
|
||||
<CheckBoxPreference
|
||||
<PreferenceCategory android:title="@string/prefs_isgd_title">
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/prefs_key_googl_chkbox"
|
||||
android:title="@string/prefs_googl_chkbox_title"/>
|
||||
android:key="@string/prefs_key_isgd_chkbox"
|
||||
android:title="@string/prefs_isgd_chkbox_title" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/prefs_bitly_title">
|
||||
<net.thauvin.erik.android.emaily.BitlyCredsDialog
|
||||
|
@ -14,15 +14,8 @@
|
|||
android:key="@string/prefs_key_bitly_creds"
|
||||
android:negativeButtonText="@string/prefs_bitly_creds_cancel"
|
||||
android:positiveButtonText="@string/prefs_bitly_creds_ok"
|
||||
android:summary="@string/prefs_bitly_creds_summary"
|
||||
android:title="@string/prefs_bitly_creds_title">
|
||||
</net.thauvin.erik.android.emaily.BitlyCredsDialog>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/prefs_html_title">
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/prefs_key_html_chkbox"
|
||||
android:title="@string/prefs_html_chkbox_title"/>
|
||||
android:summary="@string/prefs_bitly_creds_summary_default"
|
||||
android:title="@string/prefs_bitly_creds_title"/>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/prefs_about_title">
|
||||
<PreferenceScreen
|
||||
|
@ -30,7 +23,7 @@
|
|||
android:title="@string/prefs_help_title">
|
||||
<intent
|
||||
android:action="android.intent.action.VIEW"
|
||||
android:data="@string/prefs_help_url"/>
|
||||
android:data="@string/prefs_help_url" />
|
||||
</PreferenceScreen>
|
||||
<PreferenceScreen
|
||||
android:key="@string/prefs_key_feedback"
|
||||
|
@ -38,14 +31,23 @@
|
|||
android:title="@string/prefs_feedback_title">
|
||||
<intent
|
||||
android:action="android.intent.action.VIEW"
|
||||
android:data="@string/prefs_feedback_url"/>
|
||||
android:data="@string/prefs_feedback_url" />
|
||||
</PreferenceScreen>
|
||||
<Preference
|
||||
android:enabled="false"
|
||||
<PreferenceScreen
|
||||
android:key="@string/prefs_key_privacy"
|
||||
android:title="@string/prefs_privacy_title">
|
||||
<intent
|
||||
android:action="android.intent.action.VIEW"
|
||||
android:data="@string/prefs_privacy_url" />
|
||||
</PreferenceScreen>
|
||||
<PreferenceScreen
|
||||
android:key="@string/prefs_key_version"
|
||||
android:singleLine="true"
|
||||
android:summary="@string/prefs_copyright"
|
||||
android:title="@string/prefs_version_title"/>
|
||||
android:title="@string/prefs_version_title">
|
||||
<intent
|
||||
android:action="android.intent.action.VIEW"
|
||||
android:data="@string/prefs_author_url" />
|
||||
</PreferenceScreen>
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
|
@ -0,0 +1,17 @@
|
|||
package net.thauvin.erik.android.emaily;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
11
build.gradle
|
@ -1,12 +1,11 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.1.0'
|
||||
classpath 'com.github.hamsterksu:android-appversion-gradle-plugin:1.2.+'
|
||||
classpath "com.android.tools.build:gradle:4.0.1"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
@ -15,6 +14,12 @@ buildscript {
|
|||
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
# Project-wide Gradle settings.
|
||||
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
org.gradle.jvmargs=-Xmx2048m
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||
# Android operating system, and which are packaged with your app"s APK
|
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
||||
# Automatically convert third-party libraries to use AndroidX
|
||||
android.enableJetifier=true
|
||||
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
|||
#Wed Apr 10 15:27:10 PDT 2013
|
||||
#Wed Jul 29 16:20:05 PDT 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
|
||||
|
|
110
gradlew
vendored
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
|
@ -6,47 +6,6 @@
|
|||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 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
|
||||
;;
|
||||
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"
|
||||
|
@ -61,9 +20,49 @@ while [ -h "$PRG" ] ; do
|
|||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
@ -90,7 +89,7 @@ location of your Java installation."
|
|||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
|
@ -114,6 +113,7 @@ fi
|
|||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
|
@ -154,11 +154,19 @@ if $cygwin ; then
|
|||
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=("$@")
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
|
14
gradlew.bat
vendored
|
@ -8,14 +8,14 @@
|
|||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem 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=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
|
@ -46,10 +46,9 @@ echo location of your Java installation.
|
|||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
@rem Get command-line arguments, handling Windows 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.
|
||||
|
@ -60,11 +59,6 @@ set _SKIP=2
|
|||
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
|
||||
|
|
BIN
help/images/1-sm.png
Normal file
After Width: | Height: | Size: 66 KiB |
BIN
help/images/2-sm.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
help/images/3-sm.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
help/images/4-sm.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
help/images/4a-sm.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
help/images/4b-sm.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
help/images/5-sm.png
Normal file
After Width: | Height: | Size: 51 KiB |
BIN
help/images/6-sm.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
help/images/bitly_creds-sm.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
help/images/bitly_selected-sm.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
help/images/google-play-badge-sm.png
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
help/images/isgd_disabled-sm.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
help/images/isgd_selected-sm.png
Normal file
After Width: | Height: | Size: 14 KiB |
12
help/includes/bootstrap.min.css
vendored
Normal file
84
help/index.shtml
Normal file
|
@ -0,0 +1,84 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>Emaily for Android</title>
|
||||
<link rel="stylesheet" href="includes/bootstrap.min.css">
|
||||
<style>
|
||||
html {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 1.5rem
|
||||
}
|
||||
|
||||
.sshot {
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 1.5rem
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="jumbotron">
|
||||
<h2 class="display-5">Emaily <small class="text-muted">for Android</small></h2>
|
||||
<blockquote class="blockquote">
|
||||
<p class="mb-0 font-italic">A simple app that makes things easier, and helps us to save some time.</p>
|
||||
<footer class="blockquote-footer"><cite title="Source Title">AndroidZoom</cite></footer>
|
||||
</blockquote>
|
||||
<p class="sshot">
|
||||
<a
|
||||
href="https://play.google.com/store/apps/details?id=net.thauvin.erik.android.emaily&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1"><img
|
||||
alt="Get it on Google Play" src="images/google-play-badge-sm.png" /></a>
|
||||
</p>
|
||||
<p class="lead">Emaily makes it easy to share shortened links from your phone.</p>
|
||||
<p class="lead">No copy/paste required. Long URLs are squeezed into fewer characters using <a
|
||||
href="https://is.gd">is.gd</a> or <a href="https://bit.ly">bit.ly</a>.</p>
|
||||
</div>
|
||||
<div class="card mb-3">
|
||||
<h3 class="card-header">How to use…</h3>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">When you find a web page you want to share, simply follow these steps:</h5>
|
||||
<p class="card-text">
|
||||
<ol>
|
||||
<li>Select the <strong class="text-warning">Options</strong> menu:</li>
|
||||
<img src="images/1-sm.png" class="img-thumbnail img-fluid sshot">
|
||||
<li>Select the <strong class="text-warning">Share…</strong> menu option:</li>
|
||||
<img src="images/2-sm.png" class="img-thumbnail img-fluid sshot">
|
||||
<li>Select <strong class="text-warning">Emaily</strong> from the <strong>Share</strong> sheet:</li>
|
||||
<img src="images/3-sm.png" class="img-thumbnail img-fluid sshot">
|
||||
<li>Select <strong class="text-warning">Gmail</strong><span class="text-muted"> (or whichever
|
||||
application you want to share with)</span>:</li>
|
||||
<img src="images/4-sm.png" class="img-thumbnail img-fluid sshot">
|
||||
<li>The <strong>shortened link</strong> is automatically inserted in a new email:</li>
|
||||
<img src="images/6-sm.png" class="img-thumbnail img-fluid sshot">
|
||||
</ol>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-3">
|
||||
<h3 class="card-header">Using Bitly…</h3>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">In order to use Bitly as for shortening links, you will need an <a
|
||||
href="https://bitly.is/accesstoken">API Access Token</a>.</h5>
|
||||
<p class="card-text">
|
||||
<p class="lead">To enable Bitly follow these steps:</p>
|
||||
<ol>
|
||||
<li>Disable <strong class="text-warning">is.gd</strong> by turning its switch off:</li>
|
||||
<img src="images/isgd_selected-sm.png" class="img-thumbnail img-fluid sshot">
|
||||
<li>Click on the Bitly <strong class="text-warning">API Access Token</strong> preference option:</li>
|
||||
<img src="images/bitly_selected-sm.png" class="img-thumbnail img-fluid sshot">
|
||||
<li>Enter your Bitly <strong class="text-warning">Access Token</strong> and click <strong
|
||||
class="text-warning">OK</strong>:</li>
|
||||
<img src="images/bitly_creds-sm.png" class="img-thumbnail img-fluid sshot">
|
||||
</ol>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!--#include file="includes/google-analytics-async.inc" -->
|
||||
</body>
|
||||
|
||||
</html>
|
BIN
screenshots/1.0/2.png
Normal file
After Width: | Height: | Size: 282 KiB |
BIN
screenshots/1.0/3.png
Normal file
After Width: | Height: | Size: 201 KiB |
BIN
screenshots/1.0/4.png
Normal file
After Width: | Height: | Size: 182 KiB |
BIN
screenshots/1.0/5.png
Normal file
After Width: | Height: | Size: 145 KiB |
BIN
screenshots/1.0/6.png
Normal file
After Width: | Height: | Size: 188 KiB |
BIN
screenshots/1.0/7.png
Normal file
After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 415 KiB After Width: | Height: | Size: 415 KiB |