diff --git a/.gitignore b/.gitignore index 603b140..2e2a23f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,8 @@ -*.iml -.gradle -/local.properties -/.idea/caches -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -/.idea/navEditor.xml -/.idea/assetWizardSettings.xml -.DS_Store -/build -/captures -.externalNativeBuild -.cxx +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +/versions.properties diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..249f321 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +Emaily \ No newline at end of file diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml new file mode 100644 index 0000000..9d4b0e0 --- /dev/null +++ b/.idea/codeStyleSettings.xml @@ -0,0 +1,229 @@ + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 681f41a..0000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - - -
- - - - xmlns:android - - ^$ - - - -
-
- - - - xmlns:.* - - ^$ - - - BY_NAME - -
-
- - - - .*:id - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:name - - http://schemas.android.com/apk/res/android - - - -
-
- - - - name - - ^$ - - - -
-
- - - - style - - ^$ - - - -
-
- - - - .* - - ^$ - - - BY_NAME - -
-
- - - - .* - - http://schemas.android.com/apk/res/android - - - ANDROID_ATTRIBUTE_ORDER - -
-
- - - - .* - - .* - - - BY_NAME - -
-
-
-
-
-
\ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index d91f848..0000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..9a8b7e5 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,22 @@ + + + + + \ No newline at end of file diff --git a/.idea/copyright/Erik_C__Thauvin.xml b/.idea/copyright/Erik_C__Thauvin.xml new file mode 100644 index 0000000..ed13fe2 --- /dev/null +++ b/.idea/copyright/Erik_C__Thauvin.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/.idea/copyright/Erik_s_Copyright_Notice.xml b/.idea/copyright/Erik_s_Copyright_Notice.xml deleted file mode 100644 index 81a0d90..0000000 --- a/.idea/copyright/Erik_s_Copyright_Notice.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml index 1419e40..4a1337b 100644 --- a/.idea/copyright/profiles_settings.xml +++ b/.idea/copyright/profiles_settings.xml @@ -1,3 +1,11 @@ - + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index ac6b0ae..8d2df47 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -1,10 +1,8 @@ - diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..7f5b7a4 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,41 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..3b31283 --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index ac86a16..0000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 37a7509..9c184d0 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,43 @@ - + + + + + + + + + + + + + + + + + + diff --git a/.idea/modules.xml b/.idea/modules.xml index 5145ba7..ba50301 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,8 +2,8 @@ - - + + \ No newline at end of file diff --git a/.idea/scopes/Java_Source.xml b/.idea/scopes/Java_Source.xml new file mode 100644 index 0000000..582ea35 --- /dev/null +++ b/.idea/scopes/Java_Source.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 35eb1dd..94a25f7 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/Emaily.iml b/Emaily.iml new file mode 100644 index 0000000..fe1b347 --- /dev/null +++ b/Emaily.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LICENSE.TXT b/LICENSE.TXT deleted file mode 100644 index 4b28e4e..0000000 --- a/LICENSE.TXT +++ /dev/null @@ -1,27 +0,0 @@ -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. diff --git a/README.md b/README.md deleted file mode 100644 index fe6ec58..0000000 --- a/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Emaily for Android - -> "_A simple app that makes things easier, and helps us to save some time._" — AndroidZoom - -

-Get it on Google Play -

