FlowDroid Static Data Flow Tracker

Overview

FlowDroid Data Flow Analysis Tool

This repository hosts the FlowDroid data flow analysis tool. FlowDroid statically computes data flows in Android apps and Java programs. Its goal is to provide researchers and practitioners with a tool and library on which they can base their own research projects and product implementations. We are happy to see that FlowDroid is now widely used in academia as well as industry.

Obtaining The Tool

You can either build FlowDroid on your own using Maven, or you can download a release from here on Github.

Downloading The Release Via Maven

FlowDroid can now be found on Maven Central. In order to use FlowDroid in your Maven build, include the following in your pom.xml file. We recommend using the latest and greatest version unless you have a specific issue that prevents you from doing so. In that case, please let us know (see contact below).

    <dependencies>
        <dependency>
            <groupId>de.fraunhofer.sit.sse.flowdroid</groupId>
            <artifactId>soot-infoflow</artifactId>
            <version>2.10.0</version>
        </dependency>
        <dependency>
            <groupId>de.fraunhofer.sit.sse.flowdroid</groupId>
            <artifactId>soot-infoflow-summaries</artifactId>
            <version>2.10.0</version>
        </dependency>
        <dependency>
            <groupId>de.fraunhofer.sit.sse.flowdroid</groupId>
            <artifactId>soot-infoflow-android</artifactId>
            <version>2.10.0</version>
        </dependency>
    </dependencies>

For a quick start with FlowDroid, look at "Using The Data Flow Tracker" below. If you only want to use the command-line tool, all you need is the "soot-infoflow-cmd-jar-with-dependencies.jar" file.

Downloading The Release Via GitHub

The Release Page contains all pre-built JAR files for each release that we officially publish. We recommend using the latest and greatest version unless you have a specific issue that prevents you from doing so. In that case, please let us know (see contact below).

For a quick start with FlowDroid, look at "Using The Data Flow Tracker" below. If you only want to use the command-line tool, all you need is the "soot-infoflow-cmd-jar-with-dependencies.jar" file.

Building The Tool With Maven

From version 2.5 on, FlowDroid is built using Maven. Use

EXPORT ANDROID_JARS=<Android JAR folder>
EXPORT DROIDBENCH=<DroidBench folder>
mvn install

to build the tool and run all unit tests. The Android JAR folder is the "platforms" directory inside your Android SDK installation folder. The DroidBench folder is the location of DroidBench, our micro-benchmark suite. These two environment variables are only required for running the unit tests.

If you do not want DroidBench, or are in a hurry and just want to build the tool without the tests (they can take quite some time to complete, we have more than 400 of them), try

mvn -DskipTests install

Either way, you will find the built JAR files in the "target" folder of the respective modules. Maven should take care of all dependencies that are required for the build. Unless you need to build FlowDroid on a machine without an Internet connection, thing should be pretty easy.

Note that our tests runs on Java 8. The tests have not been adapted to newer versions of the JDK yet, so if your system uses a newer version, we recommend that you disable the tests for now.

Building The Tool With Eclipse

We work on FlowDroid using the Eclipse IDE. All modules are Eclipse projects and can be imported into the Eclipse IDE. They will appear as Maven projects there and Eclipse should take care of downloading all required dependencies for you.

Using The Data Flow Tracker

You can use FlowDroid either through its command-line interface (module soot-infoflow-cmd) or as a library. In general, if you would like to implement something and need a data flow tracker as a component, you are better off by integrating the FlowDroid modules as JAR files. If you just need the results quickly, simply run the command-line interface.

FlowDroid is supported on Windows, Mac OS, and Linux.

Running The Command-Line Tool

If you want to use the command-line tool to run the data flow tracker, you can use the following command:

java -jar soot-infoflow-cmd/target/soot-infoflow-cmd-jar-with-dependencies.jar \
    -a <APK File> \
    -p <Android JAR folder> \
    -s <SourcesSinks file>

