diff --git a/api-logansquare/build.gradle b/api-logansquare/build.gradle
index 9daa9da..3e774b1 100644
--- a/api-logansquare/build.gradle
+++ b/api-logansquare/build.gradle
@@ -13,10 +13,6 @@ android {
}
}
-repositories {
- maven { url "http://dl.bintray.com/touchin/touchin-tools" }
-}
-
dependencies {
api project(":storable")
api 'net.danlew:android.joda:2.9.9.4'
diff --git a/build.gradle b/build.gradle
index d489a4e..ae4e81d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -14,6 +14,7 @@ allprojects {
repositories {
google()
jcenter()
+ maven { url "http://dl.bintray.com/touchin/touchin-tools" }
}
}
@@ -31,6 +32,7 @@ ext {
dagger : '2.16',
retrofit : '2.4.0',
rxJava : '2.1.17',
- rxAndroid : '2.0.2'
+ rxAndroid : '2.0.2',
+ crashlytics : '2.9.4'
]
}
diff --git a/modules.gradle b/modules.gradle
index 9b11a59..750126e 100644
--- a/modules.gradle
+++ b/modules.gradle
@@ -15,6 +15,7 @@ include ':lifecycle-rx'
include ':views'
include ':recyclerview-adapters'
include ':kotlin-extensions'
+include ':templates'
project(':utils').projectDir = new File(rootDir, 'utils')
project(':logging').projectDir = new File(rootDir, 'logging')
@@ -26,3 +27,4 @@ project(':lifecycle-rx').projectDir = new File(rootDir, 'lifecycle-rx')
project(':views').projectDir = new File(rootDir, 'views')
project(':recyclerview-adapters').projectDir = new File(rootDir, 'recyclerview-adapters')
project(':kotlin-extensions').projectDir = new File(rootDir, 'kotlin-extensions')
+project(':templates').projectDir = new File(rootDir, 'templates')
diff --git a/templates/.gitignore b/templates/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/templates/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/templates/build.gradle b/templates/build.gradle
new file mode 100644
index 0000000..1ee1e3b
--- /dev/null
+++ b/templates/build.gradle
@@ -0,0 +1,31 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion versions.compileSdk
+
+ defaultConfig {
+ minSdkVersion versions.minSdk
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+ api project(":utils")
+ api project(":logging")
+ api project(":api-logansquare")
+ api project(":navigation")
+
+ api 'com.android.support:multidex:1.0.3'
+
+ api 'net.danlew:android.joda:2.9.9.4'
+
+ implementation "com.android.support:appcompat-v7:$versions.supportLibrary"
+
+ implementation("com.crashlytics.sdk.android:crashlytics:$versions.crashlytics@aar") {
+ transitive = true
+ }
+}
diff --git a/templates/src/main/AndroidManifest.xml b/templates/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..ad64e1e
--- /dev/null
+++ b/templates/src/main/AndroidManifest.xml
@@ -0,0 +1,3 @@
+
diff --git a/templates/src/main/java/ru/touchin/templates/TouchinActivity.java b/templates/src/main/java/ru/touchin/templates/TouchinActivity.java
new file mode 100644
index 0000000..41b2e28
--- /dev/null
+++ b/templates/src/main/java/ru/touchin/templates/TouchinActivity.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016 Touch Instinct
+ *
+ * This file is part of RoboSwag library.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package ru.touchin.templates;
+
+import android.app.ActivityManager;
+import android.content.Intent;
+import android.graphics.drawable.BitmapDrawable;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.ColorRes;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.content.ContextCompat;
+
+import ru.touchin.roboswag.components.navigation.activities.BaseActivity;
+import ru.touchin.roboswag.core.log.Lc;
+
+/**
+ * Created by Gavriil Sitnikov on 11/03/16.
+ * Base class of activity to extends for Touch Instinct related projects.
+ */
+public abstract class TouchinActivity extends BaseActivity {
+
+ @Override
+ protected void onCreate(@Nullable final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // Possible work around for market launches. See http://code.google.com/p/android/issues/detail?id=2373
+ // for more details. Essentially, the market launches the main activity on top of other activities.
+ // we never want this to happen. Instead, we check if we are the root and if not, we finish.
+ if (!isTaskRoot() && getIntent().hasCategory(Intent.CATEGORY_LAUNCHER) && Intent.ACTION_MAIN.equals(getIntent().getAction())) {
+ Lc.e("Finishing activity as it is launcher but not root");
+ finish();
+ }
+ }
+
+ /**
+ * Setup task description of application for Android 5.0 and later. It is showing when user opens task bar.
+ *
+ * @param label Name of application to show in task bar;
+ * @param iconRes Icon of application to show in task bar;
+ * @param primaryColorRes Color of application to show in task bar.
+ */
+ protected void setupTaskDescriptor(@NonNull final String label, @DrawableRes final int iconRes, @ColorRes final int primaryColorRes) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ final ActivityManager.TaskDescription taskDescription = new ActivityManager.TaskDescription(label,
+ ((BitmapDrawable) ContextCompat.getDrawable(this, iconRes)).getBitmap(),
+ ContextCompat.getColor(this, primaryColorRes));
+ setTaskDescription(taskDescription);
+ }
+ }
+
+}
diff --git a/templates/src/main/java/ru/touchin/templates/TouchinApp.java b/templates/src/main/java/ru/touchin/templates/TouchinApp.java
new file mode 100644
index 0000000..8d33cb0
--- /dev/null
+++ b/templates/src/main/java/ru/touchin/templates/TouchinApp.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2016 Touch Instinct
+ *
+ * This file is part of RoboSwag library.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package ru.touchin.templates;
+
+import android.app.Application;
+import android.content.Context;
+import android.os.StrictMode;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.multidex.MultiDex;
+import android.util.Log;
+
+import com.crashlytics.android.Crashlytics;
+
+import net.danlew.android.joda.JodaTimeAndroid;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import io.fabric.sdk.android.Fabric;
+import ru.touchin.roboswag.core.log.ConsoleLogProcessor;
+import ru.touchin.roboswag.core.log.Lc;
+import ru.touchin.roboswag.core.log.LcGroup;
+import ru.touchin.roboswag.core.log.LcLevel;
+import ru.touchin.roboswag.core.log.LogProcessor;
+import ru.touchin.roboswag.core.utils.ShouldNotHappenException;
+
+/**
+ * Created by Gavriil Sitnikov on 10/03/16.
+ * Base class of application to extends for Touch Instinct related projects.
+ */
+public abstract class TouchinApp extends Application {
+
+ @Override
+ protected void attachBaseContext(@NonNull final Context base) {
+ super.attachBaseContext(base);
+ MultiDex.install(base);
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ JodaTimeAndroid.init(this);
+ if (BuildConfig.DEBUG) {
+ enableStrictMode();
+ Lc.initialize(new ConsoleLogProcessor(LcLevel.VERBOSE), true);
+ LcGroup.UI_LIFECYCLE.disable();
+ } else {
+ try {
+ final Crashlytics crashlytics = new Crashlytics();
+ Fabric.with(this, crashlytics);
+ Fabric.getLogger().setLogLevel(Log.ERROR);
+ Lc.initialize(new CrashlyticsLogProcessor(crashlytics), false);
+ } catch (final NoClassDefFoundError error) {
+ Lc.initialize(new ConsoleLogProcessor(LcLevel.INFO), false);
+ Lc.e("Crashlytics initialization error! Did you forget to add\n"
+ + "compile('com.crashlytics.sdk.android:crashlytics:+@aar') {\n"
+ + " transitive = true;\n"
+ + "}\n"
+ + "to your build.gradle?", error);
+ }
+ }
+ }
+
+ private void enableStrictMode() {
+ StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
+ .detectAll()
+ .permitDiskReads()
+ .permitDiskWrites()
+ .penaltyLog()
+ .build());
+ StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
+ .detectAll()
+ .penaltyLog()
+ .build());
+ }
+
+ private static class CrashlyticsLogProcessor extends LogProcessor {
+
+ @NonNull
+ private final Crashlytics crashlytics;
+
+ public CrashlyticsLogProcessor(@NonNull final Crashlytics crashlytics) {
+ super(LcLevel.INFO);
+ this.crashlytics = crashlytics;
+ }
+
+ @Override
+ public void processLogMessage(@NonNull final LcGroup group,
+ @NonNull final LcLevel level,
+ @NonNull final String tag,
+ @NonNull final String message,
+ @Nullable final Throwable throwable) {
+ if (group == LcGroup.UI_LIFECYCLE) {
+ crashlytics.core.log(level.getPriority(), tag, message);
+ } else if (!level.lessThan(LcLevel.ASSERT)
+ || (group == ApiModel.API_VALIDATION_LC_GROUP && level == LcLevel.ERROR)) {
+ Log.e(tag, message);
+ if (throwable != null) {
+ crashlytics.core.log(level.getPriority(), tag, message);
+ crashlytics.core.logException(throwable);
+ } else {
+ final ShouldNotHappenException exceptionToLog = new ShouldNotHappenException(tag + ':' + message);
+ reduceStackTrace(exceptionToLog);
+ crashlytics.core.logException(exceptionToLog);
+ }
+ }
+ }
+
+ private void reduceStackTrace(@NonNull final Throwable throwable) {
+ final StackTraceElement[] stackTrace = throwable.getStackTrace();
+ final List reducedStackTraceList = new ArrayList<>();
+ for (int i = stackTrace.length - 1; i >= 0; i--) {
+ final StackTraceElement stackTraceElement = stackTrace[i];
+ if (stackTraceElement.getClassName().contains(getClass().getSimpleName())
+ || stackTraceElement.getClassName().contains(LcGroup.class.getName())
+ || stackTraceElement.getClassName().contains(Lc.class.getName())) {
+ break;
+ }
+ reducedStackTraceList.add(0, stackTraceElement);
+ }
+ StackTraceElement[] reducedStackTrace = new StackTraceElement[reducedStackTraceList.size()];
+ reducedStackTrace = reducedStackTraceList.toArray(reducedStackTrace);
+ throwable.setStackTrace(reducedStackTrace);
+ }
+
+ }
+
+}
diff --git a/views/src/main/java/ru/touchin/roboswag/components/views/TypefacedEditText.java b/views/src/main/java/ru/touchin/roboswag/components/views/TypefacedEditText.java
index d556a81..ceac558 100644
--- a/views/src/main/java/ru/touchin/roboswag/components/views/TypefacedEditText.java
+++ b/views/src/main/java/ru/touchin/roboswag/components/views/TypefacedEditText.java
@@ -43,11 +43,6 @@ import ru.touchin.defaults.DefaultTextWatcher;
import ru.touchin.roboswag.components.views.internal.AttributesUtils;
import ru.touchin.roboswag.core.log.Lc;
-/**
- * Created by Gavriil Sitnikov on 18/07/2014.
- * TextView that supports fonts from Typefaces class
- */
-
/**
* Created by Gavriil Sitnikov on 18/07/2014.
* EditText that supports custom typeface and forces developer to specify if this view multiline or not.
@@ -57,15 +52,6 @@ import ru.touchin.roboswag.core.log.Lc;
//ConstructorCallsOverridableMethod: it's ok as we need to setTypeface
public class TypefacedEditText extends AppCompatEditText {
- private static boolean inDebugMode;
-
- /**
- * Enables debugging features like checking attributes on inflation.
- */
- public static void setInDebugMode() {
- inDebugMode = true;
- }
-
private boolean multiline;
private boolean constructed;
@@ -100,7 +86,7 @@ public class TypefacedEditText extends AppCompatEditText {
setSingleLine();
}
typedArray.recycle();
- if (inDebugMode) {
+ if (BuildConfig.DEBUG) {
checkAttributes(context, attrs);
}
}
diff --git a/views/src/main/java/ru/touchin/roboswag/components/views/TypefacedTextView.java b/views/src/main/java/ru/touchin/roboswag/components/views/TypefacedTextView.java
index 188686c..702342d 100644
--- a/views/src/main/java/ru/touchin/roboswag/components/views/TypefacedTextView.java
+++ b/views/src/main/java/ru/touchin/roboswag/components/views/TypefacedTextView.java
@@ -51,15 +51,6 @@ public class TypefacedTextView extends AppCompatTextView {
private static final int UNSPECIFIED_MEASURE_SPEC = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
private static final int START_SCALABLE_DIFFERENCE = 4;
- private static boolean inDebugMode;
-
- /**
- * Enables debugging features like checking attributes on inflation.
- */
- public static void setInDebugMode() {
- inDebugMode = true;
- }
-
private boolean constructed;
@NonNull
private LineStrategy lineStrategy = LineStrategy.SINGLE_LINE_ELLIPSIZE;
@@ -92,7 +83,7 @@ public class TypefacedTextView extends AppCompatTextView {
setLineStrategy(lineStrategy);
}
typedArray.recycle();
- if (inDebugMode) {
+ if (BuildConfig.DEBUG) {
checkAttributes(context, attrs);
}
}