• Stars
    star
    273
  • Rank 150,780 (Top 3 %)
  • Language
    Java
  • License
    Apache License 2.0
  • Created about 10 years ago
  • Updated over 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

[UNMAINTAINED] Meteor's Distributed Data Protocol (DDP) for clients on Android

Android-DDP

This library implements the Distributed Data Protocol (DDP) from Meteor for clients on Android.

Connect your native Android apps, written in Java, to apps built with the Meteor framework and build real-time features.

Motivation

  • Have you built a web application with Meteor?
    • Using this library, you can build native Android apps that can talk to your Meteor server and web application.
  • Are you primarily an Android developer (who has never heard of Meteor)?
    • With "Android-DDP", you can use a Meteor server as your backend for real-time applications on Android.
  • Doesn't Meteor provide built-in features for Android app development already?
    • With Meteor's built-in features, your Android app will be written in HTML, CSS and JavaScript, wrapped in a WebView. It will not be a native app.
    • By using this library, however, you can write native Android apps in Java while still using Meteor as your real-time backend.

Requirements

  • Android 2.3+

Installation

  • Add this library to your project

    • Declare the Gradle repository in your root build.gradle

      allprojects {
          repositories {
              maven { url "https://jitpack.io" }
          }
      }
    • Declare the Gradle dependency in your app module's build.gradle

      dependencies {
          compile 'com.github.delight-im:Android-DDP:v3.3.1'
      }
  • Add the Internet permission to your app's AndroidManifest.xml:

    <uses-permission android:name="android.permission.INTERNET" />