The Android JAR folder is the "platforms" directory inside your Android SDK installation folder. The definition file for sources and sinks defines what shall be treated as a source of sensitive information and what shall be treated as a sink that can possibly leak sensitive data to the outside world. These definitions are specific to your use case. However, if you are looking for privacy issues, you can use our default file "SourcesAndSinks.txt" in the "soot-infoflow-android" folder as a starting point.

For finding out about the other options of the command-line tool, you can run the tool with the "--help" option or have a look at the MainClass.initializeCommandLineOptions()" method in the source code (module soot-infoflow-cmd).

Configuring FlowDroid for Performance

For some apps, FlowDroid will take very long for large apps. There are various options with which you can configure a tradeoff between performance, precision and recall.

  • -ns Do not track taints on static fields and disregard static initializers.
  • -ne Do not track exceptional flows.

You can also define timeouts:

  • -dt N Aborts the data flow analysis after N seconds and returns the results obtained so far.
  • -ct N Aborts the callback collection during callgraph construction after N seconds and continues with the (incomplete) callgraph constructed so far.
  • -rt N Aborts the result collection after N seconds and returns the results obtained so far.

Note that timeouts are additive. All three stages must complete or run into a timeout for the tool to return and deliver results.

Using FlowDroid as a library

If you want to include FlowDroid as a library into your own solution, you can directly reference the respective JAR files. If you use Maven, you can add FlowDroid as a reference and have Maven resolve all required components. Depending on what you want to analyze (Android apps or Java programs), your dependencies may vary.

In this section, we will collect code and configuration snippets for common tasks with FlowDroid.

Publications

If you want to read the details on how FlowDroid works, the PhD thesis of Steven Arzt is a good place to start.

Contributing to FlowDroid

Contributions are always welcome. FlowDroid is an open source project that we published in the hope that it will be useful to the research community as a whole. If you have a new feature or a bug fix that you would like to see in the official code repository, please open a merge request here on Github and contact us (see below) with a short description of what you have done.

License

FlowDroid is licensed under the LGPL license, see LICENSE file. This basically means that you are free to use the tool (even in commercial, closed-source projects). However, if you extend or modify the tool, you must make your changes available under the LGPL as well. This ensures that we can continue to improve the tool as a community effort.

Contact

If you experience any issues, you can ask for help on the Soot mailing list. You can also contact us at [email protected].

