├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── applogist │ │ └── extensions_sample │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── applogist │ │ │ └── extensions_sample │ │ │ └── MainActivity.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── applogist │ └── extensions_sample │ └── ExampleUnitTest.kt ├── build.gradle ├── extensions ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── applogist │ │ └── extensions │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── applogist │ │ │ ├── extensions │ │ │ ├── ActivityUtils.kt │ │ │ ├── ApplicationUtils.kt │ │ │ ├── BitmapUtils.kt │ │ │ ├── DateUtils.kt │ │ │ ├── FileUtils.kt │ │ │ ├── FormatUtils.kt │ │ │ ├── HexUtils.kt │ │ │ ├── MapUtils.kt │ │ │ ├── PackageUtils.kt │ │ │ ├── PhoneUtils.kt │ │ │ ├── RegexUtils.kt │ │ │ ├── SocialMediaUtils.kt │ │ │ └── ViewUtils.kt │ │ │ └── helpers │ │ │ ├── Common.kt │ │ │ ├── Resource.kt │ │ │ ├── SingleLiveEvent.kt │ │ │ └── SnapOnScrollListener.kt │ └── res │ │ ├── anim │ │ ├── slide_bottom_in.xml │ │ ├── slide_bottom_out.xml │ │ ├── slide_in_left.xml │ │ ├── slide_in_right.xml │ │ ├── slide_none.xml │ │ ├── slide_out_left.xml │ │ └── slide_out_right.xml │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── applogist │ └── extensions │ ├── ExampleUnitTest.kt │ └── RegexUtilsUnitTest.kt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | .DS_Store 6 | /build 7 | /captures 8 | .externalNativeBuild 9 | .cxx 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Extensions 4 | 5 | ## Installation 6 | [![](https://jitpack.io/v/applogistdev/ALExtensions-android.svg)](https://jitpack.io/#applogistdev/ALExtensions-android) 7 | ```gradle 8 | allprojects { 9 | repositories { ... maven { url 'https://jitpack.io' } }} 10 | 11 | dependencies { 12 | implementation 'com.github.applogistdev:ALExtensions-android:lastVersion'} 13 | ``` 14 | ## Extensions 15 | 16 | ## [ActivityUtils](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ActivityUtils.kt) 17 | | function | description | 18 | |--|--| 19 | |[startActivityModal](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ActivityUtils.kt#L14)|Open a new activity from bottom with animation| 20 | |[startActivityModalWithResult](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ActivityUtils.kt#L19)|Open a new activity from bottom with animation| 21 | |[startActivityFromRight](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ActivityUtils.kt#L27)|Open a new activity from right with animation| 22 | |[startActivityFromRightWithResult](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ActivityUtils.kt#L32)|Open a new activity from right with animation| 23 | |[slideOutRight](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ActivityUtils.kt#L40)|Close activity with animation| 24 | |[slideOutModal](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ActivityUtils.kt#L44)|Close activity with reverse modal animaton| 25 | |[reloadActivity](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ActivityUtils.kt#L48)|Reload activity instantly without animaton| 26 | |[share](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ActivityUtils.kt#L58)|Open a share intent for given type parameters| 27 | |[showAlertDialog](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ActivityUtils.kt#L70)|DSL for showing Alert Dialog| 28 | 29 | ## [BitmapUtils](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/BitmapUtils.kt) 30 | | function | description | 31 | |--|--| 32 | |[rotateBitmap](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/BitmapUtils.kt#L12)|Rotate bitmap| 33 | |[getBytes](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/BitmapUtils.kt#L50)|Return bytes of bitmap| 34 | |[convertBase64](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/BitmapUtils.kt#L59)|Convert Bitmap to Base64 String| 35 | 36 | 37 | ## [DateUtils](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/DateUtils.kt) 38 | | function | description | 39 | |--|--| 40 | |[formatDate](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/DateUtils.kt#L12)|Format string with given coming and sending date format or date format patterns| 41 | |[convertDateToCalendar](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/DateUtils.kt#L46)|Convert date string to calendar object with given date format or date format pattern| 42 | |[convertToMillis](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/DateUtils.kt#L87)|Convert date string to millis with given date format or date format pattern| 43 | |[convertDateString](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/DateUtils.kt#L103)|Convert millis to date string with given date format or date format pattern| 44 | |[toDate](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/DateUtils.kt#L137)|Convert string to date object| 45 | 46 | ## [FileUtils](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/FileUtils.kt) 47 | | function | description | 48 | |--|--| 49 | |[getOrientation](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/FileUtils.kt#L10)|Get orientation of image file| 50 | 51 | ## [FormatUtils](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/FormatUtils.kt) 52 | | function | description | 53 | |--|--| 54 | |[formatTwoDigit](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/FormatUtils.kt#L14)|Show double only with two digit| 55 | |[dp](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/FormatUtils.kt#L21)|Convert px to dp| 56 | |[px](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/FormatUtils.kt#L27)|Convert dp to px| 57 | |[trimAll](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/FormatUtils.kt#L33)|Remove all spaces in the string| 58 | |[removeNonNumeric](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/FormatUtils.kt#L40)|Remove all non numeric characters in the string| 59 | |[convertToNonTurkish](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/FormatUtils.kt#L47)|Convert turkish text to non turkish| 60 | |[format](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/FormatUtils.kt#L58)|Format double with given pattern and separators 61 | |[currencyFormat](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/FormatUtils.kt#L69)|Convert to currency format| 62 | 63 | ## [MapUtils](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/MapUtils.kt) 64 | 65 | | function | description | 66 | |--|--| 67 | |[openYandexNavi](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/MapUtils.kt#L19)|Open yandex navigation app| 68 | |[openYandexMaps](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/MapUtils.kt#L35)|Open yandex map| 69 | |[openGoogleMaps](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/MapUtils.kt#L51)|Open google maps| 70 | |[openMapAppsChooser](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/MapUtils.kt#L62)|Open map app choser intent| 71 | 72 | ## [PackageUtils](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/PackageUtils.kt) 73 | 74 | | function | description | 75 | |--|--| 76 | |[isAppInstalled](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/PackageUtils.kt#L15)|Use package name to find is app installed| 77 | |[openGooglePlayStore](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/PackageUtils.kt#L23)|Open Google Play Market, parameter tryWithWebView if fail open with browser| 78 | 79 | ## [PhoneUtils](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/PhoneUtils.kt) 80 | 81 | | function | description | 82 | |--|--| 83 | |[openPhoneDialer](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/PhoneUtils.kt#L18)|Open default dialer with phone number| 84 | 85 | 86 | 87 | ## [SocialMediaUtils](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/SocialMediaUtils.kt) 88 | 89 | | function | description | 90 | |--|--| 91 | |[openFacebookPage](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/SocialMediaUtils.kt#L18)|Open facebook page with Facebook Page Id| 92 | |[openInstagram](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/SocialMediaUtils.kt#L45)|Open Instagrem with User Id| 93 | |[openYoutube](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/SocialMediaUtils.kt#L59)|Open Youtube with Channel Id| 94 | |[openTwitter](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/SocialMediaUtils.kt#L73)|Open Twitter with User Id| 95 | 96 | ## [ViewUtils](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ViewUtils.kt) 97 | 98 | | function | description | 99 | |--|--| 100 | |[setGone](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ViewUtils.kt#L16)|Set view status to gone| 101 | |[setVisible](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ViewUtils.kt#L20)|Set view status to visible| 102 | |[setInvisible](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ViewUtils.kt#L24)|Set view status to invisible| 103 | |[setOnSingleClickListener](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ViewUtils.kt#L33)|Prevents double view click action| 104 | |[setHtmlText](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ViewUtils.kt#L47)|Set HTML text to TextView| 105 | |[setTextColorRes](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ViewUtils.kt#L57)|Change text color of TextView| 106 | |[setMargin](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/ViewUtils.kt#L64)|Change margins of the view| 107 | 108 | ## [RegexUtils](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/RegexUtils.kt) 109 | 110 | | function | description | 111 | |--|--| 112 | |[isTurkishMobileNumber](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/extensions/RegexUtils.kt#L17)|Check phone number is valid Turkish mobile phone number| 113 | 114 | ## Helpers 115 | ## [Common](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/helpers/Common.kt) 116 | 117 | | function | description | 118 | |--|--| 119 | |[isTimePassed](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/helpers/Common.kt#L12)|Check time difference between current time and given time| 120 | |[getMarketUrl](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/helpers/Common.kt#L36)|Get Google Play Market URL| 121 | 122 | ## [SingleLiveEvent](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/helpers/SingleLiveEvent.kt) 123 | Notify only observer once 124 | 125 | ## [Resource](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/helpers/Resource.kt) 126 | A generic class that holds a value with its loading status. 127 | 128 | ## [SnapOnScrollListener](https://github.com/applogistdev/ALExtensions-android/blob/master/extensions/src/main/java/com/applogist/helpers/SnapOnScrollListener.kt) 129 | Helper class for detecting snap position changes 130 | 131 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply plugin: 'kotlin-android' 4 | 5 | apply plugin: 'kotlin-android-extensions' 6 | 7 | android { 8 | compileSdkVersion 29 9 | buildToolsVersion "29.0.3" 10 | defaultConfig { 11 | applicationId "com.applogist.extensions_sample" 12 | minSdkVersion 21 13 | targetSdkVersion 29 14 | versionCode 1 15 | versionName "1.0" 16 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 17 | } 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | } 25 | 26 | dependencies { 27 | implementation fileTree(dir: 'libs', include: ['*.jar']) 28 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 29 | 30 | //Test 31 | testImplementation 'junit:junit:4.13' 32 | androidTestImplementation "androidx.test:core-ktx:1.2.0" 33 | androidTestImplementation 'androidx.test.ext:junit-ktx:1.1.1' 34 | androidTestImplementation "androidx.test:runner:1.2.0" 35 | androidTestImplementation "androidx.test:rules:1.2.0" 36 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 37 | androidTestImplementation "androidx.test.espresso:espresso-intents:3.2.0" 38 | // 39 | 40 | implementation 'androidx.appcompat:appcompat:1.1.0' 41 | implementation 'androidx.core:core-ktx:1.2.0' 42 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 43 | 44 | implementation project(':extensions') 45 | } 46 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/applogist/extensions_sample/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions_sample 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | import com.applogist.extensions.openPhoneDialer 6 | 7 | import org.junit.Test 8 | import org.junit.runner.RunWith 9 | 10 | import org.junit.Assert.* 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * See [testing documentation](http://d.android.com/tools/testing). 16 | */ 17 | @RunWith(AndroidJUnit4::class) 18 | class ExampleInstrumentedTest { 19 | @Test 20 | fun useAppContext() { 21 | // Context of the app under test. 22 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 23 | assertEquals("com.applogist.extensions_sample", appContext.packageName) 24 | } 25 | 26 | @Test 27 | fun openPhoneDialer() { 28 | val phoneNumber = "05070000000" 29 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 30 | assertTrue(appContext.openPhoneDialer(phoneNumber)) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/applogist/extensions_sample/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions_sample 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import android.os.Bundle 5 | 6 | class MainActivity : AppCompatActivity() { 7 | 8 | override fun onCreate(savedInstanceState: Bundle?) { 9 | super.onCreate(savedInstanceState) 10 | setContentView(R.layout.activity_main) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/applogistdev/ALExtensions-android/d90aabc3c421b0affb04935824eab7f30422ef44/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/applogistdev/ALExtensions-android/d90aabc3c421b0affb04935824eab7f30422ef44/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/applogistdev/ALExtensions-android/d90aabc3c421b0affb04935824eab7f30422ef44/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/applogistdev/ALExtensions-android/d90aabc3c421b0affb04935824eab7f30422ef44/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/applogistdev/ALExtensions-android/d90aabc3c421b0affb04935824eab7f30422ef44/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/applogistdev/ALExtensions-android/d90aabc3c421b0affb04935824eab7f30422ef44/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/applogistdev/ALExtensions-android/d90aabc3c421b0affb04935824eab7f30422ef44/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/applogistdev/ALExtensions-android/d90aabc3c421b0affb04935824eab7f30422ef44/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/applogistdev/ALExtensions-android/d90aabc3c421b0affb04935824eab7f30422ef44/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/applogistdev/ALExtensions-android/d90aabc3c421b0affb04935824eab7f30422ef44/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | ALExtensions-android 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/applogist/extensions_sample/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions_sample 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext.kotlin_version = '1.3.72' 5 | repositories { 6 | google() 7 | jcenter() 8 | 9 | } 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:4.0.0' 12 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | google() 21 | jcenter() 22 | 23 | } 24 | } 25 | 26 | task clean(type: Delete) { 27 | delete rootProject.buildDir 28 | } 29 | -------------------------------------------------------------------------------- /extensions/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /extensions/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | android { 5 | compileSdkVersion 29 6 | buildToolsVersion "29.0.3" 7 | 8 | 9 | defaultConfig { 10 | minSdkVersion 21 11 | targetSdkVersion 29 12 | versionCode 1 13 | versionName "1.0" 14 | 15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 16 | consumerProguardFiles 'consumer-rules.pro' 17 | } 18 | 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | 26 | } 27 | 28 | dependencies { 29 | implementation fileTree(dir: 'libs', include: ['*.jar']) 30 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 31 | implementation 'androidx.appcompat:appcompat:1.1.0' 32 | implementation 'androidx.core:core-ktx:1.2.0' 33 | testImplementation 'junit:junit:4.13' 34 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 35 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 36 | 37 | // For image rotation 38 | implementation "androidx.exifinterface:exifinterface:1.2.0" 39 | implementation 'androidx.recyclerview:recyclerview:1.1.0' 40 | } 41 | -------------------------------------------------------------------------------- /extensions/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/applogistdev/ALExtensions-android/d90aabc3c421b0affb04935824eab7f30422ef44/extensions/consumer-rules.pro -------------------------------------------------------------------------------- /extensions/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /extensions/src/androidTest/java/com/applogist/extensions/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.applogist.extensions.test", appContext.packageName) 23 | } 24 | 25 | @Test 26 | fun mapChooser(){ 27 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 28 | appContext.openMapAppsChooser(40.9889026,28.7943153, locationName = "Turkeyana Clinic") 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /extensions/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/extensions/ActivityUtils.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions 2 | 3 | 4 | import android.app.Activity 5 | import android.app.ActivityOptions 6 | import android.content.Context 7 | import android.content.Intent 8 | import android.os.Build 9 | import androidx.annotation.StyleRes 10 | import androidx.appcompat.app.AlertDialog 11 | import androidx.core.app.ActivityCompat 12 | import androidx.core.app.ShareCompat 13 | 14 | fun Activity.startActivityModal(intent : Intent) { 15 | val options = ActivityOptions.makeCustomAnimation(this, R.anim.slide_bottom_in, R.anim.slide_none) 16 | this.startActivity(intent, options.toBundle()) 17 | } 18 | 19 | fun Activity.startActivityModalWithResult(intent: Intent, requestCode : Int) { 20 | val options = ActivityOptions.makeCustomAnimation(this, R.anim.slide_bottom_in, R.anim.slide_none) 21 | if (Build.VERSION.SDK_INT >= 21) 22 | this.startActivityForResult(intent, requestCode, options.toBundle()) 23 | else 24 | ActivityCompat.startActivityForResult(this, intent, requestCode, options.toBundle()) 25 | } 26 | 27 | fun Activity.startActivityFromRight(intent: Intent) { 28 | val options = ActivityOptions.makeCustomAnimation(this, R.anim.slide_in_right, R.anim.slide_out_left) 29 | this.startActivity(intent, options.toBundle()) 30 | } 31 | 32 | fun Activity.startActivityFromRightWithResult(intent: Intent, requestCode: Int) { 33 | val options = ActivityOptions.makeCustomAnimation(this, R.anim.slide_in_right, R.anim.slide_out_left) 34 | if (Build.VERSION.SDK_INT >= 21) 35 | this.startActivityForResult(intent, requestCode, options.toBundle()) 36 | else 37 | ActivityCompat.startActivityForResult(this, intent, requestCode, options.toBundle()) 38 | } 39 | 40 | fun Activity.slideOutRight() { 41 | this.overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right) 42 | } 43 | 44 | fun Activity.slideOutModal() { 45 | this.overridePendingTransition(R.anim.slide_none, R.anim.slide_bottom_out) 46 | } 47 | 48 | fun Activity.reloadActivity() { 49 | finish() 50 | overridePendingTransition(0, 0) 51 | startActivity(intent) 52 | overridePendingTransition(0, 0) 53 | } 54 | 55 | /** 56 | * Share app link 57 | */ 58 | fun Activity.share(chooserTitle : String, text : String, type : String = "text/plain") { 59 | ShareCompat.IntentBuilder.from(this) 60 | .setType(type) 61 | .setChooserTitle(chooserTitle) 62 | .setText(text) 63 | .startChooser() 64 | } 65 | 66 | //region Alert Dialog 67 | /** 68 | * Alert Dialog 69 | */ 70 | fun Context.showAlertDialog(@StyleRes themeResId : Int? = null, cancelable: Boolean = false, cancelableTouchOutside: Boolean = false, builderFunction: AlertDialog.Builder.() -> Any) { 71 | 72 | val builder = if (themeResId == null) { 73 | AlertDialog.Builder(this) 74 | } else { 75 | AlertDialog.Builder(this, themeResId) 76 | } 77 | 78 | builder.builderFunction() 79 | val dialog = builder.create() 80 | 81 | dialog.setCancelable(cancelable) 82 | dialog.setCanceledOnTouchOutside(cancelableTouchOutside) 83 | dialog.show() 84 | } 85 | 86 | fun AlertDialog.Builder.positiveButton(text: String = "OK", handleClick: (i: Int) -> Unit = {}) { 87 | this.setPositiveButton(text) { _, i -> handleClick(i) } 88 | } 89 | 90 | fun AlertDialog.Builder.negativeButton(text: String = "CANCEL", handleClick: (i: Int) -> Unit = {}) { 91 | this.setNegativeButton(text) { _, i -> handleClick(i) } 92 | } 93 | 94 | fun AlertDialog.Builder.neutralButton(text: String, handleClick: (i: Int) -> Unit = {}) { 95 | this.setNeutralButton(text) { _, i -> handleClick(i) } 96 | } 97 | //endregion -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/extensions/ApplicationUtils.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions 2 | 3 | import android.content.Context 4 | import android.content.pm.PackageManager 5 | import android.os.Build 6 | import android.util.Log 7 | import java.security.MessageDigest 8 | 9 | /* 10 | * Created by Mustafa Ürgüplüoğlu on 10.04.2020. 11 | * Copyright © 2020 Mustafa Ürgüplüoğlu. All rights reserved. 12 | */ 13 | 14 | fun Context.getApplicationSignature(packageName: String, type : String = "SHA256"): List { 15 | val signatureList: List 16 | try { 17 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { 18 | // New signature 19 | val sig = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNING_CERTIFICATES).signingInfo 20 | signatureList = if (sig.hasMultipleSigners()) { 21 | // Send all with apkContentsSigners 22 | sig.apkContentsSigners.map { 23 | val digest = MessageDigest.getInstance(type) 24 | digest.update(it.toByteArray()) 25 | digest.digest().bytesToHex() 26 | } 27 | } else { 28 | // Send one with signingCertificateHistory 29 | sig.signingCertificateHistory.map { 30 | val digest = MessageDigest.getInstance(type) 31 | digest.update(it.toByteArray()) 32 | digest.digest().bytesToHex() 33 | } 34 | } 35 | } else { 36 | val sig = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures 37 | signatureList = sig.map { 38 | val digest = MessageDigest.getInstance(type) 39 | digest.update(it.toByteArray()) 40 | digest.digest().bytesToHex() 41 | } 42 | } 43 | 44 | return signatureList 45 | } catch (e: Exception) { 46 | Log.e("ApplicationUtils", e.toString()) 47 | } 48 | return emptyList() 49 | } -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/extensions/BitmapUtils.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions 2 | 3 | import android.graphics.Bitmap 4 | import android.graphics.Matrix 5 | import android.util.Base64 6 | import androidx.exifinterface.media.ExifInterface 7 | import java.io.ByteArrayOutputStream 8 | 9 | /** 10 | * Rotate Bitmap Image File 11 | */ 12 | fun Bitmap.rotateBitmap(orientation : Int) : Bitmap? { 13 | 14 | val matrix = Matrix() 15 | when (orientation) { 16 | ExifInterface.ORIENTATION_NORMAL -> return this 17 | ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> matrix.setScale(-1f, 1f) 18 | ExifInterface.ORIENTATION_ROTATE_180 -> matrix.setRotate(180f) 19 | ExifInterface.ORIENTATION_FLIP_VERTICAL -> { 20 | matrix.setRotate(180f) 21 | matrix.postScale(-1f, 1f) 22 | } 23 | ExifInterface.ORIENTATION_TRANSPOSE -> { 24 | matrix.setRotate(90f) 25 | matrix.postScale(-1f, 1f) 26 | } 27 | ExifInterface.ORIENTATION_ROTATE_90 -> matrix.setRotate(90f) 28 | ExifInterface.ORIENTATION_TRANSVERSE -> { 29 | matrix.setRotate(-90f) 30 | matrix.postScale(-1f, 1f) 31 | } 32 | ExifInterface.ORIENTATION_ROTATE_270 -> matrix.setRotate(-90f) 33 | else -> return this 34 | } 35 | 36 | return try { 37 | val bmRotated = Bitmap.createBitmap(this, 0, 0, this.width, this.height, matrix, true) 38 | this.recycle() 39 | bmRotated 40 | } catch (e: OutOfMemoryError) { 41 | e.printStackTrace() 42 | null 43 | } 44 | 45 | } 46 | 47 | /** 48 | * Return bytes of Bitmap 49 | */ 50 | fun Bitmap.getBytes(): ByteArray { 51 | val stream = ByteArrayOutputStream() 52 | this.compress(Bitmap.CompressFormat.JPEG, 100, stream) 53 | return stream.toByteArray() 54 | } 55 | 56 | /** 57 | * Convert Bitmap to Base64 String 58 | */ 59 | fun Bitmap.convertBase64() : String { 60 | return Base64.encodeToString(this.getBytes(), Base64.DEFAULT) 61 | } -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/extensions/DateUtils.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions 2 | 3 | import java.text.ParseException 4 | import java.text.SimpleDateFormat 5 | import java.util.* 6 | 7 | /** 8 | * Format String with given coming and sending date format 9 | * @param comingDateFormat : Current Date format of String 10 | * @param sendingDateFormat : Desired Date format for String 11 | */ 12 | fun String.formatDate(comingDateFormat: SimpleDateFormat, sendingDateFormat: SimpleDateFormat = comingDateFormat): String? { 13 | val date: Date? 14 | try { 15 | date = comingDateFormat.parse(this) 16 | } catch (e: ParseException) { 17 | e.printStackTrace() 18 | return null 19 | } 20 | date?.let { return sendingDateFormat.format(it) } ?: return null 21 | } 22 | 23 | /** 24 | * Format String with given coming and sending date format patterns 25 | * @param comingDatePattern : Current date format pattern 26 | * @param sendingDatePattern : Desired date format pattern 27 | */ 28 | fun String.formatDate(comingDatePattern : String, sendingDatePattern : String = comingDatePattern, locale : Locale = Locale.getDefault()): String? { 29 | val comingDateFormat = SimpleDateFormat(comingDatePattern, locale) 30 | val date: Date? 31 | try { 32 | date = comingDateFormat.parse(this) 33 | } catch (e: ParseException) { 34 | e.printStackTrace() 35 | return null 36 | } 37 | 38 | val sendingDateFormat = SimpleDateFormat(sendingDatePattern, locale) 39 | date?.let { return sendingDateFormat.format(it) } ?: return null 40 | } 41 | 42 | /** 43 | * Convert date to Calendar 44 | * @param comingDateFormat : Current date format of String 45 | */ 46 | fun String.convertDateToCalendar(comingDateFormat: SimpleDateFormat) : Calendar? { 47 | val date: Date? 48 | try { 49 | date = comingDateFormat.parse(this) 50 | } catch (e: ParseException) { 51 | e.printStackTrace() 52 | return null 53 | } 54 | 55 | date?.let { 56 | val cal = Calendar.getInstance() 57 | cal.time = date 58 | return cal 59 | } ?: return null 60 | } 61 | 62 | /** 63 | * Convert date to Calendar 64 | * @param sendingDatePattern : Current date format pattern 65 | */ 66 | fun String.convertDateToCalendar(sendingDatePattern : String, locale : Locale = Locale.getDefault()) : Calendar? { 67 | val comingDateFormat = SimpleDateFormat(sendingDatePattern, locale) 68 | val date: Date? 69 | try { 70 | date = comingDateFormat.parse(this) 71 | } catch (e: ParseException) { 72 | e.printStackTrace() 73 | return null 74 | } 75 | 76 | date?.let { 77 | val cal = Calendar.getInstance() 78 | cal.time = date 79 | return cal 80 | } ?: return null 81 | } 82 | 83 | /** 84 | * Convert date to millis 85 | * @param comingDateFormat : Current date format of String 86 | */ 87 | fun String.convertToMillis(comingDateFormat: SimpleDateFormat) : Long? { 88 | return this.convertDateToCalendar(comingDateFormat)?.timeInMillis 89 | } 90 | 91 | /** 92 | * Convert date to to Millis 93 | * @param sendingDatePattern : Current date format pattern 94 | */ 95 | fun String.convertToMillis(sendingDatePattern : String, locale : Locale = Locale.getDefault()) : Long? { 96 | return this.convertDateToCalendar(sendingDatePattern, locale)?.timeInMillis 97 | } 98 | 99 | /** 100 | * Convert long millis to date 101 | * @param dateFormat : Desired date format 102 | */ 103 | fun Long.convertDateString(dateFormat: SimpleDateFormat): String? { 104 | val date: Date? 105 | try { 106 | date = Date(this) 107 | } catch (e: ParseException) { 108 | e.printStackTrace() 109 | return null 110 | } 111 | return dateFormat.format(date) 112 | } 113 | 114 | /** 115 | * Convert long millis to date 116 | * @param dateFormatPattern : Desired date format pattern 117 | */ 118 | fun Long.convertDateString(dateFormatPattern: String, locale : Locale = Locale.getDefault()): String? { 119 | val comingDateFormat = SimpleDateFormat(dateFormatPattern, locale) 120 | val date: Date? 121 | try { 122 | date = Date(this) 123 | } catch (e: ParseException) { 124 | e.printStackTrace() 125 | return null 126 | } 127 | return comingDateFormat.format(date) 128 | } 129 | 130 | /** 131 | * @param pattern the pattern describing the date and time format 132 | * @param locale the locale whose date format symbols should be used 133 | * @param ifNull if you give null, when error happened 134 | * function return null otherwise return today date 135 | * @param timeZone the given new time zone 136 | */ 137 | fun String.toDate(pattern: String, locale: Locale = Locale.getDefault(), ifNull: Date? = Date(), timeZone: TimeZone? = null): Date? { 138 | val format = SimpleDateFormat(pattern, locale) 139 | if(timeZone != null){ 140 | format.timeZone = timeZone 141 | } 142 | return try { 143 | format.parse(this) ?: ifNull 144 | } catch (e: ParseException) { 145 | e.printStackTrace() 146 | ifNull 147 | } 148 | } -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/extensions/FileUtils.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions 2 | 3 | import androidx.exifinterface.media.ExifInterface 4 | import java.io.File 5 | import java.io.IOException 6 | 7 | /** 8 | * Get Orientation of Image File 9 | */ 10 | fun File.getOrientation() : Int { 11 | var exif: ExifInterface? = null 12 | try { 13 | exif = ExifInterface(this.path) 14 | } catch (e: IOException) { 15 | e.printStackTrace() 16 | } 17 | 18 | return exif?.getAttributeInt( 19 | ExifInterface.TAG_ORIENTATION, 20 | ExifInterface.ORIENTATION_UNDEFINED 21 | ) ?: ExifInterface.ORIENTATION_NORMAL 22 | } -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/extensions/FormatUtils.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions 2 | 3 | import android.content.res.Resources 4 | import java.text.DecimalFormat 5 | import java.text.DecimalFormatSymbols 6 | import java.text.Normalizer 7 | import java.text.NumberFormat 8 | import java.util.* 9 | 10 | /** 11 | * Show double only with two digit 12 | * 0.010670731707317074 -> 0.01 13 | */ 14 | fun Double.formatTwoDigit() : String { 15 | return String.format("%.2f", this) 16 | } 17 | 18 | /** 19 | * Convert px to dp 20 | */ 21 | val Int.dp: Int 22 | get() = (this / Resources.getSystem().displayMetrics.density).toInt() 23 | 24 | /** 25 | * Convert dp to px 26 | */ 27 | val Int.px: Int 28 | get() = (this * Resources.getSystem().displayMetrics.density).toInt() 29 | 30 | /** 31 | * Remove all spaces in the String 32 | */ 33 | fun String.trimAll(): String { 34 | return this.replace("\\s".toRegex(), "") 35 | } 36 | 37 | /** 38 | * Remove all non numeric characters in the String 39 | */ 40 | fun String.removeNonNumeric() : String { 41 | return this.replace("[^0-9]".toRegex(), "").trimAll() 42 | } 43 | 44 | /** 45 | * To convert turkish text to non turkish 46 | */ 47 | fun String.convertToNonTurkish(locale : Locale = Locale.getDefault()): String { 48 | val subjectString = Normalizer.normalize(this.toUpperCase(locale), Normalizer.Form.NFD) 49 | return subjectString.replace("[^\\x00-\\x7F]".toRegex(), "") 50 | } 51 | 52 | /** 53 | * Format with dots 54 | * 5000 -> 5.000 55 | * @param dfPattern : Decimal format pattern 56 | */ 57 | fun Double.format(dfPattern : String = "###,###.###", decimalSeparator : Char = '.', groupingSeparator : Char = '.'): String { 58 | val symbols = DecimalFormatSymbols() 59 | symbols.decimalSeparator = decimalSeparator 60 | symbols.groupingSeparator = groupingSeparator 61 | 62 | val dec = DecimalFormat(dfPattern, symbols) 63 | return dec.format(this) 64 | } 65 | 66 | /** 67 | * Format string for currency 68 | */ 69 | fun String.currencyFormat(locale: Locale = Locale.getDefault()): String? { 70 | return toDoubleOrNull()?.currencyFormat(locale) 71 | } 72 | 73 | /** 74 | * Format Double for currency 75 | */ 76 | fun Double.currencyFormat(locale: Locale = Locale.getDefault()): String { 77 | val nf = NumberFormat.getCurrencyInstance(locale) 78 | val decimalFormatSymbols = (nf as DecimalFormat).decimalFormatSymbols 79 | decimalFormatSymbols.currencySymbol = "" 80 | nf.decimalFormatSymbols = decimalFormatSymbols 81 | 82 | return nf.format(this) 83 | } -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/extensions/HexUtils.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions 2 | 3 | /* 4 | * Created by Mustafa Ürgüplüoğlu on 10.04.2020. 5 | * Copyright © 2020 Mustafa Ürgüplüoğlu. All rights reserved. 6 | */ 7 | 8 | fun ByteArray.bytesToHex(): String { 9 | val hexArray = charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F') 10 | val hexChars = CharArray(this.size * 2) 11 | var v: Int 12 | for (j in this.indices) { 13 | v = this[j].toInt() and 0xFF 14 | hexChars[j * 2] = hexArray[v.ushr(4)] 15 | hexChars[j * 2 + 1] = hexArray[v and 0x0F] 16 | } 17 | return String(hexChars) 18 | } -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/extensions/MapUtils.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions 2 | 3 | import android.content.ActivityNotFoundException 4 | import android.content.Context 5 | import android.content.Intent 6 | import android.net.Uri 7 | import android.util.Log 8 | import java.util.* 9 | 10 | /* 11 | * Created by Mustafa Ürgüplüoğlu on 17.02.2020. 12 | * Copyright © 2020 Mustafa Ürgüplüoğlu. All rights reserved. 13 | */ 14 | 15 | const val YANDEX_NAVI_PACKAGENAME = "ru.yandex.yandexnavi" 16 | const val YANDEX_MAPS_PACKAGENAME = "ru.yandex.yandexmaps" 17 | const val GOOGLE_MAPS_PACKAGENAME = "com.google.android.apps.maps" 18 | 19 | fun Context.openYandexNavi(latitude: Double, longitude: Double, showJams:Boolean = true): Boolean = try { 20 | val intent = Intent("ru.yandex.yandexnavi.action.BUILD_ROUTE_ON_MAP") 21 | intent.setPackage(YANDEX_NAVI_PACKAGENAME) 22 | intent.putExtra("lat_to", latitude) 23 | intent.putExtra("lon_to", longitude) 24 | if(showJams){ 25 | intent.putExtra("show_jams", 1) 26 | } 27 | intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK 28 | startActivity(intent) 29 | true 30 | }catch (e : ActivityNotFoundException){ 31 | Log.e("MapUtils", e.toString()) 32 | false 33 | } 34 | 35 | fun Context.openYandexMaps(latitude: Double, longitude: Double, showJams:Boolean = true): Boolean = try { 36 | val intent = Intent("ru.yandex.yandexmaps.action.BUILD_ROUTE_ON_MAP") 37 | intent.setPackage(YANDEX_MAPS_PACKAGENAME) 38 | intent.putExtra("lat_to", latitude) 39 | intent.putExtra("lon_to", longitude) 40 | if(showJams){ 41 | intent.putExtra("show_jams", 1) 42 | } 43 | intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK 44 | startActivity(intent) 45 | true 46 | }catch (e : ActivityNotFoundException){ 47 | Log.e("MapUtils", e.toString()) 48 | false 49 | } 50 | 51 | fun Context.openGoogleMaps(latitude: Double, longitude: Double): Boolean = try { 52 | val gmmIntentUri = Uri.parse("google.navigation:q=${latitude},${longitude}") 53 | val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri) 54 | mapIntent.setPackage(GOOGLE_MAPS_PACKAGENAME) 55 | startActivity(mapIntent) 56 | true 57 | } catch (e: ActivityNotFoundException) { 58 | Log.e("MapUtils", e.toString()) 59 | false 60 | } 61 | 62 | /** 63 | * @param latitude Location latitude 64 | * @param longitude Location longitude 65 | * @param Dialog chooser title 66 | * @param locationName Location possible name 67 | */ 68 | fun Context.openMapAppsChooser(latitude: Double, longitude: Double, chooserTitle : String = "Select your maps app", locationName : String? = null){ 69 | val uri = String.format(Locale.ENGLISH, "geo:%f,%f" + if(!locationName.isNullOrEmpty()) "?q=${locationName}" else "", latitude, longitude) 70 | val intent = Intent(Intent.ACTION_VIEW, Uri.parse(uri)) 71 | startActivity(Intent.createChooser(intent, chooserTitle)) 72 | } -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/extensions/PackageUtils.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions 2 | 3 | import android.content.ActivityNotFoundException 4 | import android.content.Context 5 | import android.content.Intent 6 | import android.content.pm.PackageManager 7 | import android.net.Uri 8 | import android.util.Log 9 | 10 | /* 11 | * Created by Mustafa Ürgüplüoğlu on 17.02.2020. 12 | * Copyright © 2020 Mustafa Ürgüplüoğlu. All rights reserved. 13 | */ 14 | 15 | fun Context.isAppInstalled(packageName: String): Boolean = try { 16 | packageManager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES) 17 | true 18 | } catch (e: PackageManager.NameNotFoundException) { 19 | Log.e("PackageUtils", e.toString()) 20 | false 21 | } 22 | 23 | fun Context.openGooglePlayStore(packageName: String, tryWithWebView: Boolean = true): Boolean = 24 | try { 25 | startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=$packageName"))) 26 | true 27 | } catch (e: ActivityNotFoundException) { 28 | if (tryWithWebView) { 29 | startActivity( 30 | Intent( 31 | Intent.ACTION_VIEW, 32 | Uri.parse("https://play.google.com/store/apps/details?id=$packageName") 33 | ) 34 | ) 35 | } 36 | false 37 | } -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/extensions/PhoneUtils.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions 2 | 3 | import android.content.ActivityNotFoundException 4 | import android.content.Context 5 | import android.content.Intent 6 | import android.net.Uri 7 | import android.util.Log 8 | 9 | /* 10 | * Created by Mustafa Ürgüplüoğlu on 17.02.2020. 11 | * Copyright © 2020 Mustafa Ürgüplüoğlu. All rights reserved. 12 | */ 13 | 14 | /** 15 | * This shows a UI with the number being dialed, allowing the user to explicitly initiate the call. 16 | * @return false if exception exist 17 | */ 18 | fun Context.openPhoneDialer(phoneNumber: String): Boolean = try { 19 | val intent = Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phoneNumber, null)) 20 | intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK 21 | startActivity(intent) 22 | true 23 | }catch (e : ActivityNotFoundException){ 24 | Log.e("PhoneUtils", e.toString()) 25 | false 26 | } 27 | 28 | -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/extensions/RegexUtils.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions 2 | 3 | import java.util.regex.Pattern 4 | 5 | /* 6 | * Created by Mustafa Ürgüplüoğlu on 14.05.2020. 7 | * Copyright © 2020 Mustafa Ürgüplüoğlu. All rights reserved. 8 | */ 9 | 10 | const val REGEX_TURKISH_MOBILE = "^[0]?((5[0-9][0-9]))\\d{7}\$" 11 | 12 | /** 13 | * Check phone number is valid Turkish mobile phone number 14 | * @param this Any string 15 | * @return true if valid 16 | */ 17 | fun String?.isTurkishMobileNumber() : Boolean{ 18 | return !this.isNullOrEmpty() && Pattern.matches(REGEX_TURKISH_MOBILE, this) 19 | } -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/extensions/SocialMediaUtils.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.net.Uri 6 | import android.util.Log 7 | 8 | /* 9 | * Created by Mustafa Ürgüplüoğlu on 17.02.2020. 10 | * Copyright © 2020 Mustafa Ürgüplüoğlu. All rights reserved. 11 | */ 12 | 13 | /** 14 | * @param pageId Facebook page id 15 | * @return true if Facebook app found 16 | */ 17 | fun Context.openFacebookPage(facebookPageID : String): Boolean { 18 | val facebookUrl = "https://www.facebook.com/$facebookPageID" 19 | val facebookUrlScheme = "fb://page/$facebookPageID" 20 | try { 21 | val versionCode = packageManager.getPackageInfo("com.facebook.katana", 0).versionCode 22 | if (versionCode >= 3002850) { 23 | val uri = Uri.parse("fb://facewebmodal/f?href=$facebookUrl") 24 | val intent = Intent(Intent.ACTION_VIEW, uri) 25 | intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK 26 | startActivity(intent) 27 | } else { 28 | val intent = Intent(Intent.ACTION_VIEW, Uri.parse(facebookUrlScheme)) 29 | intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK 30 | startActivity(intent) 31 | } 32 | return true 33 | } catch (e: Exception) { 34 | Log.e("SocialMediaUtils", e.toString()) 35 | } 36 | 37 | return false 38 | } 39 | 40 | /** 41 | * @param userId Instagram user id 42 | * @return true if Instagram app found 43 | */ 44 | fun Context.openInstagram(userId : String): Boolean = try { 45 | val intent = Intent(Intent.ACTION_VIEW, Uri.parse("http://instagram.com/_u/${userId}")) 46 | intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK 47 | startActivity(intent) 48 | true 49 | }catch (e : Exception){ 50 | Log.e("SocialMediaUtils", e.toString()) 51 | false 52 | } 53 | 54 | /** 55 | * @param channelId Youtube channel id 56 | * @return true if Youtube app found 57 | */ 58 | fun Context.openYoutube(channelId : String): Boolean = try { 59 | val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://www.youtube.com/channel/${channelId}")) 60 | intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK 61 | startActivity(intent) 62 | true 63 | }catch (e : Exception){ 64 | Log.e("SocialMediaUtils", e.toString()) 65 | false 66 | } 67 | 68 | /** 69 | * @param userId Twitter user id 70 | * @return true if Twitter app found 71 | */ 72 | fun Context.openTwitter(userId : String): Boolean = try { 73 | val intent = Intent(Intent.ACTION_VIEW, Uri.parse("twitter://user?user_id=${userId}")) 74 | intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK 75 | startActivity(intent) 76 | true 77 | }catch (e : Exception){ 78 | Log.e("SocialMediaUtils", e.toString()) 79 | false 80 | } -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/extensions/ViewUtils.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions 2 | 3 | import android.content.Context 4 | import android.view.View 5 | import android.view.ViewGroup 6 | import android.widget.TextView 7 | import androidx.annotation.ColorRes 8 | import androidx.core.content.ContextCompat 9 | import androidx.core.text.HtmlCompat 10 | 11 | /* 12 | * Created by Mustafa Ürgüplüoğlu on 18.02.2020. 13 | * Copyright © 2020 Mustafa Ürgüplüoğlu. All rights reserved. 14 | */ 15 | 16 | 17 | fun View.setGone(){ 18 | this.visibility = View.GONE 19 | } 20 | 21 | fun View.setVisible(){ 22 | this.visibility = View.VISIBLE 23 | } 24 | 25 | fun View.setInvisible(){ 26 | this.visibility = View.INVISIBLE 27 | } 28 | 29 | /** 30 | * Prevents double view click action 31 | * @param waitMillis waiting time for consume next click 32 | * @param func method that runs after click action 33 | */ 34 | fun View.setOnSingleClickListener( waitMillis : Long = 1000, func : (v : View) -> Unit) { 35 | var lastClickTime = 0L 36 | setOnClickListener { view -> 37 | if (System.currentTimeMillis() > lastClickTime + waitMillis) { 38 | func.invoke(view) 39 | lastClickTime = System.currentTimeMillis() 40 | } 41 | } 42 | } 43 | 44 | /** 45 | * Set HTML text 46 | * @param text html text string 47 | */ 48 | fun TextView.setHtmlText(text : String) { 49 | this.text = HtmlCompat.fromHtml(text, HtmlCompat.FROM_HTML_MODE_LEGACY) 50 | } 51 | 52 | internal fun Context.getColorCompat(@ColorRes color: Int) = ContextCompat.getColor(this, color) 53 | 54 | /** 55 | * Change text color of TextView 56 | * @params resId of color 57 | */ 58 | fun TextView.setTextColorRes(@ColorRes color: Int) = setTextColor(context.getColorCompat(color)) 59 | 60 | /** 61 | * Change margins of the view 62 | * Values will be converted to dp inside 63 | */ 64 | fun View.setMargin(leftMargin: Int = -1, topMargin : Int = -1, rightMargin : Int = -1, bottomMargin : Int = -1) { 65 | val params = layoutParams as ViewGroup.MarginLayoutParams 66 | params.setMargins( 67 | if (leftMargin == -1) params.leftMargin else leftMargin.px, 68 | if (topMargin == -1) params.topMargin else topMargin.px, 69 | if (rightMargin == -1) params.rightMargin else rightMargin.px, 70 | if (bottomMargin == -1) params.bottomMargin else bottomMargin.px) 71 | layoutParams = params 72 | } -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/helpers/Common.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.helpers 2 | 3 | import java.util.* 4 | import java.util.concurrent.TimeUnit 5 | 6 | /** 7 | * Check time difference between current time and given time 8 | * @param lastTime = Given time in millis format 9 | * @param isMinutes = different should be minutes or hour 10 | * @param checkTime = amount of time difference 11 | */ 12 | fun isTimePassed(lastTime : Long, isMinutes : Boolean = false, checkTime : Int = 8) : Boolean { 13 | 14 | val cal = Calendar.getInstance() 15 | val currentTime = cal.timeInMillis 16 | 17 | val difference = currentTime - lastTime 18 | 19 | val minutes = TimeUnit.MILLISECONDS.toMinutes(difference) 20 | val hours = TimeUnit.MILLISECONDS.toHours(difference) 21 | 22 | return when (isMinutes) { 23 | true -> { 24 | minutes >= checkTime 25 | } 26 | false -> { 27 | hours >= checkTime 28 | } 29 | } 30 | 31 | } 32 | 33 | /** 34 | * Get Google Play Market URL 35 | */ 36 | fun getMarketUrl(packageName : String) : String { 37 | return "https://play.google.com/store/apps/details?id=$packageName" 38 | } -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/helpers/Resource.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.helpers 2 | 3 | /** 4 | * A generic class that holds a value with its loading status. 5 | * @param 6 | */ 7 | sealed class Resource { 8 | class Success(val data: T) : Resource() 9 | class Error(val msg: String) : Resource() 10 | object Loading : Resource() 11 | } -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/helpers/SingleLiveEvent.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.helpers 2 | 3 | import android.util.Log 4 | import androidx.annotation.MainThread 5 | import androidx.annotation.Nullable 6 | import androidx.lifecycle.LifecycleOwner 7 | import androidx.lifecycle.MutableLiveData 8 | import androidx.lifecycle.Observer 9 | import java.util.concurrent.atomic.AtomicBoolean 10 | 11 | /** 12 | * Single Live Event class 13 | */ 14 | class SingleLiveEvent : MutableLiveData() { 15 | 16 | private val mPending = AtomicBoolean(false) 17 | 18 | @MainThread 19 | override fun observe(owner: LifecycleOwner, observer: Observer) { 20 | 21 | if (hasActiveObservers()) { 22 | Log.w("SingleLiveEvent", "Multiple observers registered but only one will be notified of changes.") 23 | } 24 | 25 | // Observe the internal MutableLiveData 26 | super.observe(owner, Observer { t -> 27 | if (mPending.compareAndSet(true, false)) { 28 | observer.onChanged(t) 29 | } 30 | }) 31 | } 32 | 33 | @MainThread 34 | override fun setValue(@Nullable t: T?) { 35 | mPending.set(true) 36 | super.setValue(t) 37 | } 38 | 39 | /** 40 | * Used for cases where T is Void, to make calls cleaner. 41 | */ 42 | @MainThread 43 | fun call() { 44 | value = null 45 | } 46 | } -------------------------------------------------------------------------------- /extensions/src/main/java/com/applogist/helpers/SnapOnScrollListener.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.helpers 2 | 3 | import androidx.recyclerview.widget.RecyclerView 4 | import androidx.recyclerview.widget.SnapHelper 5 | 6 | /** 7 | * Helper class for detecting snap position changes 8 | */ 9 | class SnapOnScrollListener( 10 | private val snapHelper: SnapHelper, 11 | var behavior: Behavior = Behavior.NOTIFY_ON_SCROLL, 12 | var onSnapPositionChangeListener: OnSnapPositionChangeListener? = null 13 | ) : RecyclerView.OnScrollListener() { 14 | 15 | enum class Behavior { 16 | NOTIFY_ON_SCROLL, 17 | NOTIFY_ON_SCROLL_STATE_IDLE 18 | } 19 | 20 | private var snapPosition = RecyclerView.NO_POSITION 21 | 22 | override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { 23 | if (behavior == Behavior.NOTIFY_ON_SCROLL) { 24 | maybeNotifySnapPositionChange(recyclerView) 25 | } 26 | } 27 | 28 | override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { 29 | if (behavior == Behavior.NOTIFY_ON_SCROLL_STATE_IDLE 30 | && newState == RecyclerView.SCROLL_STATE_IDLE) { 31 | maybeNotifySnapPositionChange(recyclerView) 32 | } 33 | } 34 | 35 | private fun maybeNotifySnapPositionChange(recyclerView: RecyclerView) { 36 | val snapPosition = snapHelper.getSnapPosition(recyclerView) 37 | val snapPositionChanged = this.snapPosition != snapPosition 38 | if (snapPositionChanged) { 39 | onSnapPositionChangeListener?.onSnapPositionChange(snapPosition) 40 | this.snapPosition = snapPosition 41 | } 42 | } 43 | } 44 | 45 | interface OnSnapPositionChangeListener { 46 | 47 | fun onSnapPositionChange(position: Int) 48 | } 49 | 50 | fun SnapHelper.getSnapPosition(recyclerView: RecyclerView): Int { 51 | val layoutManager = recyclerView.layoutManager ?: return RecyclerView.NO_POSITION 52 | val snapView = findSnapView(layoutManager) ?: return RecyclerView.NO_POSITION 53 | return layoutManager.getPosition(snapView) 54 | } -------------------------------------------------------------------------------- /extensions/src/main/res/anim/slide_bottom_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /extensions/src/main/res/anim/slide_bottom_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /extensions/src/main/res/anim/slide_in_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /extensions/src/main/res/anim/slide_in_right.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /extensions/src/main/res/anim/slide_none.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | -------------------------------------------------------------------------------- /extensions/src/main/res/anim/slide_out_left.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /extensions/src/main/res/anim/slide_out_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /extensions/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Extensions 3 | 4 | -------------------------------------------------------------------------------- /extensions/src/test/java/com/applogist/extensions/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /extensions/src/test/java/com/applogist/extensions/RegexUtilsUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.applogist.extensions 2 | 3 | import org.junit.Assert 4 | import org.junit.Test 5 | 6 | /* 7 | * Created by Mustafa Ürgüplüoğlu on 14.05.2020. 8 | * Copyright © 2020 Mustafa Ürgüplüoğlu. All rights reserved. 9 | */ 10 | 11 | class RegexUtilsUnitTest { 12 | 13 | @Test 14 | fun isTurkishMobileNumberTest() { 15 | //Turkcell, Vodafone, Turk Telekom 16 | val numberPrefixes = arrayListOf( 17 | "530", "531", "532", "533", "534", "535", "536", "537", "538", "539", "561", 18 | "540", "541", "542", "543", "544", "545", "546", "547", "548", "549", 19 | "500", "501", "502", "503", "504", "505", "506", "507", "508", "509", "550", "551", "552", "553", "554", "555", "556", "557", "558", "559" 20 | ) 21 | val numberSuffix = "2103350" 22 | 23 | numberPrefixes.forEach { 24 | val number = "$it$numberSuffix" 25 | println("$number - ${number.isTurkishMobileNumber()}") 26 | 27 | Assert.assertTrue(number.isTurkishMobileNumber()) 28 | } 29 | } 30 | 31 | @Test 32 | fun isTurkishMobileNumberTestWithZero() { 33 | //Turkcell, Vodafone, Turk Telekom 34 | val numberPrefixes = arrayListOf( 35 | "530", "531", "532", "533", "534", "535", "536", "537", "538", "539", "561", 36 | "540", "541", "542", "543", "544", "545", "546", "547", "548", "549", 37 | "500", "501", "502", "503", "504", "505", "506", "507", "508", "509", "550", "551", "552", "553", "554", "555", "556", "557", "558", "559" 38 | ) 39 | val numberSuffix = "2103350" 40 | 41 | numberPrefixes.forEach { 42 | val number = "0$it$numberSuffix" 43 | println("$number - ${number.isTurkishMobileNumber()}") 44 | 45 | Assert.assertTrue(number.isTurkishMobileNumber()) 46 | } 47 | } 48 | 49 | @Test 50 | fun isTurkishMobileNumberFailTest() { 51 | val numberPrefixes = arrayListOf( 52 | "262", "444", "123", "216", 53 | "0262", "0444", "0123", "0216" 54 | ) 55 | val numberSuffix = "2103350" 56 | 57 | numberPrefixes.forEach { 58 | val number = "$it$numberSuffix" 59 | println("$number - ${number.isTurkishMobileNumber()}") 60 | 61 | Assert.assertFalse(number.isTurkishMobileNumber()) 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official 22 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/applogistdev/ALExtensions-android/d90aabc3c421b0affb04935824eab7f30422ef44/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Jun 03 14:27:07 EET 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':extensions' 2 | rootProject.name='ALExtensions-android' 3 | --------------------------------------------------------------------------------