Usage

  • Creating a new instance of the DDP client

    public class MyActivity extends Activity implements MeteorCallback {
    
        private Meteor mMeteor;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            // ...
    
            // create a new instance
            mMeteor = new Meteor(this, "ws://example.meteor.com/websocket");
    
            // register the callback that will handle events and receive messages
            mMeteor.addCallback(this);
    
            // establish the connection
            mMeteor.connect();
        }
    
        public void onConnect(boolean signedInAutomatically) { }
    
        public void onDisconnect() { }
    
        public void onDataAdded(String collectionName, String documentID, String newValuesJson) {
            // parse the JSON and manage the data yourself (not recommended)
            // or
            // enable a database (see section "Using databases to manage data") (recommended)
        }
    
        public void onDataChanged(String collectionName, String documentID, String updatedValuesJson, String removedValuesJson) {
            // parse the JSON and manage the data yourself (not recommended)
            // or
            // enable a database (see section "Using databases to manage data") (recommended)
        }
    
        public void onDataRemoved(String collectionName, String documentID) {
            // parse the JSON and manage the data yourself (not recommended)
            // or
            // enable a database (see section "Using databases to manage data") (recommended)
        }
    
        public void onException(Exception e) { }
    
        @Override
        public void onDestroy() {
            mMeteor.disconnect();
            mMeteor.removeCallback(this);
            // or
            // mMeteor.removeCallbacks();
    
            // ...
    
            super.onDestroy();
        }
    
    }
  • Singleton access

    • Creating an instance at the beginning

      MeteorSingleton.createInstance(this, "ws://example.meteor.com/websocket")
      // instead of
      // new Meteor(this, "ws://example.meteor.com/websocket")
    • Accessing the instance afterwards (across Activity instances)

      MeteorSingleton.getInstance()
      // instead of
      // mMeteor
    • All other API methods can be called on MeteorSingleton.getInstance() just as you would do on any other Meteor instance, as documented here with mMeteor

  • Registering a callback

    // MeteorCallback callback;
    mMeteor.addCallback(callback);
  • Unregistering a callback

    mMeteor.removeCallbacks();
    // or
    // // MeteorCallback callback;
    // mMeteor.removeCallback(callback);
  • Available data types

    JavaScript / JSON Java / Android
    String (e.g. "John" or 'Jane') String (e.g. "John" or "Jane")
    Number (e.g. 42) byte (e.g. (byte) 42)
    short (e.g. (short) 42)
    int (e.g. 42)
    long (e.g. 42L)
    float (e.g. 3.14f)
    double (e.g. 3.14)
    Boolean (e.g. true) boolean (e.g. true)
    Array (e.g. [ 7, "Hi", true ]) Object[] (e.g. new Object[] { 7, "Hi", true })
    List<Object> (e.g. List<Object> list = new LinkedList<Object>(); list.add(7); list.add("Hi"); list.add(true);)
    Object (e.g. { "amount": 100, "currency": "USD" }) Map<String, Object> (e.g. Map<String, Object> map = new HashMap<String, Object>(); map.put("amount", 100); map.put("currency", "USD");)
    MyClass (e.g. public class MyClass { public int amount; public String currency; } MyClass myObj = new MyClass(); myObj.amount = 100; myObj.currency = "USD";)
    null null
  • Inserting data into a collection

    Map<String, Object> values = new HashMap<String, Object>();
    values.put("_id", "my-id");
    values.put("some-key", "some-value");
    
    mMeteor.insert("my-collection", values);
    // or
    // mMeteor.insert("my-collection", values, new ResultListener() { });
  • Updating data in a collection

    Map<String, Object> query = new HashMap<String, Object>();
    query.put("_id", "my-id");
    
    Map<String, Object> values = new HashMap<String, Object>();
    values.put("some-key", "some-value");
    
    mMeteor.update("my-collection", query, values);
    // or
    // mMeteor.update("my-collection", query, values, options);
    // or
    // mMeteor.update("my-collection", query, values, options, new ResultListener() { });
  • Deleting data from a collection

    mMeteor.remove("my-collection", "my-id");
    // or
    // mMeteor.remove("my-collection", "my-id", new ResultListener() { });
  • Subscribing to data from the server

    String subscriptionId = mMeteor.subscribe("my-subscription");
    // or
    // String subscriptionId = mMeteor.subscribe("my-subscription", new Object[] { arg1, arg2 });
    // or
    // String subscriptionId = mMeteor.subscribe("my-subscription", new Object[] { arg1, arg2 }, new SubscribeListener() { });
  • Unsubscribing from a previously established subscription

    mMeteor.unsubscribe(subscriptionId);
    // or
    // mMeteor.unsubscribe(subscriptionId, new UnsubscribeListener() { });
  • Calling a custom method defined on the server

    mMeteor.call("myMethod");
    // or
    // mMeteor.call("myMethod", new Object[] { arg1, arg2 });
    // or
    // mMeteor.call("myMethod", new ResultListener() { });
    // or
    // mMeteor.call("myMethod", new Object[] { arg1, arg2 }, new ResultListener() { });
  • Disconnect from the server

    mMeteor.disconnect();
  • Creating a new account (requires accounts-password package)

    mMeteor.registerAndLogin("john", "[email protected]", "password", new ResultListener() { });
    // or
    // mMeteor.registerAndLogin("john", "[email protected]", "password", profile, new ResultListener() { });
  • Signing in with an existing username (requires accounts-password package)

    mMeteor.loginWithUsername("john", "password", new ResultListener() { });
  • Signing in with an existing email address (requires accounts-password package)

    mMeteor.loginWithEmail("[email protected]", "password", new ResultListener() { });
  • Check if the client is currently logged in (requires accounts-password package)

    mMeteor.isLoggedIn();
  • Get the client's user ID (if currently logged in) (requires accounts-password package)

    mMeteor.getUserId();
  • Logging out (requires accounts-password package)

    mMeteor.logout();
    // or
    // mMeteor.logout(new ResultListener() { });
  • Checking whether the client is connected

    mMeteor.isConnected();
  • Manually attempt to re-connect (if necessary)

    mMeteor.reconnect();

Using databases to manage data

Enabling a database

Pass an instance of Database to the constructor. Right now, the only subclass provided as a built-in database is InMemoryDatabase. So the code for the constructor becomes:

mMeteor = new Meteor(this, "ws://example.meteor.com/websocket", new InMemoryDatabase());