Comments
  • Question about adding multi lib when using soot-inflow-summary

    Question about adding multi lib when using soot-inflow-summary

    soot.jimple.infoflow.methodSummary.Main when I add multi 'toAnalyse' class,such as

    'Android\\Sdk\\platforms\\android-23\\android.jar";
    Sdk\\platforms\\android-23\\data\\layoutlib.jar;" +
    Sdk\\platforms\\android-23\\optional\\org.apache.http.legacy.jar;"
    Sdk\\platforms\\android-23\\uiautomator.jar";'. 
    

    It cause the exception of arraylist unexpected mod count which is a multithread safe exception. I use the absoulute path , not relative path.Above is just an example.

    opened by Yelixing 14
  • Flowdroid cannot analyze some Android apps

    Flowdroid cannot analyze some Android apps

    Hello,

    Flowdroid is a very useful tool. I've been learning how to use flowdroid to generate application‘s function call graph recently. However, I found that the information in the figure below will appear when analyzing some applications, and it will not stop.

    I look forward to your answer to my question. Thank you very much! image

    opened by Connor-fire 13
  • No call graph in Scene (false system classes)

    No call graph in Scene (false system classes)

    Hello @StevenArzt,

    I experienced some analysis with no call graph in Scene with particular apps, I think I found the problem, take a look at this simplified activity declaration :

    <?xml version="1.0" package="com.android.security">
         <application android:debuggable="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name">
             <activity android:label="@string/app_name" android:name=".MainActivity">
             </activity>
         </application>
    </manifest>
    

    We can see that the full name of the activity is "com.android.security.MainActivity"

    Now take a look at checkAndAddComponent method in Flowdroid :

    private void checkAndAddComponent(Set<String> entryPoints, AXmlNode node) {
        AXmlAttribute<?> attrEnabled = node.getAttribute("enabled");
        if (attrEnabled == null || !attrEnabled.getValue().equals(Boolean.FALSE)) {
            AXmlAttribute<?> attr = node.getAttribute("name");
                if (attr != null) {
                    String className = expandClassName((String) attr.getValue());
                    if (!SystemClassHandler.isClassInSystemPackage(className))
                        entryPoints.add(className);
                } else {
                    // This component does not have a name, so this might be
                    // obfuscated malware. We apply a heuristic.
                    for (Entry<String, AXmlAttribute<?>> a : node.getAttributes().entrySet()) {
                        AXmlAttribute<?> attrValue = a.getValue();
                        if (attrValue != null) {
                            String attrValueName = attrValue.getName();
                            if ((attrValueName == null || attrValueName.isEmpty())
                                    && attrValue.getType() == AxmlVisitor.TYPE_STRING) {
                                String name = (String) attrValue.getValue();
                                if (isValidComponentName(name)) {
                                    String expandedName = expandClassName(name);
                                    if (!SystemClassHandler.isClassInSystemPackage(expandedName))
                                        entryPoints.add(expandedName);
                                }
                            }
                        }
                    }
                }
            }
        }
    

    The piece of code we are interested in is this one :

    AXmlAttribute<?> attr = node.getAttribute("name");
        if (attr != null) {
            String className = expandClassName((String) attr.getValue());
            if (!SystemClassHandler.isClassInSystemPackage(className))
                entryPoints.add(className);
        }
    

    attr get the value : name="com.android.security.MainActivity", so it is not null, then className get the value : com.android.security.MainActivity Then a check is performed on this name, this is the code of the check :

    public static boolean isClassInSystemPackage(String className) {
            return className.startsWith("android.") || className.startsWith("java.") || className.startsWith("javax.")
                    || className.startsWith("sun.") || className.startsWith("org.omg.")
                    || className.startsWith("org.w3c.dom.") || className.startsWith("com.google.")
                    || className.startsWith("com.android.");
    }
    

    We clearly see the problem here, it is assumed that if the className startsWith "com.android." it is a system class, so the class is not added as an entrypoint. But in this case, the className startsWith "com.android." as it is equals to "com.android.security.MainActivity" but is not a system class. I think the heuristic is not precise enough.

    It is very likely that in #139 it is the same issue as the main activity of @BushraAloraini app is called "com.google.sample.echo.MainActivity".

    bug 
    opened by JordanSamhi 13
  • Any configuration example for FlowDroid taint analysis on latest version (2.5) ?

    Any configuration example for FlowDroid taint analysis on latest version (2.5) ?

    Hi there,

    I'm currently trying to use the latest version of FlowDroid, which looks very handy and more modular. However, I'm a bit stuck with the new way of setting up a taint analysis programatically with sources and sinks. I think one way to do it is to start with a InfoflowAndroidConfiguration instance, but not sure about all the options…

    Do you have a working example somewhere that I could use as a starting point ? I would like to use it as a library because i'm already using Soot in my program to instrument some methods from apks.

    Thank you in advance :)

    question 
    opened by louison 13
  • Interprocedural data flow analysis for Java programs

    Interprocedural data flow analysis for Java programs

    Hi! First I want to thank you all for developing such a handy tool for flow analysis.

    Since I saw you mentioned FlowDroid is also able to compute data flows for Java programs, just wondering is there any documentation on how to analyse Jar file (from a Java program) solely instead of including an Android JAR? I saw that soot-infoflow was implemented for Java programs but are there any documentation/guide on how to do a pure Java implementation with it? Sorry for the naive question :)

    Thanks a lot!

    opened by tangfy97 12
  • A wrong call graph but pointsTo analysis result is correct

    A wrong call graph but pointsTo analysis result is correct

    Hi @StevenArzt , I found FlowDroid manifest a weird bug on this specific app (apk). It turns out the pointsTo analysis is correct but the call graph is not correct.

    I simplify the inheritance hierarchy that is related to the bug as follows. CycleStreets extends MainNavDrawerActivity, whose method onNewVersion is then overridden by CycleStreets.

    class CycleStreets extends MainNavDrawerActivity {
         protected void onCreate() {
             super.onCreate();
         }
    
         protected void onNewVersion() {...}
    }
    
    abstract class MainNavDrawerActivity {
         protected void onCreate() {
             onNewVersion();
         }
    
         protected void onNewVersion() {...}
    }
    

    Then I print the call graph, the expected result should be

    MainNavDrawerActivity: onCreate() ==> CycleStreets: onNewVersion()
    

    However, the actual output is

    MainNavDrawerActivity: onCreate() ==> MainNavDrawerActivity: onNewVersion()
    

    I also locate the callsite of onNewVersion() and see the pointTo results of the base local (i.e., r0 at virtualinvoke r0.<net.cyclestreets.MainNavDrawerActivity: void onNewVersion()>()). I found the only possible types of r0 is CycleStreets, which means the pointsTo result is correct. In this case, why the call graph is not correct?

    BTW, I also make my own app to simulate this inheritance structure and it looks the call graph is correct. So the bug can only be reproduced on that specific app. Could you take a look at this issue? Thanks in advance!

    opened by RichardHoOoOo 11
  • FlowDroid fails to propagate taint when involving type casting

    FlowDroid fails to propagate taint when involving type casting

    considering this running example:

    public class Case21CastingAfterMapGet {
    
        public static void main(String[] args) {
            Map<String, Object> conf = new HashMap<String, Object>();
            conf.put("mode", 'c');
            conf.put("jobs", 1);
            char mode = (char) (conf.get("mode"));
    
            if (mode == 'c') {
                System.out.println("mode is c");
            }
    
            int jobs = (int) (conf.get("jobs"));
            if (jobs == 1){
                System.out.println("jobs is 1");
            }
        }
    }
    

    the source method signature is "<java.util.Map: java.lang.Object get(java.lang.Object)>" the sink we foucus on is every if statement, so I instrument a dummy sink void sink(Object o) before every if statment, so that i can track if the log shows that [main] WARN No results found. so, the question i wanna know is What causes this?, i found a paper Analyzing Android Taint Analysis Tools: FlowDroid, Amandroid, and DroidSafe described this problem, but without any solution.

    opened by jimmy66688 11
  • [Question] How to get SCC of a CFG and how to get data flow graph for a method?

    [Question] How to get SCC of a CFG and how to get data flow graph for a method?

    Hi @StevenArzt ,

    I'm wondering if there are constructs or sections of code that compute the strongly connected components of a call graph/control flow graph.

    Also is it possible to get the data flow graph for a method?

    Kind regards, Zhijun

    question 
    opened by FrankieYin 11
  • FLOWDROID ERROR - xception in thread

    FLOWDROID ERROR - xception in thread "main" java.lang.NoSuchMethodError: soot.Body.getUnits()Lsoot/PatchingChain;

    I'm trying to use FlowDroid for the first time and keep having an error while doing (on windows):

    java -Xmx4g -cp sootclasses-trunk-jar-with-dependencies.jar;soot-infoflow.jar;soot-infoflow-android.jar;slf4j-api-1.7.5.jar;slf4j-simple-1.7.5.jar;axml-2.0.jar s
    oot.jimple.infoflow.android.TestApps.Test "C:\Users\javie\AndroidStudioProjects\Project\malware\73ddc408b518826064878dfc0064c4cd4fe512c0.apk" C:\Users\javie\AppData\Local\Android\Sdk\platforms
    
    

    Running data flow analysis... Exception in thread "main" java.lang.NoSuchMethodError: soot.Body.getUnits()Lsoot/PatchingChain; at soot.jimple.infoflow.cfg.LibraryClassPatcher.patchHandlerPostBody(LibraryClassPatcher.java:386) at soot.jimple.infoflow.cfg.LibraryClassPatcher.patchHandlerImplementation(LibraryClassPatcher.java:285) at soot.jimple.infoflow.cfg.LibraryClassPatcher.patchLibraries(LibraryClassPatcher.java:44) at soot.jimple.infoflow.android.SetupApplication.initializeSoot(SetupApplication.java:1021) at soot.jimple.infoflow.android.SetupApplication.runInfoflow(SetupApplication.java:1187) at soot.jimple.infoflow.android.SetupApplication.runInfoflow(SetupApplication.java:1160) at soot.jimple.infoflow.android.TestApps.Test.runAnalysis(Test.java:798) at soot.jimple.infoflow.android.TestApps.Test.main(Test.java:249)

    opened by jpuentea 9
  • How to integrate soot-infoflow-android as library using maven?

    How to integrate soot-infoflow-android as library using maven?

    It's my first time to use this tool, and I want to integrate it as part of my project. I tried to add dependency statement into 'pom.xml' file and failed for that the resource doesn't exist in the central repository of maven. After I looked at the Readme of soot project and issue submitted by @xcdu, I added the following code <repositories> <repository> <id>soot-snapshot</id> <name>soot snapshots</name> <url>https://soot-build.cs.uni-paderborn.de/nexus/repository/soot-snapshot/</url> </repository> </repositories> It still goes wrong, with maven's information that ' Failed to transfer file https://soot-build.cs.uni-paderborn.de/nexus/repository/soot-snapshot/de/tud/sse/soot-infoflow-android/2.6.1/soot-infoflow-android-2.6.1.pom with status code 400'. I guess there is still something wrong in my pom file. I have succeed in running flowdoird by downloading soot-infoflow-android, soot-infoflow, soot, heros and jasmin, but it's inconvenience compared with maven style. So I want to know how to simply build it with maven. Thanks.

    opened by singleboat 9
  • Testing FlowDroid

    Testing FlowDroid

    Hello!

    A little background

    I am writing a framework to execute static android security analysis tools, and I would like to inlcude FlowDroid in it to show what it can do!

    Issue

    I have a (small) apk, which I test with to see if my framework works okay. I found that Flowdroid does not work with my test apk:

    [main] ERROR soot.jimple.infoflow.android.SetupApplication$InPlaceInfoflow - No 
    sources found, aborting analysis
    

    My apk is malware, it has sources and sinks, confirmed by multiple analysers. e.g.: I have used IccTa (with IC3), which also uses soot. There, I got a welcoming

    [main] INFO soot.jimple.infoflow.data.pathBuilders.ContextSensitivePathBuilder - Obtainted 3
    connections between sources and sinks
    

    I thought: Maybe it is because of the SourcesSinks definition text file (maybe IccTa uses more fitting source/sink rules for this apk), but: After launching flowdroid with the SourcesSinks-file of IccTa, the error persisted.

    Question

    Do you know, by any chance, how Flowdroid's soot cannot find sources, while IccTa's soot does find them, with the same source (and sink)-definition file?

    With kind regards, Sebastiaan

    opened by Sebastiaan-Alvarez-Rodriguez 8
  • How to get line number of the source code?

    How to get line number of the source code?

    Hi Steven. I'm currently trying to use flowdroid to analyze android apk and give some useful feedback to user. But now I'm having difficult in getting the line number of a certain (jimple) statement. I have tried the code below

    Options.v().set_keep_line_number(true); // soot option
    
    val unit: Unit = /*certain statement*/
    val lineno: Int = (unit.getTag("LineNumberTag") as LineNumberTag).lineNumber
    

    However, the getTag("LineNumberTag") above just return null. So I wonder is the way to get line number in source right? Or you can just offer some examples to get line number of source. Thanks!

    opened by ZephyrusZhang 0
  • Source and sink definition of methods in the MainActivity.java class

    Source and sink definition of methods in the MainActivity.java class

    I wanted to ask if the methods inside the MainActivity class of an apk are not supposed to be defined as a source or a sink. This is because during the taint analysis these types of methods are never recognized as such, despite being declared in the sourcessinks.xml file. Meanwhile, a method in any other class is correctly identified as a source or a sink depending on the xml file definition.

    Thank you.

    opened by NicolasFNino 3
  • Wondering the Relationship between CallGraph and SourceToSInk

    Wondering the Relationship between CallGraph and SourceToSInk

    Hello Arzt:

    I use runInfoflow() to perform taint analysis which also generates a call graph. I want to add a special edge from source method to sink method in the call graph for further malware detection task. Here's an example of what I get.

    $r4 = virtualinvoke $r3.<android.telephony.TelephonyManager: java.lang.String getDeviceId()>() -> $r5 = virtualinvoke $r19.<java.lang.String: java.lang.String replace(java.lang.CharSequence,java.lang.CharSequence)>("UDIDPHONE", $r5),

    But many source and sink methods like android.telephony.TelephonyManager.getDeviceId don't even appear in the call graph. I want to know the reason behind this. Also I want to know how to understand the following sentence:

    The sink <...> in method <...> was called with values from the following sources: - <...>() in method <...>

    What does the word 'in' mean?

    Thank You!

    opened by russwestbrick 10
  • How to measure accurate time required to construct callgraph?

    How to measure accurate time required to construct callgraph?

    Hello @StevenArzt ! FlowDroid by default gives the following: Callgraph construction took 0 seconds // for all the applications being analyzed (a set of 50 different apps) callgraph construction is the same irrespective of the apps being analyzed and callgraph being used. Furthermore, It also gives: Collecting callbacks and building a callgraph took 18 seconds // this time is different for all apps being analyzed and callgraph being used. So, I need to measure the accurate time taken to construct the callgraph. What is the best way to do this? Any suggestion Please!

    opened by neupaneprakash 5
  • Run single Test using Maven

    Run single Test using Maven

    Hi @StevenArzt, I am trying to run a single class test using the next command mvn test -Dtest=soot.jimple.infoflow.test.securibench.AliasingTests in the previous line, I am trying to run a tests from Infloflow folder in its securibench folder (which I imagine are their test) Am I right?

    opened by Jclavo 0
