✔️ Secure, simple key-value storage for Android

Overview

Android Arsenal API Join the chat at https://gitter.im/orhanobut/hawk Build Status

Hawk 2.0

Secure, simple key-value storage for android

Important Note

This version has no backward compatibility with Hawk 1+ versions. If you still want to use old versions, check here

Download

compile "com.orhanobut:hawk:2.0.1"

Initialize

Hawk.init(context).build();

Usage

Save any type (Any object, primitives, lists, sets, maps ...)

Hawk.put(key, T);

Get the original value with the original type

T value = Hawk.get(key);

Delete any entry

Hawk.delete(key);

Check if any key exists

Hawk.contains(key);

Check total entry count

Hawk.count();

Get crazy and delete everything

Hawk.deleteAll();

How does Hawk work?

More options

  • Everything is pluggable, therefore you can change any layer with your custom implementation.
  • NoEncryption implementation is provided out of box If you want to disable crypto.
Hawk.init(context)
  .setEncryption(new NoEncryption())
  .setLogInterceptor(new MyLogInterceptor())
  .setConverter(new MyConverter())
  .setParser(new MyParser())
  .setStorage(new MyStorage())
  .build();

License

Copyright 2016 Orhan Obut

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.
Comments
  • SecretKeyFactory PBKDF2WithHmacSHA1 implementation not found

    SecretKeyFactory PBKDF2WithHmacSHA1 implementation not found

    Thanks for creating this.

    I am trying to use Hawk in one of my projects but getting the bellow error on some Samsung devices:

    java.lang.RuntimeException: java.security.NoSuchAlgorithmException: SecretKeyFactory PBKDF2WithHmacSHA1 implementation not found

    Any workaround for that?. Thanks.

    bug 
    opened by savekirk 23
  • Hawk 2 Specs

    Hawk 2 Specs

    The goal

    CRUD one object in secure way and super fast.

    Hawk should do only and only one thing and it should do it best.

    Known Issues

    • Startup time is quite long and this creates frictions
    • Selecting right encryption option is complex, Strong, medium, no encryption etc creates confusion.
    • Some devices don't have required encryption packages
    • Serialization/Deserialization problems. Usually object is saved but .get() function returns null.
    • Performance issues
    • Singleton

    Hawk 2.0

    • [x] Use only one mode as default. Fast and secure persistency.
    • [x] Reduce the startup time, therefore users won't need async operation for initialization. Better, find a way to remove init operation.
    • [x] Reduce the time for the CRUD operations. Async operation should be only used for very big data.
    • [x] Async utility is up to the client, therefore everything should be sync
    • [x] Use only one storage provider and keep it pluggable. Currently sqlite and sharedpreferences are both supported but Hawk should not be used for a lot of data already. Most probably only sharedpref will be supported as built-in.
    • [ ] Hawk.init() should be optional.
    • [x] Provide pluggable logger abstraction. Implementation should be up to client. Therefore remove LogLevel
    • [x] Remove chain option.
    • [x] Provide pluggable storage.
    • [x] Provide pluggable converter
    // Initialization
    Hawk.init(context);
    
    // Save any data
    Hawk.put(key, T);
    
    // Get the original data
    T t = Hawk.get(key);
    
    // Delete 
    Hawk.delete(key);
    
    // Contains
    boolean value = Hawk.contains(key);
    
    // Total count
    int count = Hawk.count();
    
    // Delete all entries
    Hawk.deleteAll();
    
    // intercept logs
    Hawk.init(context).interceptLog(new LogInterceptor(){
       @Override public void onLog(String message){
        }
    });
    
    // plug converter
    Hawk.init(context).addConverter(new YourCustomConverter());
    
    // plug storage
    Hawk.init(context).addStorage(new YourCustomStorage());
    
    
    

    To be continued

    opened by orhanobut 16
  • java.lang.IllegalArgumentException: Cannot parse iv:ciphertext:mac

    java.lang.IllegalArgumentException: Cannot parse iv:ciphertext:mac

    I am using version 1.17,

    We are getting this error on some of the devices, (HUAWEI Y300-0100, VS930 4G, GT-18552, LG-F100L). Affected operating systems are(Android 4.1.1 and 4.1.2). Locale is all "en". This is our full error stacktrace

    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4247) at android.app.ActivityThread.access$1300(ActivityThread.java:137) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1270) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4838) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:875) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:642) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.IllegalArgumentException: Cannot parse iv:ciphertext:mac at com.orhanobut.hawk.AesCbcWithIntegrity$CipherTextIvMac.(AesCbcWithIntegrity.java:538) at com.orhanobut.hawk.AesEncryption.getCipherTextIvMac(AesEncryption.java:77) at com.orhanobut.hawk.AesEncryption.decrypt(AesEncryption.java:62) at com.orhanobut.hawk.Hawk.get(Hawk.java:132)

    Thanks

    bug 
    opened by yekmer 14
  • Strange ArrayIndexOutOfBoundsException

    Strange ArrayIndexOutOfBoundsException

    I am receiving some crash logs which I suspect is related to Hawk. Here's the log:

    java.lang.ArrayIndexOutOfBoundsException: src.length=75 srcPos=0 dst.length=0 dstPos=0 length=57
           at java.lang.System.arraycopy(System.java)
           at java.lang.String.getChars(String.java:889)
           at com.android.internal.util.FastXmlSerializer.append(FastXmlSerializer.java:89)
           at com.android.internal.util.FastXmlSerializer.append(FastXmlSerializer.java:113)
           at com.android.internal.util.FastXmlSerializer.startDocument(FastXmlSerializer.java:326)
           at com.android.internal.util.XmlUtils.writeMapXml(XmlUtils.java:183)
           at android.app.SharedPreferencesImpl.writeToFile(SharedPreferencesImpl.java:598)
           at android.app.SharedPreferencesImpl.access$800(SharedPreferencesImpl.java:52)
           at android.app.SharedPreferencesImpl$2.run(SharedPreferencesImpl.java:513)
           at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
           at java.lang.Thread.run(Thread.java:838)
    

    In all of the crashes src.length is 75 and length is 57. Maybe it's the salt or some other key that is stored by Hawk? Crashes occurred on devices like: HUAWEI Y320-U30, HUAWEI Y511-U30. I also can tell that this crashes occurs on the startup of the application. Any idea why this is happening?

    bug 
    opened by avsector 11
  • Hawk should allow broken PRNG or at least fallback

    Hawk should allow broken PRNG or at least fallback

    On some devices with old updates, PRNG is broken, causing crashes. For example Nokia XL with Android 4.1. In latest updates to AesCbcWithIntegrity this flag is introduced:

    private static final boolean ALLOW_BROKEN_PRNG = false;
    

    which if set to true will prevent SecurityException on such devices in places like:

    if (!rng2.getProvider().getClass().getSimpleName().equals("LinuxPRNGSecureRandomProvider")) {
        if (ALLOW_BROKEN_PRNG) {
                Log.w(PrngFixes.class.getSimpleName(),
                        "SecureRandom.getInstance(\"SHA1PRNG\") backed by wrong" + " Provider: "
                        + rng2.getProvider().getClass());
                return;
        } else {
                throw new SecurityException(
                    "SecureRandom.getInstance(\"SHA1PRNG\") backed by wrong" + " Provider: "
                    + rng2.getProvider().getClass());
        }
    }
    

    Without that on some devices crashes like this will occur as stated above:

    java.lang.SecurityException: SecureRandom.getInstance("SHA1PRNG") backed by wrong Provider: class org.apache.harmony.security.provider.crypto.CryptoProvider
           at com.c.a.c.d(AesCbcWithIntegrity.java:718)
           at com.c.a.c.a(AesCbcWithIntegrity.java:642)
           at com.c.a.a.d(AesCbcWithIntegrity.java:313)
           at com.c.a.a.a(AesCbcWithIntegrity.java:219)
           at com.c.a.a.c(AesCbcWithIntegrity.java:215)
           at com.c.a.a.a(AesCbcWithIntegrity.java:289)
           at com.c.a.g.a(AesEncryption.java:45)
           at com.c.a.n.b(Hawk.java:218)
           at com.c.a.n.a(Hawk.java:174)
           ...
    

    I think as an encrypted storage library, Hawk should allow broken PRNG. I also don't see why Hawk is not using the latest version of AesCbcWithIntegrity. Are there any conflicts? I suggest updating to the latest AesCbcWithIntegrity and setting that flag to true. I can send a pull request with these changes if that's ok. Just let me know.

    opened by avsector 8
  • NPE again...

    NPE again...

    Caused by: java.lang.NullPointerException at com.orhanobut.hawk.AesCbcWithIntegrity.decrypt(AesCbcWithIntegrity.java:368) at com.orhanobut.hawk.AesEncryption.decrypt(AesEncryption.java:61) at com.orhanobut.hawk.Hawk.get(Hawk.java:220) at com.orhanobut.hawk.Hawk.get(Hawk.java:237)

    bug 
    opened by csechuan 8
  • Multiple Hawk instances

    Multiple Hawk instances

    First of all, great start to this library- I sense a real need for a solid encrypted key/value store in the Android ecosystem.

    I'm working on a use case that requires a set of encrypted stores, where one is semi-secure (encrypted by a secret in the app binary) and another is encrypted using a value inputted from the user. Hawk has most of the features I need but I think its singleton nature is a limitation here.

    Some ideas:

    Questions for you:

    • Do you still see the need for a singleton instance of Hawk? Is it good enough to let users create one with new Hawk() and manage that object themselves? Or maybe have 1 global instance (Hawk.getInstance()) as well as a public constructor?
    • Logger becomes an issue if Hawk is no longer a singleton, because the Logger instance must be passed down the object hierarchy.

    I've already started some of this, but was interested in your feedback.

    opened by bosgood 8
  • Created status for Hawk

    Created status for Hawk

    I've created a "status" field for Hawk. In this way the dev can know if Hawk is ready to be used and Hawk itself avoid operations if it has not been initialised

    opened by carlonzo 7
  • Add Hawk.buildRx()

    Add Hawk.buildRx()

    StrictMode showed that .build() was doing a lot of work on the main thread, even with the callback setup. I tried to wrap the callback with Rx, but I was having issue with Schedulers, Looper, Handler and so on. I have just created a new method that wraps the synchronous .startbuild(), and exposes an Observable version of build().

    opened by hamen 7
  • Can't get List<Foo> from Hawk.get

    Can't get List from Hawk.get

    Hi there, I defined a Class named Foo.

    public class Foo {
    
        private String carSeries;
        private Uri carImageUri;
        private String carType;
    
    
        public String getCarSeries() {
            return carSeries;
        }
    
        public void setCarSeries(String carSeries) {
            this.carSeries = carSeries;
        }
    
        public Uri getCarImageUri() {
            return carImageUri;
        }
    
        public void setCarImageUri(Uri carImageUri) {
            this.carImageUri = carImageUri;
        }
    
        public String getCarType() {
            return carType;
        }
    
        public void setCarType(String carType) {
            this.carType = carType;
        }
    
        @Override
        public String toString() {
            return "Foo{" +
                "carSeries='" + carSeries + '\'' +
                ", carImageUri=" + carImageUri +
                ", carType='" + carType + '\'' +
                '}';
        }
    }
    
    List<Foo> foos = new ArrayList<Foo>();
    foos.add(new Foo());
    foos.add(new Foo());
    Hawk.put(Constant.PREF_FOO, foos);
    

    but Hawk.get(Constant.PREF_FOO, new ArrayList<Foo>()); always return list which size is 0(default value).

    opened by dos1in 7
  • Crash on return from background

    Crash on return from background

    Hi there, I have been having a crash when the app returns from background, specifically after a few hours. It seems Hawk instance is removed and it becomes null. Throwing exception

    java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object com.orhanobut.hawk.Storage.get(java.lang.String)' on a null object reference at com.orhanobut.hawk.Hawk.get

    I have tried re-initializing Hawk onResume but does'nt seem to help.

    Any suggestions?

    Thanks

    opened by VeeruPV 7
  • Hawk.count() shows it has items but when use hawl.get(key, type) it gives only last or zero items

    Hawk.count() shows it has items but when use hawl.get(key, type) it gives only last or zero items

    Please try to fill all questions below before submitting an issue.

    • [x] On which android versions do you have this issue? : Android 10
    • [x] On which phones do you have this issue? : Redmi note 7 pro
    • [x] Which hawk version are you using? : "com.orhanobut:hawk:2.0.1"
    • [x] Does this issue happen always or is it flaky? : always
    • [ ] Can you write failing test? :
    • [x] Is the data you are trying to save it huge or small? : small
    • [x] If it is Hawk.put and Hawk.get issue, can you write down which data you were trying to save and get it back? List<StickerPack> packs = Hawk.get("sticker_packs", new ArrayList<StickerPack>());

    app stored 158 sticker packs and whatsapp can access those sticker packs. But when I tried to access it withing class it give only one item which last added item while Hawk.count() gives proper count. I saw there is syntax for single or multiple items retrieval. But when I pass second argument as boolean it gives error that it accepts (key, type).

    opened by CrackerKSR 0
  • ANR problem when init Hawk

    ANR problem when init Hawk

    Please try to fill all questions below before submitting an issue.

    • [x] On which android versions do you have this issue? : android > 11
    • [x] On which phones do you have this issue? : Samsung & vivo
    • [x] Which hawk version are you using? : 2.0.1
    • [x] Does this issue happen always or is it flaky? : yes
    • [x] Can you write failing test? : It's hard to test since in my emulator everything looks normal.
    • [ ] If it is Hawk.put and Hawk.get issue, can you write down which data you were trying to save and get it back? : Issue only happened when device state in background. It's causing ANR and there is no user journey detecting in Crashlytics
    • [ ] Is the data you are trying to save it huge or small?

    Log Error

    main (runnable): tid=1 systid=31973 
           at com.google.gson.FieldNamingPolicy.<init>(FieldNamingPolicy.java)
           at com.google.gson.FieldNamingPolicy.<init>(FieldNamingPolicy.java)
           at com.google.gson.FieldNamingPolicy$1.<init>(FieldNamingPolicy.java)
           at com.google.gson.FieldNamingPolicy.<clinit>(FieldNamingPolicy.java)
           at com.google.gson.Gson.<init>(Gson.java)
           at com.orhanobut.hawk.HawkBuilder.getParser(HawkBuilder.java)
           at com.orhanobut.hawk.HawkBuilder.getConverter(HawkBuilder.java)
           at com.orhanobut.hawk.DefaultHawkFacade.<init>(DefaultHawkFacade.java)
           at com.orhanobut.hawk.Hawk.build(Hawk.java)
           at com.orhanobut.hawk.HawkBuilder.build(HawkBuilder.java)
           at com.tribunnews.app.TribunNewsApplication.onCreate(TribunNewsApplication.java)
           at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1192)
           at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7593)
           at android.app.ActivityThread.access$1500(ActivityThread.java:301)
           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2177)
           at android.os.Handler.dispatchMessage(Handler.java:106)
           at android.os.Looper.loop(Looper.java:246)
           at android.app.ActivityThread.main(ActivityThread.java:8653)
           at java.lang.reflect.Method.invoke(Method.java)
           at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
    
    opened by superdiazzz 1
  • Improve GRADLE build Performance

    Improve GRADLE build Performance

    Incremental compilation. Gradle recompile only the classes that were affected by a change. This feature is the default since Gradle 4.10. For an older versions, we can activate it by setting options.incremental = true.

    ===================== If there are any inappropriate modifications in this PR, please give me a reply and I will change them.

    opened by shisheng-1 0
  • can't get data when overriding apps

    can't get data when overriding apps

    Please try to fill all questions below before submitting an issue.

    • [ ] On which android versions do you have this issue? : every version
    • [ ] On which phones do you have this issue? : xiaomi 8 lite
    • [ ] Which hawk version are you using? : 2.0.1
    • [ ] Does this issue happen always or is it flaky? : no
    • [ ] Can you write failing test? : no
    • [ ] If it is Hawk.put and Hawk.get issue, can you write down which data you were trying to save and get it back?no
    • [ ] Is the data you are trying to save it huge or small? small

    i am using Hawk in a project (A), it's publishing in google play. Now, i created another project (B), I let the appId of 2 projects overlap, I increased the version code and version name on B, B can override A but B can't get data in A.

    in project A, i saved String by Hawk, when B override A, B can read this data, but when i save object in A, B can't read it. What have i do?

    Thanks

    opened by jynd 2
  • Classifier 'Hawk' does not have a companion object, and thus must be initialized here

    Classifier 'Hawk' does not have a companion object, and thus must be initialized here

    Hi I new in kotlin and when use Hawk.get(key), get error below: Classifier 'Hawk' does not have a companion object, and thus must be initialized here

    please help me

    opened by iranandroid 0