After that change, all data received from the server will automatically be parsed, updated and managed for you in the built-in database. That means no manual JSON parsing!

So whenever you receive data notifications via onDataAdded, onDataChanged or onDataRemoved, that data has already been merged into the database and can be retrieved from there. In these callbacks, you can thus ignore the parameters containing JSON data and instead get the data from your database.

Accessing the database

Database database = mMeteor.getDatabase();

This method call and most of the following method calls can be chained for simplicity.

Getting a collection from the database by name

// String collectionName = "myCollection";
Collection collection = mMeteor.getDatabase().getCollection(collectionName);

Retrieving the names of all collections from the database

String[] collectionNames = mMeteor.getDatabase().getCollectionNames();

Fetching the number of collections from the database

int numCollections = mMeteor.getDatabase().count();

Getting a document from a collection by ID

// String documentId = "wjQvNQ6sGjzLMDyiJ";
Document document = mMeteor.getDatabase().getCollection(collectionName).getDocument(documentId);

Retrieving the IDs of all documents from a collection

String[] documentIds = mMeteor.getDatabase().getCollection(collectionName).getDocumentIds();

Fetching the number of documents from a collection

int numDocuments = mMeteor.getDatabase().getCollection(collectionName).count();

Querying a collection for documents

Any of the following method calls can be chained and combined in any way to select documents via complex queries.

// String fieldName = "age";
// int fieldValue = 62;
Query query = mMeteor.getDatabase().getCollection(collectionName).whereEqual(fieldName, fieldValue);
// String fieldName = "active";
// int fieldValue = false;
Query query = mMeteor.getDatabase().getCollection(collectionName).whereNotEqual(fieldName, fieldValue);
// String fieldName = "accountBalance";
// float fieldValue = 100000.00f;
Query query = mMeteor.getDatabase().getCollection(collectionName).whereLessThan(fieldName, fieldValue);
// String fieldName = "numChildren";
// long fieldValue = 3L;
Query query = mMeteor.getDatabase().getCollection(collectionName).whereLessThanOrEqual(fieldName, fieldValue);
// String fieldName = "revenue";
// double fieldValue = 0.00;
Query query = mMeteor.getDatabase().getCollection(collectionName).whereGreaterThan(fieldName, fieldValue);
// String fieldName = "age";
// int fieldValue = 21;
Query query = mMeteor.getDatabase().getCollection(collectionName).whereGreaterThanOrEqual(fieldName, fieldValue);
// String fieldName = "address";
Query query = mMeteor.getDatabase().getCollection(collectionName).whereNull(fieldName);
// String fieldName = "modifiedAt";
Query query = mMeteor.getDatabase().getCollection(collectionName).whereNotNull(fieldName);
// String fieldName = "age";
// Integer[] fieldValues = new Integer[] { 60, 70, 80 };
Query query = mMeteor.getDatabase().getCollection(collectionName).whereIn(fieldName, fieldValues);
// String fieldName = "languageCode";
// String[] fieldValues = new String[] { "zh", "es", "en", "hi", "ar" };
Query query = mMeteor.getDatabase().getCollection(collectionName).whereNotIn(fieldName, fieldValues);

Any query can be executed by a find or findOne call. The step of first creating the Query instance can be skipped if you chain the calls to execute the query immediately.

Document[] documents = mMeteor.getDatabase().getCollection(collectionName).find();
// int limit = 30;
Document[] documents = mMeteor.getDatabase().getCollection(collectionName).find(limit);
// int limit = 30;
// int offset = 5;
Document[] documents = mMeteor.getDatabase().getCollection(collectionName).find(limit, offset);
Document document = mMeteor.getDatabase().getCollection(collectionName).findOne();

Chained together, these calls may look as follows, for example:

Document document = mMeteor.getDatabase().getCollection("users").whereNotNull("lastLoginAt").whereGreaterThan("level", 3).findOne();

Getting a field from a document by name