Releases(v2.10)
Owner
Secure Software Engineering Group at Paderborn University and Fraunhofer IEM
Secure Software Engineering Group at Paderborn University and Fraunhofer IEM
StaCoAn is a crossplatform tool which aids developers, bugbounty hunters and ethical hackers performing static code analysis on mobile applications.

StaCoAn Not maintained anymore! Will be archived soon. StaCoAn is a crossplatform tool which aids developers, bugbounty hunters and ethical hackers pe

Vincent Cox 769 Dec 31, 2022
Easy setup of static analysis tools for Android and Java projects.

[DEPRECATED] Gradle static analysis plugin ⚠️ A fork of this project is maintained at https://github.com/GradleUp/static-analysis-plugin/ Please migra

Novoda 408 Dec 19, 2022
Yet another static code analyzer for malicious Android applications

Androwarn Yet another static code analyzer for malicious Android applications Description Androwarn is a tool whose main aim is to detect and warn the

Thomas D. 422 Dec 28, 2022
Sample application to show state management & unidirectional data flow using Jetpack compose.

Jetpack Compose State Management A sample project to demonstrate State Management in Jetpack compose by following This CodeLab. Through the project yo

Rafsan Ahmad 9 Nov 1, 2022
Loop Habit Tracker, a mobile app for creating and maintaining long-term positive habits