Releases(2.0.1)
  • 2.0.1(Apr 3, 2018)

    2.0.1

    • Conceal is updated, with the new version the size is way smaller

    2.0.0

    • Rx support is removed
    • Chain option is removed
    • Facebook conceal is added as crypto provider
    • Async operations are removed
    • EncryptionMethod is removed, as default it's encrypted and fallback to no encryption mode if the crypto is not available
    • NoEncryption option is available through setEncryption out of box
    • LogLevel is removed. All log messages are delegated to LogInterceptor, thus you can intercept and print it. Otherwise all log messages will be ignored.
    • All abstraction layers are pluggable. (Converter, Parser, Encryption, Serializer, Storage)
    • Sqlite option is removed.
    • Init is super fast now, no need to async operation.
    Source code(tar.gz)
    Source code(zip)
  • 1.23(Apr 5, 2016)

  • 1.22(Jan 24, 2016)

  • 1.21(Dec 17, 2015)

    • static variables are removed
    • isBuilt() function is introduced, you can use this function to determine whether Hawk is initialised or not before using.
    Source code(tar.gz)
    Source code(zip)
  • 1.20(Sep 16, 2015)

  • 1.19(Sep 15, 2015)

  • v1.18(Aug 7, 2015)

  • v1.17(Jul 18, 2015)

    • HawkBuilder introduced, Hawk.init is radically changed
    Hawk.init(this)
        .setEncryptionMethod(HawkBuilder.EncryptionMethod.HIGHEST)
        .setPassword("password")
        .setStorage(HawkBuilder.newSqliteStorage(this))
        .setLogLevel(LogLevel.FULL)
        .setCallback    //optional
        .build();
    
    • Storage option added, Sqlite or sharedpreferences
    Source code(tar.gz)
    Source code(zip)
  • v1.16(Jul 15, 2015)

  • v1.15(Jul 4, 2015)

  • v1.14(May 30, 2015)

  • v1.13(May 30, 2015)

  • v1.12(May 29, 2015)

  • v1.10(May 16, 2015)

  • v1.9(May 16, 2015)

  • v1.8(May 13, 2015)

    • Fallback support added for encryption when the device does not support PBE algorithm.
    • Value can be null now, if the value is null, it will do remove operation instead of saving null value.
    Source code(tar.gz)
    Source code(zip)
  • v1.5(Mar 13, 2015)

    • API 9 supported methods are replaced
    • Gradle credentials.properties file issue fixed
    • Bulk insert added
    • Bulk remove added
    • init method can work async now with the callback.
    • remove, put methods return the result as boolean
    Source code(tar.gz)
    Source code(zip)
  • v1.4(Feb 26, 2015)

  • v1.3(Feb 23, 2015)

  • v1.2(Feb 23, 2015)

  • v1.1(Feb 21, 2015)

