Blockcerts Android application by Learning Machine
Gradle allows us to define different product variants. Each has a separate app id and can be installed simultaneously. Currently they all use the Bitcoin main net and do not differ all that much. Production has an empty logging tree.
dev
- App id:
com.learningmachine.android.app.dev
- Dimension:
env
- App id:
staging
- App id:
com.learningmachine.android.app.staging
- Dimension:
env
- App id:
production
- App id:
com.learningmachine.android.app
- Dimension:
env
- App id:
sh scripts/run_tests.sh
At the time of writing it seems Robolectric is not compatible with JDK > 13 (robolectric/robolectric#5863)
sh scripts/GenerateReleaseBuild.command
Answer the prompts as they come.
Blockcerts team members: password is stored in regular password manager.
The following are guidelines for this Android project.
- Naming
- Suffix with the type of class:
Activity
,Fragment
,Listener
,ListItemView
,Manager
- Prefix member variables with
m
. - If a variable is a view, consider suffixing with the type:
mPasswordEditText
,mLoginButton
- Boolean member variables should reflect state (
mLocked
) and have getters usingisState()
(ie:isLocked
)
- Suffix with the type of class:
- Extract common elements to a superclass to avoid duplication.
- Prefer
abstract
methods in super over implicit setup in subclass constructors. - The suggested template below should guide naming:
public class TemplateFragment {
private static final String ARG_CONSTANT = "TemplateFragment.Constant";
private List<Object> mObjects;
/* static methods */
public static TemplateFragment newInstance() {
return new TemplateFragment();
}
/* lifecycle overrides, onSavedInstanceState, options menu, onActivityResult */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mObjects = new ArrayList<Object>();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
// databinding & init
initView();
}
/* private methods */
private void initView() {}
private void setupData() {}
/* getters, setters, and other public methods */
public List<Object> getObjects() {
return mObjects;
}
public void setObjects(List<Objects> objects) {
mObjects = objects;
}
/* enums */
protected enum ObjectItemType {
ITEM_TYPE_A,
ITEM_TYPE_B,
}
/* inner classes */
private class TemplateListAdapter extends ArrayAdapter<ObjectItemType> {
public EnergyListAdapter(List<ObjectItemType> items) {
super(getActivity(), 0, items);
}
}
/* base class overrides */
@Override
protected boolean usesInjection() {
return true;
}
}
We suggest the following method orgainization:
- newInstance and other static methods
- lifecycle, onSavedInstanceState, options menu, onActivityResult
- private methods
- all other protected methods (including immediate parent overrides)
- all other public methods(including immediate parent overrides)
- enums
- defined interfaces
- inner classes
- base overrides
- Naming
- Reverse DNS style.
- Prefix with the type of layout:
activity_login
,fragment_login
,list_item_login
- Describe widgets and suffix with the type:
login_username_text_view
- Use auto format for consistency.
- Prefer
/>
over open and close tags that do not contain children. - Extract strings and dimensions to their respective xml resources.
0dp
is an exception and should remain in the layout file. - Use styles when possible.
- id's should come first for easy element identification, and be on a new line. Enable
Preferences > Code Style > XML > Android > Insert Line break before first attribute
to help format your layout files properly.
- Naming
- Describe where it is used:
fragment_login_username_hint
- For long strings, append
_message
: "We would like to welcome you to this app because it is amazing" becomesfragment_login_welcome_message
- If error, append
_error_message
: "Failed to login" would belogin_error_message
- Describe where it is used:
- Formatted strings
- Use the recommended pattern:
%1$s
- Use the correct type for the data it will be formatting:
s
,d
,f
, etc.
- Use the recommended pattern:
-
Responsibilities
- Loading and providing data
- Creating success and failure callbacks
- Fetching / pushing data from / to the
WebService
-
Prefix data operations with
load
, this signifies an asynchronous call (i.e. webservice or database) -
Prefix direct data accessors with
get
. These methods will synchronously return data directly to the caller.
- Controllers (i.e. Activities and Fragments) should never access Stores directly. All requests to load or get data should be relayed through a Manager.
- We like and make extensive use of these.
- They are a great way to enforce implementation of something a calling class may need.
- Javascript library for verifying Blockcerts Certificates
Pull down the cvjs repository:
https://github.com/blockchain-certificates/cert-verifier-js.git && cd cert-verifier-js
CVJS requires an npm token, so create one on npm
export NPM_TOKEN={insert token here}
Install
npm install
Generate build
npm run-script build
Copy content of /dist/verifier-iife.js
Paste in this android project at this location: wallet-android/LearningMachine/app/src/main/assets/www/verifier.js
- Utility to convert urls found in HTML into links
- Minified javascript included as a static asset in the
www
directory of the app - MIT
- Java implementation of the Bitcoin protocol
- Forked by uniquid to allow creation of wallets with arbitrary path (e.g m/44'/0'/0/0)
- Apache License
- Simple Logging Facade for Java
- Required by BitcoinJ
- MIT
- Repackage of Bouncy Castle for Android
- Required by BitcoinJ
- MIT X11
- Google's language-neutral, platform-neutral, extensible mechanism for serializing structured data
- Required by BitcoinJ
- License
- Dependency injection framework
- Apache 2.0
- A logger with a small, extensible API which provides utility on top of Android's normal Log class
- Apache 2.0
- A version of Joda-Time built with Android in mind
- Apache 2.0
- A type-safe REST client for Android and Java
- Apache 2.0
- An HTTP+HTTP/2 client for Android and Java applications
- Apache 2.0
- JSON object converter and parser
- Apache 2.0
- RxJava bindings for Android
- Apache 2.0
- Automatically complete sequences based on a second lifecycle stream
- Apache 2.0
- A set of lint checks that check your RxJava code
- Apache 2.0
- Image loading and caching
- Apache 2.0
- Google Core Libraries for Java
- Apache 2.0
- A simple framework to write repeatable tests.
- Eclipse Public License - v 1.0
- Tasty mocking framework for unit tests in Java
- MIT
- Unit testing framework
- MIT
- A quality replacement for the Java date and time classes
- Required for unit tests
- Apache 2.0
Contact us at the Blockcerts community forum.