// String fieldName = "age";
Object field = mMeteor.getDatabase().getCollection(collectionName).getDocument(documentId).getField(fieldName);

Retrieving the names of all fields from a document

String[] fieldNames = mMeteor.getDatabase().getCollection(collectionName).getDocument(documentId).getFieldNames();

Fetching the number of fields from a document

int numFields = mMeteor.getDatabase().getCollection(collectionName).getDocument(documentId).count();

Contributing

All contributions are welcome! If you wish to contribute, please create an issue first so that your feature, problem or question can be discussed.

Dependencies

Further reading

Disclaimer

This project is neither affiliated with nor endorsed by Meteor.

License

Copyright (c) delight.im <[email protected]>

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.

More Repositories

1

Android-AdvancedWebView

Enhanced WebView component for Android that works as intended out of the box
Java
2,387
star
2

FreeGeoDB

Free database of geographic place names and corresponding geospatial data
PHP
1,586
star
3

HTML-Sheets-of-Paper

Word processor in your browser using HTML and CSS (for invoices, legal notices, etc.)
CSS
1,208
star
4

PHP-Auth

Authentication for PHP. Simple, lightweight and secure.
PHP
1,073
star
5

Faceless

[UNMAINTAINED] Faceless is where you can talk freely
Java
488
star
6

ShortURL

Bijective conversion between natural numbers (IDs) and short strings
C
381
star
7

PHP-PrivacyPolicy

Programmatically composable privacy policies for humans and machines
PHP
257
star
8

Android-SimpleLocation

Utility class for easy access to the device location on Android
Java
198
star
9

Knowledge

Random pieces of knowledge โ€” with anecdotes and quotes
189
star
10

PHP-Cookie

Modern cookie management for PHP
PHP
165
star
11

MovieContentFilter

Watch movies with the freedom (not) to filter
PHP
142
star
12

Emoji

[UNMAINTAINED] Emoji (Unicode) and emoticon support for Java and Android
Java
95
star
13

AppRater

Android library that lets you prompt users to rate your application on their appstore (e.g. Google Play)
Java
75
star
14

Android-Languages

Custom language selection and access to language names for Android
Java
74
star
15

PHP-Str

Convenient object-oriented operations on strings
PHP
70
star
16

Android-Commons

[UNMAINTAINED] Reusable components and utilities for Android
Java
69
star
17

AndroidPatternLock

List of all combinations for the Android pattern lock
Java
69
star
18

PHP-FileUpload

Simple and convenient file uploads โ€” secure by default
PHP
63
star
19

PHP-I18N

Internationalization and localization for PHP
PHP
57
star
20

Javadoc-to-Markdown

[UNMAINTAINED] Generate Markdown from your Javadoc, PHPDoc or JSDoc comments
JavaScript
56
star
21

JS-NeuralNetwork

Neural networks in JavaScript. Well-documented and object-oriented.
JavaScript
56
star
22

OpenSoccer

[UNMAINTAINED] Online Soccer Manager
PHP
51
star
23

PHP-DB

Safe and convenient SQL database access in a driver-agnostic way
PHP
47
star
24

Localize

[UNMAINTAINED] Collaborative Translation for Android
PHP
46
star
25

PHP-Router

Router for PHP. Simple, lightweight and convenient.
PHP
38
star
26

Android-Audio

High-level library for efficient playback of sounds and music on Android
Java
35
star
27

htaccess

.htaccess with reasonable defaults for most sites
ApacheConf
29
star
28

PHP-Foundation

Writing modern PHP applications efficiently
Shell
29
star
29

PHP-IDs

Short, obfuscated and efficient IDs for PHP
PHP
27
star
30

Secure-Firefox

Hardening Mozilla Firefox for maximum privacy and security
27
star
31

Android-Identicons

[UNMAINTAINED] Identicons for Android โ€” turn any data into a visual hash
Java
23
star
32

PHP-Random

The most convenient way to securely generate anything random in PHP
PHP
22
star
33

PHP-GitScraper