Owner
Orhan Obut
Architect | ex Android GDE
Orhan Obut
Android library to easily serialize and cache your objects to disk using key/value pairs.

Deprecated This project is no longer maintained. No new issues or pull requests will be accepted. You can still use the source or fork the project to

Anup Cowkur 667 Dec 22, 2022
Reactor is key value database and is a great alternative to Shared Preferences.

Reactor Reactor is a fast and secure key-value library for Android, and has an embedded database based on the JSON structure and is a great alternativ

mr amir abbas 37 Oct 30, 2022
An easy-to-use, cross-platform measurement tool that pulls data out of CD pipelines and analysis the four key metrics for you.

Maintained by SEA team, ThoughtWorks Inc. Read this in other languages: English, 简体中文 Table of Contents About the Project Usage How to Compute Contrib

Thoughtworks 277 Jan 7, 2023
ModernStorage is a group of libraries that provide an abstraction layer over storage on Android to simplify its interactions

ModernStorage ModernStorage is a group of libraries that provide an abstraction layer over storage on Android to simplify its interactions by apps dev

Google 1.1k Dec 30, 2022
CloudStorageUtil - An Android library to make sync on Google Cloud Storage easier

gCloud Storage Utils An Android library to make sync on Google Cloud Storage eas

Evolve Asia 0 Jul 13, 2022
KmmCaching - An application that illustrates fetching data from remote data source and caching it in local storage