Loop is a mobile app that helps you create and maintain good habits, allowing you to achieve your long-term goals. Detailed graphs and statistics show you how your habits improved over time.

Alinson S. Xavier 5.8k Jan 7, 2023
Episodie is a TV show time tracker app with unusual design written in kotlin and clean architecture approach. Get to know how much time you spent watching tv shows.

Episodie Episodie is a TV show time tracker app with unusual design. Get to know how much time you spent watching tv shows. Track easily overall progr

Przemek 126 Dec 7, 2022
Open source Crypto Currency Tracker Android App made fully in Kotlin

CoinBit CoinBit is a beautiful CryptoCurrency app, completely open sourced and 100% in kotlin. It supports following features Track prices of over 300

Pranay Airan 50 Dec 5, 2022
DNS over HTTPS / DNS over Tor / DNSCrypt client, firewall, and connection tracker for Android.

RethinkDNS + Firewall for Android An OpenSnitch-inspired firewall and network monitor + a pi-hole-inspired DNS over HTTPS client with blocklists. In o

null 1.1k Jan 5, 2023
Water tracker app helps you with daily reminder to drink water. This app is just a trial to test and improve my android development skills.

?? About Me I am a self-thaught developer learning web and android development. This app is just a trial to test and improve my android development sk

Sinan Sonmez (Chaush) 28 Dec 17, 2022
A Simple Expense Tracker App 📱 built to demonstrate the use of modern android architecture component with MVVM Architecture