Downloads entire Git repositories from publicly accessible ".git" folders over HTTP
PHP
20
star
34

PHP-HTTP

Hypertext Transfer Protocol (HTTP) utilities for PHP
PHP
18
star
35

Android-Countries

Provides country codes in accordance with ISO-3166-1 and localized names for each country
Java
18
star
36

PHP-Base64

Simple and convenient Base64 encoding and decoding for PHP
PHP
15
star
37

PHP-BaseConvert

Conversion of arbitrarily large numbers between any two bases or alphabets
PHP
15
star
38

NationSoccer

[UNMAINTAINED] Free 1-vs-1 soccer game for Android
Java
14
star
39

PHP-Temporal

Immutable date and time for PHP with a convenient interface
PHP
13
star
40

Java-Shapefile-Parser

Parses ESRI shapefiles and extracts all spatial/geometric data with attributes
Java
11
star
41

Android-WebRequest

Fluent interface for easy HTTP requests to web servers (GET, POST, PUT or DELETE)
Java
11
star
42

Android-Time

Library for displaying locale-specific time in Android
Java
10
star
43

Android-Tasks

[UNMAINTAINED] Helper classes for recurring and automatic tasks in Android
Java
9
star
44

AndroidDrawableResizer

[UNMAINTAINED] Automatic resizing of Android drawables from one density to all others
PHP
8
star
45

Java-Crash-ID

Generates unique fingerprints for crashes on Android and the JVM
Java
8
star
46

AndroidEmoji-PNG

[UNMAINTAINED] Android emoji from AndroidEmoji.ttf as single icons in PNG format
PHP
8
star
47

Android-KeyValueSpinner

Spinner component that works with normal values but additionally lets you use keys of an arbitrary class
Java
7
star
48

AndroidImageScraper

Extracts all image URLs from a given website ordered by file size
Java
7
star
49

MusikPlayer

Simple Music Player for Windows/Linux/Mac
Java
6
star
50

PHP-Foundation-Core

Core of โ€œPHP-Foundationโ€
PHP
6
star
51

Android-InfiniteScrolling

Easily add infinite scrolling to ListView or GridView instances in Android
Java
5
star
52

2048

Fork of the popular game "2048"
CSS
5
star
53

Tools-for-Spotify

Tools and utilities for Spotify using the Spotify Web API
PHP
5
star
54

PHP-Alphabets

Sets of digits or characters that may be used for base conversions, encoding and decoding tasks, and input validation
PHP
4
star
55

Weather

Current weather data and hourly weather forecasts
PHP
4
star
56

JS-AbstractStorage

Flexible data storage for JavaScript backed by the Web Storage API
JavaScript
3
star
57

Maintenance

Simple and effective maintenance page for websites
PHP
3
star
58

Android-Monkey

[UNMAINTAINED] Library that generates pseudo-random streams of user input for Android apps
Java
3
star
59

JS-MediaPlayer

Convenient media playback with powerful controls in JavaScript
JavaScript
3
star
60

JS-PRNG

Pseudorandom number generator (PRNG) for JavaScript
JavaScript
2
star
61

2FA-Backup-Sheet

Create backup sheets for any service where you use two-factor authentication (2FA)
Shell
2
star
62

Batch-Renamer

Platform-independent utility for renaming batches of files
PHP
2
star
63

News60

Simple news aggregator and Twitter charts
PHP
2
star
64

PHP-OTP

One-time password (OTP) implementation for two-factor authentication with TOTP in accordance with RFC 6238 and RFC 4226
PHP
2
star
65

Requests

Logging and analysis of requests with optional static responses and redirects
Shell
2
star
66

Simple-ACRA-Storage

[UNMAINTAINED] Simple storage system for crash reports from ACRA on Android
PHP
2
star
67

Twitter-Charts-DE-AT-CH

Inofficial Twitter charts for Germany, Austria and Switzerland
1
star
68

Social-News-Germany

500 most-shared pieces from German online newspapers (March '13 โ€” May '14)
1
star