An application that illustrates fetching data from remote data source and caching it in local storage for both IOS and Android platforms using Kotlin Multiplatform Mobile and SqlDelight.

Felix Kariuki 5 Oct 6, 2022
Android Shared preference wrapper than encrypts the values of Shared Preferences. It's not bullet proof security but rather a quick win for incrementally making your android app more secure.

Secure-preferences - Deprecated Please use EncryptedSharedPreferences from androidx.security in preferenced to secure-preference. (There are no active

Scott Alexander-Bown 1.5k Dec 24, 2022
Android Secure SharedPreferences Using Facebook Conceal Encryption

SharedChamber Android Project : SharedChamber on top of SharedPreferences using Facebook Conceal Description Conceal provides a set of Java APIs to pe

Hafiq 95 Nov 25, 2022
Secure Preference Manager for android. It uses various Encryption to protect your application's Shared Preferences.

Secure-Pref-Manager ##Secure Preference Manager is a simple Library to help you protect your Shared Preferences. Secure Preference Manager for android

Prashant Solanki 72 Nov 25, 2022
Simple-Claim-Form - Android App for creating a simple dynamic form with MVVM architecture

Simple-Claim-Form Android App for creating a simple dynamic form with MVVM archi

Shubham Gangpuri 1 Aug 14, 2022
a simple cache for android and java

ASimpleCache ASimpleCache 是一个为android制定的 轻量级的 开源缓存框架。轻量到只有一个java文件(由十几个类精简而来)。 1、它可以缓存什么东西? 普通的字符串、JsonObject、JsonArray、Bitmap、Drawable、序列化的java对象,和 b

Michael Yang 3.7k Dec 14, 2022
Create a simple and more understandable Android logs.

DebugLog Create a simple and more understandable Android logs. #Why? android.util.Log is the most usable library of the Android. But, when the app rel

mf 418 Nov 25, 2022
A simple Android utils library to write any type of data into cache files and read them later.

CacheUtilsLibrary This is a simple Android utils library to write any type of data into cache files and then read them later, using Gson to serialize

Wesley Lin 134 Nov 25, 2022
A simple and easy to use stopwatch and timer library for android

TimeIt Now with Timer support! A simple and easy to use stopwatch and timer library for android Introduction A stopwatch can be a very important widge

Yashovardhan Dhanania 35 Dec 10, 2022
Trail is a simple logging system for Java and Android. Create logs using the same API and the library will detect automatically in which platform the code is running.

Trail Trail is a simple logging system for Java and Android. Create logs using the same API and the library will detect automatically in which platfor

Mauricio Togneri 13 Aug 29, 2022
A Simple Android Library for Kenyan Counties

A Simple Android Library for Kenyan Counties

Joel Kanyi 18 Jul 12, 2022
DiskCache - Simple and readable disk cache for kotlin and android applications

DiskCache Simple and readable disk cache for kotlin and android applications (with journaled lru strategy) This is a simple lru disk cache, based on t

Giovanni Corte 14 Dec 2, 2022
A simple library for validating user input in forms using annotations.

ValidationKomensky for Android A simple library for validating user input in forms using annotations. Features: Validate all views at once and show fe

Inmite s.r.o. 512 Nov 20, 2022
A small library which will save you from writing the same intent creation code again and again for the most simple tasks

Android Intents A small library which will save you from writing the same intent creation code again and again for the most simple tasks. I found myse

MarvinLabs 420 Nov 20, 2022