- -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. diff --git a/app/app.iml b/app/app.iml new file mode 100644 index 0000000..35469ec --- /dev/null +++ b/app/app.iml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 1b78165..1d02d0b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,34 +1,41 @@ apply plugin: 'com.android.application' +apply plugin: 'versionPlugin' android { - compileSdkVersion 29 - buildToolsVersion "29.0.3" + compileSdkVersion 23 + buildToolsVersion "23.0.1" defaultConfig { applicationId "net.thauvin.erik.android.emaily" - minSdkVersion 16 - targetSdkVersion 29 + minSdkVersion 14 + targetSdkVersion 23 versionCode 2 - versionName "1.2.0-beta" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + versionName "1.1b10" } buildTypes { release { minifyEnabled true - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + proguardFiles getDefaultProguardFile('proguard-android.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 { - 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' + compile fileTree(dir: 'libs', include: ['*.jar']) + //compile 'com.android.support:appcompat-v7:22.0.0' + compile 'com.android.support:support-annotations:23.1.0' } diff --git a/app/libs/bitlyj-2.0.0.jar b/app/libs/bitlyj-2.0.0.jar new file mode 100644 index 0000000..7c6558f Binary files /dev/null and b/app/libs/bitlyj-2.0.0.jar differ diff --git a/app/libs/google-api-client-1.7.0-beta.jar b/app/libs/google-api-client-1.7.0-beta.jar new file mode 100644 index 0000000..ee8281b Binary files /dev/null and b/app/libs/google-api-client-1.7.0-beta.jar differ diff --git a/app/libs/google-api-client-android2-1.7.0-beta.jar b/app/libs/google-api-client-android2-1.7.0-beta.jar new file mode 100644 index 0000000..f4417ed Binary files /dev/null and b/app/libs/google-api-client-android2-1.7.0-beta.jar differ diff --git a/app/libs/google-api-urlshortener-v1-rev2-java-1.4.0-beta.jar b/app/libs/google-api-urlshortener-v1-rev2-java-1.4.0-beta.jar new file mode 100644 index 0000000..1257ade Binary files /dev/null and b/app/libs/google-api-urlshortener-v1-rev2-java-1.4.0-beta.jar differ diff --git a/app/libs/google-http-client-1.7.0-beta.jar b/app/libs/google-http-client-1.7.0-beta.jar new file mode 100644 index 0000000..591be28 Binary files /dev/null and b/app/libs/google-http-client-1.7.0-beta.jar differ diff --git a/app/libs/google-http-client-android2-1.7.0-beta.jar b/app/libs/google-http-client-android2-1.7.0-beta.jar new file mode 100644 index 0000000..68d95b7 Binary files /dev/null and b/app/libs/google-http-client-android2-1.7.0-beta.jar differ diff --git a/app/libs/google-http-client-android3-1.7.0-beta.jar b/app/libs/google-http-client-android3-1.7.0-beta.jar new file mode 100644 index 0000000..f8add82 Binary files /dev/null and b/app/libs/google-http-client-android3-1.7.0-beta.jar differ diff --git a/app/libs/google-oauth-client-1.7.0-beta.jar b/app/libs/google-oauth-client-1.7.0-beta.jar new file mode 100644 index 0000000..e431110 Binary files /dev/null and b/app/libs/google-oauth-client-1.7.0-beta.jar differ diff --git a/app/libs/gson-2.1.jar b/app/libs/gson-2.1.jar new file mode 100644 index 0000000..83c5c99 Binary files /dev/null and b/app/libs/gson-2.1.jar differ diff --git a/app/libs/guava-11.0.1.jar b/app/libs/guava-11.0.1.jar new file mode 100644 index 0000000..af4a383 Binary files /dev/null and b/app/libs/guava-11.0.1.jar differ diff --git a/app/libs/jackson-core-asl-1.9.4.jar b/app/libs/jackson-core-asl-1.9.4.jar new file mode 100644 index 0000000..8ad2d81 Binary files /dev/null and b/app/libs/jackson-core-asl-1.9.4.jar differ diff --git a/app/libs/jsr305-1.3.9.jar b/app/libs/jsr305-1.3.9.jar new file mode 100644 index 0000000..a9afc66 Binary files /dev/null and b/app/libs/jsr305-1.3.9.jar differ diff --git a/app/libs/protobuf-java-2.2.0.jar b/app/libs/protobuf-java-2.2.0.jar new file mode 100644 index 0000000..7a0ccde Binary files /dev/null and b/app/libs/protobuf-java-2.2.0.jar differ diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index f1b4245..8fa57da 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,21 +1,82 @@ # Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. +# 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. # # 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/* -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable +-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 -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembers class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembers class * { + public (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 ; +} + +# 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.* \ No newline at end of file diff --git a/app/src/androidTest/java/net/thauvin/erik/android/emaily/ExampleInstrumentedTest.java b/app/src/androidTest/java/net/thauvin/erik/android/emaily/ExampleInstrumentedTest.java deleted file mode 100644 index 6d1e030..0000000 --- a/app/src/androidTest/java/net/thauvin/erik/android/emaily/ExampleInstrumentedTest.java +++ /dev/null @@ -1,26 +0,0 @@ -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 Testing documentation - */ -@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()); - } -} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4da6182..3b71d09 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,39 +1,37 @@ + package="net.thauvin.erik.android.emaily"> - - - + + + + android:allowBackup="true" + android:icon="@mipmap/icon" + android:label="@string/app_name" + android:theme="@style/Emaily"> + android:name="net.thauvin.erik.android.emaily.Emaily" + android:label="@string/app_name" + android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"> - + - + - + + android:name=".EmailyPrefs" + android:label="@string/app_name"> - + - + - + + \ No newline at end of file diff --git a/app/src/main/java/net/thauvin/erik/android/emaily/BitlyCredsDialog.java b/app/src/main/java/net/thauvin/erik/android/emaily/BitlyCredsDialog.java index 34f50de..8f0f837 100644 --- a/app/src/main/java/net/thauvin/erik/android/emaily/BitlyCredsDialog.java +++ b/app/src/main/java/net/thauvin/erik/android/emaily/BitlyCredsDialog.java @@ -1,33 +1,35 @@ /* - * BitlyCredsDialog.java + * @(#)BitlyCredsDialog.java * - * Copyright (c) 2011-2020, Erik C. Thauvin (erik@thauvin.net) + * Copyright (c) 2011-2015 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: + * 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. + * 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. + * 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 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. + * 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. */ package net.thauvin.erik.android.emaily; @@ -42,16 +44,19 @@ import android.util.AttributeSet; import android.view.View; import android.widget.EditText; import android.widget.TextView; +import android.support.annotation.NonNull; /** * The BitlyCredsDialog class implements a bit.ly credential dialog. * * @author Erik C. Thauvin + * @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) @@ -62,15 +67,17 @@ public class BitlyCredsDialog extends DialogPreference } @Override - protected void onBindDialogView(View view) + protected void onBindDialogView(@NonNull View view) { super.onBindDialogView(view); final SharedPreferences sharedPrefs = getSharedPreferences(); - apikey = view.findViewById(R.id.bitly_accesstoken_edittext); - final TextView textFld = view.findViewById(R.id.bitly_needtoken_textview); + 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.setText(sharedPrefs.getString(context.getString(R.string.prefs_key_bitly_apitoken), "")); + username.setText(sharedPrefs.getString(context.getString(R.string.prefs_key_bitly_username), "")); + apikey.setText(sharedPrefs.getString(context.getString(R.string.prefs_key_bitly_apikey), "")); textFld.setOnClickListener(new View.OnClickListener() { @@ -92,9 +99,9 @@ public class BitlyCredsDialog extends DialogPreference { final SharedPreferences sharedPrefs = getSharedPreferences(); final Editor editor = sharedPrefs.edit(); - - editor.putString(context.getString(R.string.prefs_key_bitly_apitoken), apikey.getText().toString()); - editor.apply(); + 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(); } } diff --git a/app/src/main/java/net/thauvin/erik/android/emaily/Emaily.java b/app/src/main/java/net/thauvin/erik/android/emaily/Emaily.java index 877c755..727a865 100644 --- a/app/src/main/java/net/thauvin/erik/android/emaily/Emaily.java +++ b/app/src/main/java/net/thauvin/erik/android/emaily/Emaily.java @@ -1,64 +1,95 @@ /* - * Emaily.java + * @(#)Emaily.java * - * Copyright (c) 2011-2020, Erik C. Thauvin (erik@thauvin.net) + * Copyright (c) 2011-2015 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: + * 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. + * 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. + * 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 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. + * 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. */ 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 net.thauvin.erik.bitly.Bitlinks; -import net.thauvin.erik.isgd.Isgd; +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 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 Emaily class implements a URL shortener intent. * * @author Erik C. Thauvin + * @created Oct 11, 2011 * @since 1.0 */ -public class Emaily extends Activity { +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"; + private String appName; private SharedPreferences sharedPrefs; @@ -66,34 +97,218 @@ public class Emaily extends Activity { * Validates a string. * * @param s The string to validate. - * @return returns true if the string is not empty or null, false - * otherwise. + * @return returns true if the string is not empty or null, false otherwise. */ - public static boolean isValid(String s) { + public static boolean isValid(String s) + { return (s != null) && (!s.trim().isEmpty()); } - /** - * Returns the value of the specified shared reference based on the specified string id. - * - * @param id The string id. - * @param defaultValue The default value, used if the preference is empty. - * @return The preference value. - */ - @SuppressWarnings("SameParameterValue") - private boolean getBoolPref(int id, boolean defaultValue) { - return sharedPrefs.getBoolean(getString(id), defaultValue); + @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(); + } + } /** - * Returns the value of the specified shared reference based on the specified string id. The - * default value is an empty string. + * Starts the task. + * + * @param intent The original intent. + * @param isGoogl The goo.gl flag. + * @param isRetry The retry flag. + */ + 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); + } + + /** + * 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() + { + @SuppressLint("CommitPrefEdits") + @Override + public void run(AccountManagerFuture 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. * * @param id The string id. * @return The preference value. */ - @SuppressWarnings("SameParameterValue") - private String getPref(int id) { + private String getPref(int id) + { return getPref(id, ""); } @@ -104,226 +319,276 @@ public class Emaily extends Activity { * @param defaultValue The default value, used if the preference is empty. * @return The preference value. */ - @SuppressWarnings("SameParameterValue") - private String getPref(int id, String defaultValue) { + private String getPref(int id, String defaultValue) + { return sharedPrefs.getString(getString(id), defaultValue); } - @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(); - } - - } - /** - * Starts the task. + * Returns the value of the specified shared reference based on the specified string id. The default value is false. * - * @param intent The original intent. - * @param isGd The is.gd flag. + * @param id The string id. + * @return The preference value. */ - 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); + private boolean getBoolPref(int id) + { + return getBoolPref(id, false); } - /** - * The EmailyResult class. + * Returns the value of the specified shared reference based on the specified string id. + * + * @param id The string id. + * @param defaultValue The default value, used if the preference is empty. + * @return The preference value. */ - 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; - } + private boolean getBoolPref(int id, boolean defaultValue) + { + return sharedPrefs.getBoolean(getString(id), defaultValue); } /** * The EmailyTask class. */ - @SuppressLint("StaticFieldLeak") - private class EmailyTask extends AsyncTask { - private final ProgressDialog dialog = - new ProgressDialog(Emaily.this, AlertDialog.THEME_DEVICE_DEFAULT_DARK); - private final boolean isGd; + private class EmailyTask extends AsyncTask + { + private final ProgressDialog dialog = new ProgressDialog(Emaily.this, AlertDialog.THEME_DEVICE_DEFAULT_DARK); + private final String username; private final String keytoken; + private final boolean isGoogl; + private final boolean isHtml; + private final boolean isRetry; - public EmailyTask(String keytoken, boolean isGd) { + public EmailyTask(String username, String keytoken, boolean isGoogl, boolean isHtml, boolean isRetry) + { + this.username = username; this.keytoken = keytoken; - this.isGd = isGd; + this.isGoogl = isGoogl; + this.isHtml = isHtml; + this.isRetry = isRetry; } @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); - 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; + if (isHtml) + { + emailIntent.setType("text/html"); + } + else + { + emailIntent.setType("text/plain"); } + + final Bundle extras = intent[0].getExtras(); + + 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)) { + 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(); + final String[] splits = pageUrl.split("\\s"); - for (String item : splits) { - try { + for (String item : splits) + { + try + { new URL(item.trim()); - 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); - result.setMessage(String.format( - getString(R.string.alert_http_status_code), - bitlinks.getLastCallResponse().getResultCode())); - } - } else { - shortUrl.append(item); - result.setCode(R.string.alert_notoken); - } - } - } catch (Exception e) { - final Throwable cause = e.getCause(); + if (isGoogl || !hasCredentials) + { + Log.d(appName, "goo.gl -> " + item); - if (cause instanceof UnknownHostException) { - result.setCode(R.string.alert_nohost); - result.setMessage(cause.getMessage()); - } else { + 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) + { result.setCode(R.string.alert_error); - if (cause != null) { + + final GoogleJsonError err = e.getDetails(); + + result.setMessage(err.message); + + if (err.code == 401) + { + if (!isRetry) + { + result.setRetry(true); + } + } + + 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) + { + final Throwable cause = e.getCause(); + + if (cause != null && cause instanceof UnknownHostException) + { + result.setCode(R.string.alert_nohost); result.setMessage(cause.getMessage()); - } else { + } + else + { + result.setCode(R.string.alert_error); result.setMessage(e.getMessage()); } + + Log.e(appName, "Exception while shortening '" + item + "' via bit.ly.", e); } + + break; } break; - } catch (MalformedURLException mue) { - Log.d(appName, "Attempted to process an invalid URL --> " + item, mue); + } + 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_nourl); + } + else + { + result.setCode(R.string.alert_nocreds); } - if (shortUrl.length() > 0) { - emailIntent.putExtra(Intent.EXTRA_TEXT, shortUrl.toString()); + if (!result.isRetry()) + { + if (shortUrl.length() > 0) + { + if (isHtml) + { + emailIntent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml("" + shortUrl + "")); + } + else + { + emailIntent.putExtra(Intent.EXTRA_TEXT, shortUrl.toString()); + } - if (!isValid(pageTitle) && textBefore.length() > 0) { - emailIntent.putExtra(Intent.EXTRA_SUBJECT, textBefore.toString()); + if (!isValid(pageTitle) && textBefore.length() > 0) + { + emailIntent.putExtra(Intent.EXTRA_SUBJECT, textBefore.toString()); + } } - } else { - if (extras != null) { + else + { final CharSequence chars = extras.getCharSequence(Intent.EXTRA_TEXT); - if (chars != null && chars.length() > 0) { + if (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 { - startActivity(emailIntent); - } catch (android.content.ActivityNotFoundException ignore) { - if (!result.hasError() && shortUrl.length() > 0) { - @SuppressWarnings("deprecation") - final ClipboardManager clip = - (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); - if (clip != null) { - //noinspection deprecation + try + { + startActivity(emailIntent); + } + catch (android.content.ActivityNotFoundException ignore) + { + if (!result.hasError() && shortUrl.length() > 0) + { + @SuppressWarnings("deprecation") + final ClipboardManager clip = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); clip.setText(shortUrl); - } - result.setCode(R.string.alert_notfound_clip); - } else { - result.setCode(R.string.alert_notfound); + result.setCode(R.string.alert_notfound_clip); + } + else + { + result.setCode(R.string.alert_notfound); + } } } @@ -331,27 +596,108 @@ public class Emaily extends Activity { } @Override - protected void onPreExecute() { - this.dialog.setMessage(getString(R.string.progress_msg)); - this.dialog.show(); - } - - @Override - protected void onPostExecute(EmailyResult result) { - if (this.dialog.isShowing()) { + protected void onPostExecute(EmailyResult result) + { + if (this.dialog.isShowing()) + { this.dialog.dismiss(); } - 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(); + 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(); + + } + + 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)); } - Emaily.this.finish(); + this.dialog.show(); } } -} + + /** + * The EmailyResult 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; + } + } +} \ No newline at end of file diff --git a/app/src/main/java/net/thauvin/erik/android/emaily/EmailyPrefs.java b/app/src/main/java/net/thauvin/erik/android/emaily/EmailyPrefs.java index 9a5b94e..54b6a93 100644 --- a/app/src/main/java/net/thauvin/erik/android/emaily/EmailyPrefs.java +++ b/app/src/main/java/net/thauvin/erik/android/emaily/EmailyPrefs.java @@ -1,36 +1,40 @@ /* - * EmailyPrefs.java + * @(#)EmailyPrefs.java * - * Copyright (c) 2011-2020, Erik C. Thauvin (erik@thauvin.net) + * Copyright (c) 2011-2015 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: + * 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. + * 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. + * 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 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. + * 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. */ package net.thauvin.erik.android.emaily; +import java.util.Locale; + import android.annotation.SuppressLint; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; @@ -39,104 +43,128 @@ 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 EmailyPrefs class implements a preferences screen. - * + * * @author Erik C. Thauvin + * @created Oct 11, 2011 * @since 1.0 */ -@SuppressLint("ExportedPreferenceActivity") @SuppressWarnings("deprecation") -public class EmailyPrefs extends PreferenceActivity implements OnSharedPreferenceChangeListener { - private BitlyCredsDialog bitlyCreds; - private SwitchPreference isgdBox; - private SharedPreferences sharedPrefs; +public class EmailyPrefs extends PreferenceActivity implements OnSharedPreferenceChangeListener +{ + private SharedPreferences sharedPrefs; - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + private CheckBoxPreference googlBox; + private BitlyCredsDialog bitlyCreds; - addPreferencesFromResource(R.xml.prefs); + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); - sharedPrefs = getPreferenceScreen().getSharedPreferences(); + addPreferencesFromResource(R.xml.prefs); - isgdBox = (SwitchPreference) findPreference(getString(R.string.prefs_key_isgd_chkbox)); - bitlyCreds = (BitlyCredsDialog) findPreference(getString(R.string.prefs_key_bitly_creds)); + sharedPrefs = getPreferenceScreen().getSharedPreferences(); - setBitlyCredsSummary(); + googlBox = (CheckBoxPreference) findPreference(getString(R.string.prefs_key_googl_chkbox)); + bitlyCreds = (BitlyCredsDialog) findPreference(getString(R.string.prefs_key_bitly_creds)); - if (isgdBox.isChecked()) { - bitlyCreds.setEnabled(false); - } + 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), ""); - 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; + if (googlBox.isChecked()) + { + bitlyCreds.setEnabled(false); + } - version.setTitle(getString(R.string.prefs_version_title) + ' ' + vNumber); + 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; - 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))); + version.setTitle(getString(R.string.prefs_version_title) + ' ' + vNumber); - } catch (NameNotFoundException ignore) { - // Do nothing. - } - } + 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))); - @Override - protected void onResume() { - super.onResume(); - sharedPrefs.registerOnSharedPreferenceChangeListener(this); - } + } + catch (NameNotFoundException ignore) + { + // Do nothing. + } + } - @Override - protected void onPause() { - super.onPause(); - sharedPrefs.unregisterOnSharedPreferenceChangeListener(this); - } + @Override + protected void onResume() + { + super.onResume(); + sharedPrefs.registerOnSharedPreferenceChangeListener(this); + } - @Override - 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(); + @Override + protected void onPause() + { + super.onPause(); + sharedPrefs.unregisterOnSharedPreferenceChangeListener(this); + } - bitlyCreds.setEnabled(!checked); + @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(); - final Editor editor = sharedPrefs.edit(); - editor.putBoolean(getString(R.string.prefs_key_isgd_enabled), checked); - editor.apply(); - } - } + bitlyCreds.setEnabled(!checked); - /** - * Sets the bit.ly credentials summary. - */ - 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)); - } - } + 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(); + } + } + + /** + * Sets a preference's summary. + * + * @param editPref The preference. + * @param key The preference key. + * @param defValue The default value. + */ + 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); + } + } } diff --git a/app/src/main/res/layout/bitlycreds.xml b/app/src/main/res/layout/bitlycreds.xml index 859d613..b0bf4e5 100644 --- a/app/src/main/res/layout/bitlycreds.xml +++ b/app/src/main/res/layout/bitlycreds.xml @@ -1,34 +1,66 @@ - - + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:paddingTop="20dip"> - + 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"/> + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml deleted file mode 100644 index 036d09b..0000000 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index 036d09b..0000000 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 810a095..0000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png deleted file mode 100644 index 534341c..0000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index d4801a8..0000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-hdpi/icon.png b/app/src/main/res/mipmap-hdpi/icon.png new file mode 100644 index 0000000..960a148 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/icon.png differ diff --git a/app/src/main/res/mipmap-ldpi/icon.png b/app/src/main/res/mipmap-ldpi/icon.png new file mode 100644 index 0000000..494c897 Binary files /dev/null and b/app/src/main/res/mipmap-ldpi/icon.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index d80f36b..0000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png deleted file mode 100644 index f907330..0000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index 60e8276..0000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/icon.png b/app/src/main/res/mipmap-mdpi/icon.png new file mode 100644 index 0000000..adf62b8 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/icon.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index eb57116..0000000 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png deleted file mode 100644 index 0d67d2e..0000000 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 8883f45..0000000 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/icon.png b/app/src/main/res/mipmap-xhdpi/icon.png new file mode 100644 index 0000000..b51271b Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/icon.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 0d301e8..0000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png deleted file mode 100644 index bdcd09f..0000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index 4d28019..0000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 8ccb5db..0000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png deleted file mode 100644 index 4ca7614..0000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index 62540c4..0000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/values-v11/themes.xml b/app/src/main/res/values-v11/themes.xml new file mode 100644 index 0000000..3b567a6 --- /dev/null +++ b/app/src/main/res/values-v11/themes.xml @@ -0,0 +1,6 @@ + + + + - - - -
-

Emaily for Android

-
-

A simple app that makes things easier, and helps us to save some time.

-
AndroidZoom
-
-

- Get it on Google Play -

-

Emaily makes it easy to share shortened links from your phone.

-

No copy/paste required. Long URLs are squeezed into fewer characters using is.gd or bit.ly.

-
-
-

How to use…

-
-
When you find a web page you want to share, simply follow these steps:
-

-

    -
  1. Select the Options menu:
  2. - -
  3. Select the Share… menu option:
  4. - -
  5. Select Emaily from the Share sheet:
  6. - -
  7. Select Gmail (or whichever - application you want to share with):
  8. - -
  9. The shortened link is automatically inserted in a new email:
  10. - -
-

-
-
-
-

Using Bitly…

-
-
In order to use Bitly as for shortening links, you will need an API Access Token.
-

-

To enable Bitly follow these steps:

-
    -
  1. Disable is.gd by turning its switch off:
  2. - -
  3. Click on the Bitly API Access Token preference option:
  4. - -
  5. Enter your Bitly Access Token and click OK:
  6. - -
-

-
-
- - - - diff --git a/screenshots/1.0/.gitignore b/screenshots/.gitignore similarity index 93% rename from screenshots/1.0/.gitignore rename to screenshots/.gitignore index d758e81..5eacdb9 100644 --- a/screenshots/1.0/.gitignore +++ b/screenshots/.gitignore @@ -1,2 +1,2 @@ -/emaily.orig.avi -/emaily.wmv +/emaily.orig.avi +/emaily.wmv diff --git a/screenshots/1.0/2.png b/screenshots/1.0/2.png deleted file mode 100644 index 21f7544..0000000 Binary files a/screenshots/1.0/2.png and /dev/null differ diff --git a/screenshots/1.0/3.png b/screenshots/1.0/3.png deleted file mode 100644 index be36e2e..0000000 Binary files a/screenshots/1.0/3.png and /dev/null differ diff --git a/screenshots/1.0/4.png b/screenshots/1.0/4.png deleted file mode 100644 index d4d9419..0000000 Binary files a/screenshots/1.0/4.png and /dev/null differ diff --git a/screenshots/1.0/5.png b/screenshots/1.0/5.png deleted file mode 100644 index 73d6753..0000000 Binary files a/screenshots/1.0/5.png and /dev/null differ diff --git a/screenshots/1.0/6.png b/screenshots/1.0/6.png deleted file mode 100644 index b149ae8..0000000 Binary files a/screenshots/1.0/6.png and /dev/null differ diff --git a/screenshots/1.0/7.png b/screenshots/1.0/7.png deleted file mode 100644 index c3fabf6..0000000 Binary files a/screenshots/1.0/7.png and /dev/null differ diff --git a/screenshots/1.0/old/1.png b/screenshots/1.png similarity index 100% rename from screenshots/1.0/old/1.png rename to screenshots/1.png diff --git a/screenshots/1.0/old/2.png b/screenshots/2.png similarity index 100% rename from screenshots/1.0/old/2.png rename to screenshots/2.png diff --git a/screenshots/1.0/old/3.png b/screenshots/3.png similarity index 100% rename from screenshots/1.0/old/3.png rename to screenshots/3.png diff --git a/screenshots/1.0/old/4.png b/screenshots/4.png similarity index 100% rename from screenshots/1.0/old/4.png rename to screenshots/4.png diff --git a/screenshots/1.0/old/5.png b/screenshots/5.png similarity index 100% rename from screenshots/1.0/old/5.png rename to screenshots/5.png diff --git a/screenshots/1.0/api_branding.png b/screenshots/api_branding.png similarity index 100% rename from screenshots/1.0/api_branding.png rename to screenshots/api_branding.png diff --git a/screenshots/1.0/emaily.gif b/screenshots/emaily.gif similarity index 100% rename from screenshots/1.0/emaily.gif rename to screenshots/emaily.gif diff --git a/screenshots/google-play-badge.png b/screenshots/google-play-badge.png deleted file mode 100644 index c77b746..0000000 Binary files a/screenshots/google-play-badge.png and /dev/null differ diff --git a/screenshots/ic_launcher-playstore.png b/screenshots/ic_launcher-playstore.png deleted file mode 100644 index 3aa705b..0000000 Binary files a/screenshots/ic_launcher-playstore.png and /dev/null differ diff --git a/screenshots/1.0/icon-512x512.png b/screenshots/icon-512x512.png similarity index 100% rename from screenshots/1.0/icon-512x512.png rename to screenshots/icon-512x512.png diff --git a/screenshots/icon-noedge.png b/screenshots/icon-noedge.png deleted file mode 100644 index 6b252dd..0000000 Binary files a/screenshots/icon-noedge.png and /dev/null differ diff --git a/screenshots/1.0/icon.png b/screenshots/icon.png similarity index 100% rename from screenshots/1.0/icon.png rename to screenshots/icon.png diff --git a/screenshots/1.0/icon114x114.png b/screenshots/icon114x114.png similarity index 100% rename from screenshots/1.0/icon114x114.png rename to screenshots/icon114x114.png diff --git a/screenshots/main.png b/screenshots/main.png deleted file mode 100644 index a8b0934..0000000 Binary files a/screenshots/main.png and /dev/null differ diff --git a/screenshots/main_framed.png b/screenshots/main_framed.png deleted file mode 100644 index 4cd4439..0000000 Binary files a/screenshots/main_framed.png and /dev/null differ diff --git a/screenshots/1.0/promo-1024x500.png b/screenshots/promo-1024x500.png similarity index 100% rename from screenshots/1.0/promo-1024x500.png rename to screenshots/promo-1024x500.png diff --git a/screenshots/1.0/promo-180x120.png b/screenshots/promo-180x120.png similarity index 100% rename from screenshots/1.0/promo-180x120.png rename to screenshots/promo-180x120.png diff --git a/screenshots/steps/1.png b/screenshots/steps/1.png deleted file mode 100644 index a1773b5..0000000 Binary files a/screenshots/steps/1.png and /dev/null differ diff --git a/screenshots/steps/2.png b/screenshots/steps/2.png deleted file mode 100644 index b8bea53..0000000 Binary files a/screenshots/steps/2.png and /dev/null differ diff --git a/screenshots/steps/3.png b/screenshots/steps/3.png deleted file mode 100644 index b62bebe..0000000 Binary files a/screenshots/steps/3.png and /dev/null differ diff --git a/screenshots/steps/4.png b/screenshots/steps/4.png deleted file mode 100644 index 41288df..0000000 Binary files a/screenshots/steps/4.png and /dev/null differ diff --git a/screenshots/steps/4a.png b/screenshots/steps/4a.png deleted file mode 100644 index 4151759..0000000 Binary files a/screenshots/steps/4a.png and /dev/null differ diff --git a/screenshots/steps/4b.png b/screenshots/steps/4b.png deleted file mode 100644 index 18f6466..0000000 Binary files a/screenshots/steps/4b.png and /dev/null differ diff --git a/screenshots/steps/5.png b/screenshots/steps/5.png deleted file mode 100644 index 1659264..0000000 Binary files a/screenshots/steps/5.png and /dev/null differ diff --git a/screenshots/steps/6.png b/screenshots/steps/6.png deleted file mode 100644 index d2e1515..0000000 Binary files a/screenshots/steps/6.png and /dev/null differ diff --git a/screenshots/steps/bitly_creds.png b/screenshots/steps/bitly_creds.png deleted file mode 100644 index 98c26a2..0000000 Binary files a/screenshots/steps/bitly_creds.png and /dev/null differ diff --git a/screenshots/steps/bitly_selected.png b/screenshots/steps/bitly_selected.png deleted file mode 100644 index bffec06..0000000 Binary files a/screenshots/steps/bitly_selected.png and /dev/null differ diff --git a/screenshots/steps/isgd_disabled.png b/screenshots/steps/isgd_disabled.png deleted file mode 100644 index e29c1c1..0000000 Binary files a/screenshots/steps/isgd_disabled.png and /dev/null differ diff --git a/screenshots/steps/isgd_selected.png b/screenshots/steps/isgd_selected.png deleted file mode 100644 index c79d3c3..0000000 Binary files a/screenshots/steps/isgd_selected.png and /dev/null differ diff --git a/screenshots/web_hi_res_512.png b/screenshots/web_hi_res_512.png deleted file mode 100644 index 4d3d616..0000000 Binary files a/screenshots/web_hi_res_512.png and /dev/null differ diff --git a/settings.gradle b/settings.gradle index 3c080bb..e7b4def 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1 @@ include ':app' -rootProject.name = "Emaily"