Expenso ?? A Simple Expense Tracker App ?? built to demonstrate the use of modern android architecture component with MVVM Architecture ?? . Made with

Michel Horacio 1 Dec 28, 2022
Time Tracker Application

Time Tracker Application This Application is to serve two purposes. Learning Android Development Tracking Time Technology Language and Libraries Kotli

null 0 Dec 10, 2021
Room : Sleep Quality Tracker app

Room - SleepQualityTracker app This is the toy app for Lesson 6 of the Android App Development in Kotlin course on Udacity. SleepQualityTracker The Sl

Martin 0 Dec 8, 2021
Google map location tracker uploading current to realtime database and displaying location information from firebase realtime.

WEEK-8-SQ009-ANDROID LOCATION - GROUP WORK (2) Problem Description Track your partner(s). Implementation 1: You are to build a map application to show

null 0 Mar 16, 2022
The Sleep tracker app for lesson 6 of the Udacity: Developing Android Apps with Kotlin Course

App Architecture-Presistence This is the Sleep tracker app for lesson 6 of the U

null 0 Dec 28, 2021
NimTome is a Free and open-source spell tracker application for Dungeons and Dragons

Nimtome: An open source application to manage all your spells in D&D About This project came to life as a homework assignment, but it became a lot bit

null 2 Jan 11, 2022
Covid Tracker - Show Details of Corona virus cases of all affected country

Covid_Tracker Based on MVVM Architecture Show Details of Corona virus cases of a

inderjeet yadav 1 Feb 27, 2022
A productivity tracker app published on Google Play

producktivity-tracker A productivity tracker app published on Google Play. Includes Google AdMob and in-app-purchases to disable ads. This project was

null 1 Mar 9, 2022
Self hosted read and to-read list book tracker

JELU Official documentation Like Jelu or find it useful ? Offer me a coffee ☕ Purpose This app main purpose is to track what you have read, what you a

null 181 Dec 28, 2022
Open Source Magic: The Gathering life tracker and companion app

SpellCounter SpellCounter is a free, open source Magic: The Gathering life and counter tracking app Features 100% free with no ads Supports up to 8 pl

Sean Kenkeremath 3 Jul 27, 2022