From 98ceec15c89beaa0892a2c982e70c1ab6a70a254 Mon Sep 17 00:00:00 2001 From: Alexander Date: Wed, 15 Aug 2018 14:39:38 +0300 Subject: [PATCH] First commit --- app/build.gradle | 104 +++--- app/release/output.json | 1 + .../1.json | 313 ++++++++++++++++++ app/src/main/AndroidManifest.xml | 24 +- .../bitshareswallet/BalancesFragment.java | 39 +-- .../bitshareswallet/BitsharesApplication.java | 35 +- .../bitshareswallet/ExchangeFragment.java | 31 +- .../bitshareswallet/ImportActivty.java | 2 +- .../bitshareswallet/LockActivity.java | 102 ++++++ .../bitshareswallet/MainActivity.java | 249 +++++++------- .../bitshareswallet/ModelSelectActivity.java | 56 ++-- .../bitshareswallet/PinSetFragment.java | 185 +++++++++++ .../bitshareswallet/PinSettingsFragment.java | 42 +++ .../bitshareswallet/ReceiveFragment.java | 57 ++++ .../bitshareswallet/ScannerFragment.java | 122 +++++++ .../bitshareswallet/SendFragment.java | 272 +++++++-------- .../bitshareswallet/SettingsActivity.java | 11 +- .../bitshareswallet/SettingsFragment.java | 23 +- .../bitshareswallet/SignUpButtonActivity.java | 29 +- .../TransactionSellBuyFragment.java | 53 +-- .../bitshareswallet/TransactionsFragment.java | 28 +- .../bitshareswallet/WalletFragment.java | 81 +---- .../repository/MarketTickerRepository.java | 13 +- .../bitshares/bitshareswallet/util/Safe.java | 15 + .../viewmodel/SellBuyViewModel.java | 8 +- .../viewmodel/WalletViewModel.java | 6 +- .../wallet/BitsharesWalletWraper.java | 10 +- .../wallet/graphene/chain/fee_schedule.java | 7 +- .../bitshareswallet/wallet/wallet_api.java | 27 +- .../bitshareswallet/wallet/websocket_api.java | 5 +- app/src/main/res/drawable/camera_rear.xml | 9 + app/src/main/res/drawable/dot_filled_dark.xml | 5 + app/src/main/res/drawable/flash.xml | 9 + app/src/main/res/drawable/flash_off.xml | 9 + app/src/main/res/drawable/ic_delete.xml | 9 + app/src/main/res/drawable/qrcode_scan.xml | 9 + app/src/main/res/layout/activity_lock.xml | 54 +++ app/src/main/res/layout/activity_settings.xml | 5 - app/src/main/res/layout/fragment_camera.xml | 42 +++ app/src/main/res/layout/fragment_pin_set.xml | 44 +++ app/src/main/res/layout/fragment_receive.xml | 37 +++ app/src/main/res/layout/fragment_send.xml | 18 +- app/src/main/res/layout/fragment_wallet.xml | 3 - .../main/res/menu/navigation_drawer_menu.xml | 4 +- app/src/main/res/values-ru/strings.xml | 19 ++ app/src/main/res/values/strings.xml | 13 + app/src/main/res/xml/preferences.xml | 5 + app/src/main/res/xml/preferences_pin.xml | 13 + build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 +- settings.gradle | 2 +- 51 files changed, 1593 insertions(+), 672 deletions(-) create mode 100644 app/release/output.json create mode 100644 app/schemas/com.bitshares.bitshareswallet.room.BitsharesDatabase/1.json create mode 100644 app/src/main/java/com/bitshares/bitshareswallet/LockActivity.java create mode 100644 app/src/main/java/com/bitshares/bitshareswallet/PinSetFragment.java create mode 100644 app/src/main/java/com/bitshares/bitshareswallet/PinSettingsFragment.java create mode 100644 app/src/main/java/com/bitshares/bitshareswallet/ReceiveFragment.java create mode 100644 app/src/main/java/com/bitshares/bitshareswallet/ScannerFragment.java create mode 100644 app/src/main/java/com/bitshares/bitshareswallet/util/Safe.java create mode 100644 app/src/main/res/drawable/camera_rear.xml create mode 100644 app/src/main/res/drawable/dot_filled_dark.xml create mode 100644 app/src/main/res/drawable/flash.xml create mode 100644 app/src/main/res/drawable/flash_off.xml create mode 100644 app/src/main/res/drawable/ic_delete.xml create mode 100644 app/src/main/res/drawable/qrcode_scan.xml create mode 100644 app/src/main/res/layout/activity_lock.xml create mode 100644 app/src/main/res/layout/fragment_camera.xml create mode 100644 app/src/main/res/layout/fragment_pin_set.xml create mode 100644 app/src/main/res/layout/fragment_receive.xml create mode 100644 app/src/main/res/xml/preferences_pin.xml diff --git a/app/build.gradle b/app/build.gradle index 9913e3b..e1acdef 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,28 +1,33 @@ buildscript { repositories { - maven { url 'https://maven.fabric.io/public' } + jcenter() + google() + //maven { url 'https://maven.fabric.io/public' } } - dependencies { - classpath 'io.fabric.tools:gradle:1.+' + classpath 'com.android.tools.build:gradle:3.1.4' + classpath 'io.sentry:sentry-android-gradle-plugin:1.7.5' + //classpath 'io.fabric.tools:gradle:1.+' } } apply plugin: 'com.android.application' -apply plugin: 'io.fabric' +apply plugin: 'io.sentry.android.gradle' +//apply plugin: 'io.fabric' repositories { - maven { url 'https://maven.fabric.io/public' } + jcenter() maven { url "https://jitpack.io" } google() + //maven { url 'https://maven.fabric.io/public' } } android { - compileSdkVersion 26 - buildToolsVersion '26.0.2' + compileSdkVersion 27 + buildToolsVersion '28.0.2' defaultConfig { applicationId "com.bitshares.bitshareswallet" minSdkVersion 15 - targetSdkVersion 25 + targetSdkVersion 27 versionCode 10201001 versionName "1.2.1.1" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -87,46 +92,55 @@ android { } dependencies { - compile fileTree(include: ['*.jar'], dir: 'libs') - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + implementation fileTree(include: ['*.jar'], dir: '../libs') + + androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) - compile('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') { - transitive = true; - } - compile 'com.android.support:multidex:1.0.2' - compile 'com.android.support:appcompat-v7:26.1.0' - compile 'com.android.support.constraint:constraint-layout:1.0.2' - compile 'com.android.support:support-v4:26.1.0' - compile 'com.android.support:preference-v7:26.1.0' - compile 'com.android.support:preference-v14:26.1.0' - compile 'com.android.support:design:26.1.0' - compile 'com.google.guava:guava:23.0-android' - compile 'com.madgag.spongycastle:core:1.56.0.0' - compile 'com.madgag.spongycastle:prov:1.56.0.0' - compile 'com.madgag.spongycastle:pkix:1.51.0.0' - compile 'com.madgag.spongycastle:pg:1.51.0.0' - compile 'org.slf4j:slf4j-android:1.7.25' - compile 'com.google.protobuf:protobuf-java:3.4.0' - compile 'com.squareup.okhttp3:okhttp:3.9.0' - compile 'com.fasterxml.jackson.core:jackson-databind:2.5.1' - compile 'com.google.code.gson:gson:2.8.1' - compile 'com.kaopiz:kprogresshud:1.0.2' - compile 'com.wang.avi:library:2.1.3' - compile 'com.google.firebase:firebase-core:11.4.2' - compile 'com.github.PhilJay:MPAndroidChart:v3.0.2' - compile 'com.squareup.retrofit2:retrofit:2.3.0' - compile 'com.squareup.retrofit2:converter-gson:2.3.0' - compile 'com.jakewharton:butterknife:8.8.1' + + implementation 'io.sentry:sentry-android:1.7.5' + //implementation "ch.acra:acra-http:5.1.3" + implementation 'com.android.support:appcompat-v7:27.0.2' + implementation 'com.android.support.constraint:constraint-layout:1.1.2' + implementation 'com.android.support:support-v4:27.0.2' + implementation 'com.android.support:preference-v7:27.0.2' + implementation 'com.android.support:preference-v14:27.0.2' + implementation 'com.android.support:design:27.0.2' + implementation 'com.google.guava:guava:23.0-android' + implementation 'com.madgag.spongycastle:core:1.56.0.0' + implementation 'com.madgag.spongycastle:prov:1.56.0.0' + implementation 'com.madgag.spongycastle:pkix:1.51.0.0' + implementation 'com.madgag.spongycastle:pg:1.51.0.0' + implementation 'org.slf4j:slf4j-android:1.7.25' + implementation 'com.google.protobuf:protobuf-java:3.4.0' + implementation 'com.squareup.okhttp3:okhttp:3.11.0' + implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.5' + implementation 'com.google.code.gson:gson:2.8.2' + implementation 'com.kaopiz:kprogresshud:1.0.2' + implementation 'com.wang.avi:library:2.1.3' + implementation 'com.github.PhilJay:MPAndroidChart:v3.0.2' + implementation 'com.squareup.retrofit2:retrofit:2.3.0' + implementation 'com.squareup.retrofit2:converter-gson:2.3.0' + implementation 'com.jakewharton:butterknife:8.8.1' annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' - implementation 'android.arch.persistence.room:runtime:1.0.0-rc1' - annotationProcessor "android.arch.persistence.room:compiler:1.0.0-rc1" - implementation 'android.arch.lifecycle:extensions:1.0.0-rc1' - annotationProcessor "android.arch.lifecycle:compiler:1.0.0-rc1" - testCompile 'junit:junit:4.12' + implementation 'android.arch.persistence.room:runtime:1.1.1' + annotationProcessor "android.arch.persistence.room:compiler:1.1.1" + implementation 'android.arch.lifecycle:extensions:1.1.1' + annotationProcessor "android.arch.lifecycle:compiler:1.1.1" + testImplementation 'junit:junit:4.12' implementation 'io.reactivex.rxjava2:rxjava:2.1.5' implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' - implementation project(':graphenej:graphenej') -} + implementation 'me.dm7.barcodescanner:zxing:1.9.8' + implementation 'com.andrognito.pinlockview:pinlockview:2.1.0' + //implementation 'com.github.atomfrede:jadenticon:2.0.0' + //implementation project(':graphenej:graphenej') + implementation 'com.github.bilthon:graphenej:0.4.2' -apply plugin: 'com.google.gms.google-services' \ No newline at end of file + /*implementation('com.crashlytics.sdk.android:answers:1.4.2@aar') { + transitive = true; + } + + implementation('com.crashlytics.sdk.android:crashlytics:2.9.4@aar') { + transitive = true; + }*/ +} diff --git a/app/release/output.json b/app/release/output.json new file mode 100644 index 0000000..239bfae --- /dev/null +++ b/app/release/output.json @@ -0,0 +1 @@ +[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":10201001,"versionName":"1.2.1.1","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] \ No newline at end of file diff --git a/app/schemas/com.bitshares.bitshareswallet.room.BitsharesDatabase/1.json b/app/schemas/com.bitshares.bitshareswallet.room.BitsharesDatabase/1.json new file mode 100644 index 0000000..ad7dcdd --- /dev/null +++ b/app/schemas/com.bitshares.bitshareswallet.room.BitsharesDatabase/1.json @@ -0,0 +1,313 @@ +{ + "formatVersion": 1, + "database": { + "version": 1, + "identityHash": "50adca5ce42c2b4860616029d4324041", + "entities": [ + { + "tableName": "balance", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `amount` INTEGER NOT NULL, `currency` TEXT, `asset_id` TEXT, `type` INTEGER NOT NULL, `precision` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "amount", + "columnName": "amount", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "currency", + "columnName": "currency", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "asset_id", + "columnName": "asset_id", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "precision", + "columnName": "precision", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_balance_asset_id_type", + "unique": true, + "columnNames": [ + "asset_id", + "type" + ], + "createSql": "CREATE UNIQUE INDEX `index_balance_asset_id_type` ON `${TABLE_NAME}` (`asset_id`, `type`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "market_ticker", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `base` TEXT, `quote` TEXT, `latest` REAL, `lowest_ask` REAL, `highest_bid` REAL, `percent_change` TEXT, `base_volume` REAL, `quote_volume` REAL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "marketTicker.base", + "columnName": "base", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "marketTicker.quote", + "columnName": "quote", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "marketTicker.latest", + "columnName": "latest", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "marketTicker.lowest_ask", + "columnName": "lowest_ask", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "marketTicker.highest_bid", + "columnName": "highest_bid", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "marketTicker.percent_change", + "columnName": "percent_change", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "marketTicker.base_volume", + "columnName": "base_volume", + "affinity": "REAL", + "notNull": false + }, + { + "fieldPath": "marketTicker.quote_volume", + "columnName": "quote_volume", + "affinity": "REAL", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_market_ticker_base_quote", + "unique": true, + "columnNames": [ + "base", + "quote" + ], + "createSql": "CREATE UNIQUE INDEX `index_market_ticker_base_quote` ON `${TABLE_NAME}` (`base`, `quote`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "asset_object", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `asset_id` TEXT, `symbol` TEXT, `precision` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "asset_id", + "columnName": "asset_id", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "symbol", + "columnName": "symbol", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "precision", + "columnName": "precision", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_asset_object_asset_id_symbol", + "unique": true, + "columnNames": [ + "asset_id", + "symbol" + ], + "createSql": "CREATE UNIQUE INDEX `index_asset_object_asset_id_symbol` ON `${TABLE_NAME}` (`asset_id`, `symbol`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "operation_history", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `timestamp` INTEGER NOT NULL, `history_id` TEXT, `op` TEXT, `block_num` INTEGER, `trx_in_block` INTEGER, `op_in_trx` INTEGER, `virtual_op` INTEGER)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "operationHistoryObject.id", + "columnName": "history_id", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "operationHistoryObject.op", + "columnName": "op", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "operationHistoryObject.block_num", + "columnName": "block_num", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "operationHistoryObject.trx_in_block", + "columnName": "trx_in_block", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "operationHistoryObject.op_in_trx", + "columnName": "op_in_trx", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "operationHistoryObject.virtual_op", + "columnName": "virtual_op", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_operation_history_timestamp_history_id", + "unique": true, + "columnNames": [ + "timestamp", + "history_id" + ], + "createSql": "CREATE UNIQUE INDEX `index_operation_history_timestamp_history_id` ON `${TABLE_NAME}` (`timestamp`, `history_id`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "account_object", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `account_id` TEXT, `name` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "account_id", + "columnName": "account_id", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_account_object_account_id_name", + "unique": true, + "columnNames": [ + "account_id", + "name" + ], + "createSql": "CREATE UNIQUE INDEX `index_account_object_account_id_name` ON `${TABLE_NAME}` (`account_id`, `name`)" + } + ], + "foreignKeys": [] + } + ], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"50adca5ce42c2b4860616029d4324041\")" + ] + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 470ec8d..9bb4586 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,7 +2,9 @@ + + @@ -18,11 +20,6 @@ android:launchMode="singleTask" android:screenOrientation="portrait" android:windowSoftInputMode="adjustPan"> - - - - - - - @@ -54,9 +47,20 @@ android:name=".AboutActivity" android:screenOrientation="portrait" android:theme="@style/ActivityTheme" /> - + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/bitshares/bitshareswallet/BalancesFragment.java b/app/src/main/java/com/bitshares/bitshareswallet/BalancesFragment.java index 28e3ca0..4c24b25 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/BalancesFragment.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/BalancesFragment.java @@ -28,14 +28,6 @@ * create an instance of this fragment. */ public class BalancesFragment extends BaseFragment { - // TODO: Rename parameter arguments, choose names that match - // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER - private static final String ARG_PARAM1 = "param1"; - private static final String ARG_PARAM2 = "param2"; - - // TODO: Rename and change types of parameters - private String mParam1; - private String mParam2; private BalancesAdapter mBalancesAdapter; @@ -52,11 +44,11 @@ class BalanceItemViewHolder extends RecyclerView.ViewHolder { public BalanceItemViewHolder(View itemView) { super(itemView); view = itemView; - viewNumber = (TextView) itemView.findViewById(R.id.textViewNumber); - viewUnit = (TextView) itemView.findViewById(R.id.textViewUnit); - viewEqual = (TextView) itemView.findViewById(R.id.textViewEqual); - viewConvertNumber = (TextView) itemView.findViewById(R.id.textViewNumber2); - viewConvertUnit = (TextView) itemView.findViewById(R.id.textViewUnit2); + viewNumber = itemView.findViewById(R.id.textViewNumber); + viewUnit = itemView.findViewById(R.id.textViewUnit); + viewEqual = itemView.findViewById(R.id.textViewEqual); + viewConvertNumber = itemView.findViewById(R.id.textViewNumber2); + viewConvertUnit = itemView.findViewById(R.id.textViewUnit2); } } @@ -110,31 +102,14 @@ public BalancesFragment() { // Required empty public constructor } - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @param param1 Parameter 1. - * @param param2 Parameter 2. - * @return A new instance of fragment BalancesFragment. - */ - // TODO: Rename and change types and number of parameters - public static BalancesFragment newInstance(String param1, String param2) { + public static BalancesFragment newInstance() { BalancesFragment fragment = new BalancesFragment(); - Bundle args = new Bundle(); - args.putString(ARG_PARAM1, param1); - args.putString(ARG_PARAM2, param2); - fragment.setArguments(args); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (getArguments() != null) { - mParam1 = getArguments().getString(ARG_PARAM1); - mParam2 = getArguments().getString(ARG_PARAM2); - } } @Override @@ -167,7 +142,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_balances, container, false); - RecyclerView recyclerView = (RecyclerView)view.findViewById(R.id.recyclerView); + RecyclerView recyclerView = view.findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); mBalancesAdapter = new BalancesAdapter(); recyclerView.setAdapter(mBalancesAdapter); diff --git a/app/src/main/java/com/bitshares/bitshareswallet/BitsharesApplication.java b/app/src/main/java/com/bitshares/bitshareswallet/BitsharesApplication.java index 493e77c..e328cc4 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/BitsharesApplication.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/BitsharesApplication.java @@ -1,24 +1,22 @@ package com.bitshares.bitshareswallet; +import android.app.Application; import android.arch.persistence.room.Room; -import android.support.multidex.MultiDexApplication; import com.bitshares.bitshareswallet.room.BitsharesDatabase; -import com.crashlytics.android.Crashlytics; import org.spongycastle.jce.provider.BouncyCastleProvider; import java.security.Security; -import io.fabric.sdk.android.Fabric; +import io.sentry.Sentry; +import io.sentry.android.AndroidSentryClientFactory; - -public class BitsharesApplication extends MultiDexApplication { +//@AcraCore(buildConfigClass = BuildConfig.class, reportFormat = StringFormat.JSON) +//@AcraHttpSender(uri = "https://collector.tracepot.com/e05fd60d", httpMethod = HttpSender.Method.POST) +public class BitsharesApplication extends Application { private static BitsharesApplication theApp; private BitsharesDatabase bitsharesDatabase; - /* - * 是否需要把涨跌的颜色互换 - */ public static BitsharesApplication getInstance() { return theApp; } @@ -34,7 +32,24 @@ public BitsharesDatabase getBitsharesDatabase() { @Override public void onCreate() { super.onCreate(); - Fabric.with(this, new Crashlytics()); + //Fabric.with(this, new Answers(), new Crashlytics()); + /*CoreConfigurationBuilder builder = new CoreConfigurationBuilder(this) + .setBuildConfigClass(BuildConfig.class) + .setReportFormat(StringFormat.JSON); + builder.getPluginConfigurationBuilder(HttpSenderConfigurationBuilder.class) + .setUri("http://95.179.134.24:5984/acra-bitshares/_design/acra-storage/_update/report") + .setHttpMethod(HttpSender.Method.POST) + .setBasicAuthLogin("bitshares_reporter") + .setBasicAuthPassword("yUofei783Jh0lseg94Qw") + .setEnabled(true); + + ACRA.init(this, builder);*/ + + //ACRA.init(this); + + String sentryDsn = "https://f7a95030510e4047ae1f7463327395b4@sentry.io/1261657"; + Sentry.init(sentryDsn, new AndroidSentryClientFactory(this)); + Security.insertProviderAt(new BouncyCastleProvider(), 1); bitsharesDatabase = Room.databaseBuilder( @@ -42,7 +57,5 @@ public void onCreate() { BitsharesDatabase.class, "bitshares.db" ).build(); - - // 注册回调,保证数据更新 } } diff --git a/app/src/main/java/com/bitshares/bitshareswallet/ExchangeFragment.java b/app/src/main/java/com/bitshares/bitshareswallet/ExchangeFragment.java index 1c95231..81ff6fd 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/ExchangeFragment.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/ExchangeFragment.java @@ -20,14 +20,6 @@ * create an instance of this fragment. */ public class ExchangeFragment extends BaseFragment { - // TODO: Rename parameter arguments, choose names that match - // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER - private static final String ARG_PARAM1 = "param1"; - private static final String ARG_PARAM2 = "param2"; - - // TODO: Rename and change types of parameters - private String mParam1; - private String mParam2; private OnFragmentInteractionListener mListener; private ViewPager mViewPager; @@ -35,35 +27,16 @@ public class ExchangeFragment extends BaseFragment { private BtsFragmentPageAdapter mExchangeFragmentPageAdapter; private OrdersFragment mOrdersFragment; - public ExchangeFragment() { - // Required empty public constructor - } + public ExchangeFragment() {} - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @param param1 Parameter 1. - * @param param2 Parameter 2. - * @return A new instance of fragment ExchangeFragment. - */ - // TODO: Rename and change types and number of parameters - public static ExchangeFragment newInstance(String param1, String param2) { + public static ExchangeFragment newInstance() { ExchangeFragment fragment = new ExchangeFragment(); - Bundle args = new Bundle(); - args.putString(ARG_PARAM1, param1); - args.putString(ARG_PARAM2, param2); - fragment.setArguments(args); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (getArguments() != null) { - mParam1 = getArguments().getString(ARG_PARAM1); - mParam2 = getArguments().getString(ARG_PARAM2); - } } @Override diff --git a/app/src/main/java/com/bitshares/bitshareswallet/ImportActivty.java b/app/src/main/java/com/bitshares/bitshareswallet/ImportActivty.java index 0d8d876..7a94058 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/ImportActivty.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/ImportActivty.java @@ -179,7 +179,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { private void processImport(final String strAccount, final String strPassword, final String strVariant) { - final TextView textView = (TextView) findViewById(R.id.textViewErrorInfo); + final TextView textView = findViewById(R.id.textViewErrorInfo); new Thread(new Runnable() { @Override public void run() { diff --git a/app/src/main/java/com/bitshares/bitshareswallet/LockActivity.java b/app/src/main/java/com/bitshares/bitshareswallet/LockActivity.java new file mode 100644 index 0000000..6bb0844 --- /dev/null +++ b/app/src/main/java/com/bitshares/bitshareswallet/LockActivity.java @@ -0,0 +1,102 @@ +package com.bitshares.bitshareswallet; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.support.v4.content.ContextCompat; +import android.support.v7.app.AppCompatActivity; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.widget.Toast; + +import com.andrognito.pinlockview.IndicatorDots; +import com.andrognito.pinlockview.PinLockListener; +import com.andrognito.pinlockview.PinLockView; +import com.bitshares.bitshareswallet.util.Safe; +import com.bitshares.bitshareswallet.wallet.BitsharesWalletWraper; +import com.bitshares.bitshareswallet.wallet.fc.crypto.sha256_object; + +public class LockActivity extends AppCompatActivity { + + private SharedPreferences preferences; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + BitsharesWalletWraper bitsharesWalletWraper = BitsharesWalletWraper.getInstance(); + + if (bitsharesWalletWraper.load_wallet_file() != 0 || bitsharesWalletWraper.is_new()){ + Intent intent = new Intent(this, SignUpButtonActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_ANIMATION); + startActivity(intent); + finish(); + } else { + preferences = getSharedPreferences("data", Context.MODE_PRIVATE); + if(!preferences.contains("val")) { + Intent intent = new Intent(this, MainActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_ANIMATION); + startActivity(intent); + finish(); + } else { + setContentView(R.layout.activity_lock); + + String strName = bitsharesWalletWraper.get_account().name; + + sha256_object.encoder encoder = new sha256_object.encoder(); + encoder.write(strName.getBytes()); + + WebView webViewFrom = findViewById(R.id.webViewAvatarFrom); + loadWebView(webViewFrom, 85, encoder.result().toString()); + + PinLockView mPinLockView = findViewById(R.id.pin_lock_view); + IndicatorDots mIndicatorDots = findViewById(R.id.indicator_dots); + + mPinLockView.attachIndicatorDots(mIndicatorDots); + mPinLockView.setPinLockListener(new PinLockListener() { + @Override + public void onComplete(String pin) { + if (checkPin(pin)) { + Intent intent = new Intent(LockActivity.this, MainActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); + startActivity(intent); + finish(); + } else { + mPinLockView.resetPinLockView(); + Toast.makeText(LockActivity.this, R.string.incorrect_pin, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onEmpty() { } + + @Override + public void onPinChange(int pinLength, String intermediatePin) { } + }); + + mPinLockView.setPinLength(6); + mPinLockView.setShowDeleteButton(true); + mPinLockView.setTextColor(ContextCompat.getColor(this, R.color.white)); + + mIndicatorDots.setIndicatorType(IndicatorDots.IndicatorType.FILL_WITH_ANIMATION); + } + } + } + + private boolean checkPin(String pin) { + String val = preferences.getString("val", null); + if(val != null) { + return Safe.encryptDecrypt(val, new char[]{'B','I','T','S','H','A','R','E'}).equals(pin); + } + return false; + } + + private void loadWebView(WebView webView, int size, String encryptText) { + String htmlShareAccountName = ""; + WebSettings webSettings = webView.getSettings(); + webSettings.setJavaScriptEnabled(true); + webView.loadData(htmlShareAccountName, "text/html", "UTF-8"); + } + +} diff --git a/app/src/main/java/com/bitshares/bitshareswallet/MainActivity.java b/app/src/main/java/com/bitshares/bitshareswallet/MainActivity.java index e1ab7b0..16c1f47 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/MainActivity.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/MainActivity.java @@ -5,31 +5,26 @@ import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; import android.content.res.Resources; import android.net.Uri; -import android.os.Handler; +import android.os.Bundle; import android.support.annotation.NonNull; import android.support.design.widget.BottomNavigationView; import android.support.design.widget.NavigationView; +import android.support.v4.app.Fragment; import android.support.v4.content.LocalBroadcastManager; -import android.support.v4.media.session.PlaybackStateCompat; import android.support.v4.view.GravityCompat; import android.support.v4.view.ViewPager; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBarDrawerToggle; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; import android.support.v7.app.AppCompatDelegate; import android.support.v7.preference.PreferenceManager; import android.support.v7.widget.Toolbar; import android.util.Pair; -import android.view.MenuItem; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.webkit.WebSettings; @@ -49,11 +44,13 @@ import com.bitshares.bitshareswallet.wallet.fc.crypto.sha256_object; import com.bitshares.bitshareswallet.wallet.graphene.chain.signed_transaction; import com.bitshares.bitshareswallet.wallet.graphene.chain.utils; + import java.util.List; import io.reactivex.Flowable; import io.reactivex.schedulers.Schedulers; - +import io.sentry.Sentry; +import io.sentry.event.UserBuilder; public class MainActivity extends AppCompatActivity @@ -77,7 +74,6 @@ public class MainActivity extends AppCompatActivity private TextView mTxtTitle; private LinearLayout mLayoutTitle; private BottomNavigationView mBottomNavigation; - private Handler mHandler = new Handler(); private static final int REQUEST_CODE_SETTINGS = 1; @@ -126,26 +122,28 @@ private void setTitleVisible(boolean visible){ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + account_object account = BitsharesWalletWraper.getInstance().get_account(); + Sentry.getContext().setUser(new UserBuilder() + .setUsername(account.name) + .setId(account.id.toString()) + .withData("pin", getSharedPreferences("data", Context.MODE_PRIVATE).contains("val")) + .build()); + rasingColorRevers = getResources().getConfiguration().locale.getCountry().equals("CN"); setContentView(R.layout.activity_main); - mToolbar = (Toolbar) findViewById(R.id.toolbar); + mToolbar = findViewById(R.id.toolbar); setSupportActionBar(mToolbar); mToolbar.setTitle(""); - // Toolbar的标题文本不支持居中,故创建了新文本 - mLayoutTitle = (LinearLayout) mToolbar.findViewById(R.id.lay_title); - mTxtTitle = (TextView) mToolbar.findViewById(R.id.txt_bar_title); + + mLayoutTitle = mToolbar.findViewById(R.id.lay_title); + mTxtTitle = mToolbar.findViewById(R.id.txt_bar_title); updateTitle(); setTitleVisible(false); - mLayoutTitle.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - processChooseCurency(); - } - }); + mLayoutTitle.setOnClickListener(v -> processChooseCurency()); - mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer); + mDrawerLayout = findViewById(R.id.drawer); mActionBarDrawerToggle = new ActionBarDrawerToggle( this, mDrawerLayout, @@ -156,13 +154,13 @@ public void onClick(View v) { mDrawerLayout.addDrawerListener(mActionBarDrawerToggle); mActionBarDrawerToggle.syncState(); - mViewPager = (NonScrollViewPager) findViewById(R.id.viewPager); + mViewPager = findViewById(R.id.viewPager); mMainFragmentPageAdapter = new BtsFragmentPageAdapter(getSupportFragmentManager()); - mWalletFragment = WalletFragment.newInstance("",""); + mWalletFragment = WalletFragment.newInstance(); mQuotationFragment = QuotationFragment.newInstance(); - mExchangeFragment = ExchangeFragment.newInstance("", ""); + mExchangeFragment = ExchangeFragment.newInstance(); mMainFragmentPageAdapter.addFragment(mWalletFragment, "Wallet"); mMainFragmentPageAdapter.addFragment(mQuotationFragment, "Quotation"); @@ -193,28 +191,24 @@ public void onPageScrollStateChanged(int state) { } }); - NavigationView navigationView = (NavigationView)findViewById(R.id.navigation_view); - navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { - @Override - public boolean onNavigationItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case R.id.logout: - processLogout(); - break; - case R.id.settings: - Intent intentSettings = new Intent(MainActivity.this, SettingsActivity.class); - //startActivity(intent); - startActivityForResult(intentSettings, REQUEST_CODE_SETTINGS); - break; - case R.id.about: - Intent intentAbout = new Intent(MainActivity.this, AboutActivity.class); - startActivity(intentAbout); - break; - } - - mDrawerLayout.closeDrawer(GravityCompat.START); - return false; + NavigationView navigationView = findViewById(R.id.navigation_view); + navigationView.setNavigationItemSelectedListener(item -> { + switch (item.getItemId()) { + case R.id.logout: + processLogout(); + break; + case R.id.settings: + Intent intentSettings = new Intent(MainActivity.this, SettingsActivity.class); + startActivityForResult(intentSettings, REQUEST_CODE_SETTINGS); + break; + case R.id.about: + Intent intentAbout = new Intent(MainActivity.this, AboutActivity.class); + startActivity(intentAbout); + break; } + + mDrawerLayout.closeDrawer(GravityCompat.START); + return false; }); WalletViewModel walletViewModel = ViewModelProviders.of(this).get(WalletViewModel.class); @@ -223,58 +217,45 @@ public boolean onNavigationItemSelected(@NonNull MenuItem item) { walletViewModel.changeCurrency(strCurrency); - if (BitsharesWalletWraper.getInstance().load_wallet_file() != 0 || - BitsharesWalletWraper.getInstance().is_new() == true ){ - Intent intent = new Intent(this, SignUpButtonActivity.class); - startActivity(intent); - finish(); - } else { - final account_object accountObject = BitsharesWalletWraper.getInstance().get_account(); - if (accountObject != null) { - View view = navigationView.getHeaderView(0); - TextView textViewAccountName = (TextView)view.findViewById(R.id.textViewAccountName); - textViewAccountName.setText(accountObject.name); - - sha256_object.encoder encoder = new sha256_object.encoder(); - encoder.write(accountObject.name.getBytes()); - - WebView webView = (WebView)view.findViewById(R.id.webViewAvatar); - loadWebView(webView, 70, encoder.result().toString()); - - TextView textViewAccountId = (TextView)view.findViewById(R.id.textViewAccountId); - textViewAccountId.setText("#" + accountObject.id.get_instance()); - - view.findViewById(R.id.textViewCopyAccount).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - ClipboardManager clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); - ClipData clipData = ClipData.newPlainText("account name", accountObject.name); - clipboardManager.setPrimaryClip(clipData); - Toast toast = Toast.makeText(MainActivity.this, "Copy Successfully", Toast.LENGTH_SHORT); - toast.show(); - } - }); - } + final account_object accountObject = BitsharesWalletWraper.getInstance().get_account(); + if (accountObject != null) { + View view = navigationView.getHeaderView(0); + TextView textViewAccountName = view.findViewById(R.id.textViewAccountName); + textViewAccountName.setText(accountObject.name); + + sha256_object.encoder encoder = new sha256_object.encoder(); + encoder.write(accountObject.name.getBytes()); + + WebView webView = view.findViewById(R.id.webViewAvatar); + loadWebView(webView, 70, encoder.result().toString()); + + TextView textViewAccountId = view.findViewById(R.id.textViewAccountId); + textViewAccountId.setText("#" + accountObject.id.get_instance()); + + view.findViewById(R.id.textViewCopyAccount).setOnClickListener(v -> { + ClipboardManager clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); + ClipData clipData = ClipData.newPlainText("account name", accountObject.name); + clipboardManager.setPrimaryClip(clipData); + Toast toast = Toast.makeText(MainActivity.this, "Copy Successfully", Toast.LENGTH_SHORT); + toast.show(); + }); } - mBottomNavigation = (BottomNavigationView) findViewById(R.id.navigation_bottom); - mBottomNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { - @Override - public boolean onNavigationItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()){ - case R.id.navigation_wallet: - mViewPager.setCurrentItem(0, true); - return true; - case R.id.navigation_quotation: - mViewPager.setCurrentItem(1, true); - return true; - case R.id.navigation_exchange: - mViewPager.setCurrentItem(2, true); - return true; - } - return false; + mBottomNavigation = findViewById(R.id.navigation_bottom); + mBottomNavigation.setOnNavigationItemSelectedListener(item -> { + switch (item.getItemId()){ + case R.id.navigation_wallet: + mViewPager.setCurrentItem(0, true); + return true; + case R.id.navigation_quotation: + mViewPager.setCurrentItem(1, true); + return true; + case R.id.navigation_exchange: + mViewPager.setCurrentItem(2, true); + return true; } + return false; }); QuotationViewModel viewModel = ViewModelProviders.of(this).get(QuotationViewModel.class); @@ -316,6 +297,16 @@ public void notifyCurrencyPairChange() { onCurrencyUpdate(); } + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + List fragments = getSupportFragmentManager().getFragments(); + if (fragments != null) { + for (Fragment fragment : fragments) { + fragment.onRequestPermissionsResult(requestCode, permissions, grantResults); + } + } + } public static void hideSoftKeyboard(View view, Context context) { if (view != null && context != null) { @@ -341,33 +332,25 @@ private void loadWebView(WebView webView, int size, String encryptText) { private void processLogout() { AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); - builder.setPositiveButton(R.string.log_out_dialog_confirm_button, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - Flowable.just(0) - .subscribeOn(Schedulers.io()) - .map(integer -> { - BitsharesDao bitsharesDao = BitsharesApplication.getInstance().getBitsharesDatabase().getBitsharesDao();; - List bitsharesAssetList = bitsharesDao.queryBalanceList(); - List bitsharesOperationHistoryList = bitsharesDao.queryOperationHistoryList(); - bitsharesDao.deleteBalance(bitsharesAssetList); - bitsharesDao.deleteOperationHistory(bitsharesOperationHistoryList); - - return 0; - }).subscribe(); - - BitsharesWalletWraper.getInstance().reset(); - Intent intent = new Intent(MainActivity.this, SignUpButtonActivity.class); - startActivity(intent); - finish(); - } - }); - builder.setNegativeButton(R.string.log_out_dialog_cancel_button, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - - } + builder.setPositiveButton(R.string.log_out_dialog_confirm_button, (dialog, which) -> { + Flowable.just(0) + .subscribeOn(Schedulers.io()) + .map(integer -> { + BitsharesDao bitsharesDao = BitsharesApplication.getInstance().getBitsharesDatabase().getBitsharesDao();; + List bitsharesAssetList = bitsharesDao.queryBalanceList(); + List bitsharesOperationHistoryList = bitsharesDao.queryOperationHistoryList(); + bitsharesDao.deleteBalance(bitsharesAssetList); + bitsharesDao.deleteOperationHistory(bitsharesOperationHistoryList); + + return 0; + }).subscribe(); + + BitsharesWalletWraper.getInstance().reset(); + Intent intent = new Intent(MainActivity.this, SignUpButtonActivity.class); + startActivity(intent); + finish(); }); + builder.setNegativeButton(R.string.log_out_dialog_cancel_button, null); builder.setMessage(R.string.log_out_dialog_message); builder.show(); @@ -387,27 +370,19 @@ private void processChooseCurency(){ break; } } - dialogBuilder.setSingleChoiceItems(R.array.quotation_currency_pair_options, currSelectIndex, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - prefs.edit(). - putString("quotation_currency_pair", arrValues[which]) - .apply(); - String strAsset[] = arrValues[which].split(":"); - QuotationViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(QuotationViewModel.class); - viewModel.selectedMarketTicker(new Pair(strAsset[1], strAsset[0])); - - onCurrencyUpdate(); - } + dialogBuilder.setSingleChoiceItems(R.array.quotation_currency_pair_options, currSelectIndex, (dialog, which) -> { + dialog.dismiss(); + prefs.edit(). + putString("quotation_currency_pair", arrValues[which]) + .apply(); + String strAsset[] = arrValues[which].split(":"); + QuotationViewModel viewModel = ViewModelProviders.of(MainActivity.this).get(QuotationViewModel.class); + viewModel.selectedMarketTicker(new Pair(strAsset[1], strAsset[0])); + + onCurrencyUpdate(); }); - dialogBuilder.setPositiveButton(R.string.log_out_dialog_cancel_button, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } - }); + dialogBuilder.setPositiveButton(R.string.log_out_dialog_cancel_button, null); dialogBuilder.show(); } diff --git a/app/src/main/java/com/bitshares/bitshareswallet/ModelSelectActivity.java b/app/src/main/java/com/bitshares/bitshareswallet/ModelSelectActivity.java index 83a2dc1..56647cc 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/ModelSelectActivity.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/ModelSelectActivity.java @@ -1,10 +1,9 @@ package com.bitshares.bitshareswallet; import android.content.Intent; -import android.support.v7.app.AppCompatActivity; import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; -import android.view.View; public class ModelSelectActivity extends AppCompatActivity { private Toolbar mToolbar; @@ -14,51 +13,34 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_model_select); - mToolbar = (Toolbar) findViewById(R.id.toolbar); + mToolbar = findViewById(R.id.toolbar); setSupportActionBar(mToolbar); - mToolbar.setNavigationOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - finish(); - } - }); + mToolbar.setNavigationOnClickListener(v -> finish()); getSupportActionBar().setDisplayHomeAsUpEnabled(true); - findViewById(R.id.textViewAccountModel).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(ModelSelectActivity.this, ImportActivty.class); - intent.putExtra("model", ImportActivty.ACCOUNT_MODEL); - startActivity(intent); - } + findViewById(R.id.textViewAccountModel).setOnClickListener(v -> { + Intent intent = new Intent(ModelSelectActivity.this, ImportActivty.class); + intent.putExtra("model", ImportActivty.ACCOUNT_MODEL); + startActivity(intent); }); - findViewById(R.id.textViewWalletModelWifKey).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(ModelSelectActivity.this, ImportActivty.class); - intent.putExtra("model", ImportActivty.WALLET_MODEL_WIF_KEY); - startActivity(intent); - } + findViewById(R.id.textViewWalletModelWifKey).setOnClickListener(v -> { + Intent intent = new Intent(ModelSelectActivity.this, ImportActivty.class); + intent.putExtra("model", ImportActivty.WALLET_MODEL_WIF_KEY); + startActivity(intent); }); - findViewById(R.id.textViewWalletModelBin).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(ModelSelectActivity.this, ImportActivty.class); - intent.putExtra("model", ImportActivty.WALLET_MODEL_BIN_FILE); - startActivity(intent); - } + findViewById(R.id.textViewWalletModelBin).setOnClickListener(v -> { + Intent intent = new Intent(ModelSelectActivity.this, ImportActivty.class); + intent.putExtra("model", ImportActivty.WALLET_MODEL_BIN_FILE); + startActivity(intent); }); - findViewById(R.id.textViewWalletModelBrainKey).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(ModelSelectActivity.this, ImportActivty.class); - intent.putExtra("model", ImportActivty.WALLET_MODEL_BRAIN_KEY); - startActivity(intent); - } + findViewById(R.id.textViewWalletModelBrainKey).setOnClickListener(v -> { + Intent intent = new Intent(ModelSelectActivity.this, ImportActivty.class); + intent.putExtra("model", ImportActivty.WALLET_MODEL_BRAIN_KEY); + startActivity(intent); }); } } diff --git a/app/src/main/java/com/bitshares/bitshareswallet/PinSetFragment.java b/app/src/main/java/com/bitshares/bitshareswallet/PinSetFragment.java new file mode 100644 index 0000000..807d2d2 --- /dev/null +++ b/app/src/main/java/com/bitshares/bitshareswallet/PinSetFragment.java @@ -0,0 +1,185 @@ +package com.bitshares.bitshareswallet; + + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toast; + +import com.andrognito.pinlockview.IndicatorDots; +import com.andrognito.pinlockview.PinLockListener; +import com.andrognito.pinlockview.PinLockView; +import com.bitshares.bitshareswallet.util.Safe; + +public class PinSetFragment extends Fragment { + + public static final byte SET = 0; + public static final byte REMOVE = 1; + public static final byte CHANGE = 2; + + private static final String ARG_MODE = "MODE"; + + private SharedPreferences preferences; + + private byte mode; + private byte step = 0; + private String temp; + + public PinSetFragment() {} + + public static PinSetFragment newInstance(byte mode) { + PinSetFragment fragment = new PinSetFragment(); + Bundle args = new Bundle(); + args.putByte(ARG_MODE, mode); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (getArguments() != null) { + mode = getArguments().getByte(ARG_MODE); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View fragmentView = inflater.inflate(R.layout.fragment_pin_set, container, false); + + preferences = getActivity().getSharedPreferences("data", Context.MODE_PRIVATE); + + PinLockView pinLockView = fragmentView.findViewById(R.id.pin_lock_view); + IndicatorDots indicatorDots = fragmentView.findViewById(R.id.indicator_dots); + + pinLockView.attachIndicatorDots(indicatorDots); + + pinLockView.setPinLength(6); + pinLockView.setShowDeleteButton(true); + + indicatorDots.setIndicatorType(IndicatorDots.IndicatorType.FILL_WITH_ANIMATION); + + TextView textView = fragmentView.findViewById(R.id.textView); + + switch (mode) { + case SET: + textView.setText(R.string.pin_enter_new); + pinLockView.setPinLockListener(new PinLockListener() { + @Override + public void onComplete(String pin) { + pinLockView.resetPinLockView(); + if(step == 0) { + temp = pin; + textView.setText(R.string.pin_confirm_new); + step = 1; + } else if(step == 1) { + if(pin.equals(temp)) { + temp = null; + preferences.edit().putString("val", Safe.encryptDecrypt(pin, new char[]{'B','I','T','S','H','A','R','E'})).apply(); + Toast.makeText(getActivity(), R.string.pin_save_success, Toast.LENGTH_SHORT).show(); + getActivity().getSupportFragmentManager().popBackStack(); + } else { + Toast.makeText(getActivity(), R.string.incorrect_pin, Toast.LENGTH_SHORT).show(); + textView.setText(R.string.pin_enter_new); + step = 0; + } + } + } + + @Override + public void onEmpty() { } + + @Override + public void onPinChange(int pinLength, String intermediatePin) { } + }); + break; + case REMOVE: + textView.setText(R.string.pin_enter_current); + pinLockView.setPinLockListener(new PinLockListener() { + @Override + public void onComplete(String pin) { + if (checkPin(pin)) { + preferences.edit().remove("val").apply(); + Toast.makeText(getActivity(), R.string.pin_delete_success, Toast.LENGTH_SHORT).show(); + getActivity().getSupportFragmentManager().popBackStack(); + } else { + pinLockView.resetPinLockView(); + Toast.makeText(getActivity(), R.string.incorrect_pin, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onEmpty() { } + + @Override + public void onPinChange(int pinLength, String intermediatePin) { } + }); + break; + case CHANGE: + textView.setText(R.string.pin_enter_current); + pinLockView.setPinLockListener(new PinLockListener() { + @Override + public void onComplete(String pin) { + if (checkPin(pin) || step != 0) { + pinLockView.resetPinLockView(); + switch (step) { + case 0: + textView.setText(R.string.pin_enter_new); + step = 1; + break; + case 1: + temp = pin; + textView.setText(R.string.pin_confirm_new); + step = 2; + break; + case 2: + if(pin.equals(temp)) { + temp = null; + preferences.edit().putString("val", Safe.encryptDecrypt(pin, new char[]{'B','I','T','S','H','A','R','E'})).apply(); + Toast.makeText(getActivity(), R.string.pin_edit_success, Toast.LENGTH_SHORT).show(); + getActivity().getSupportFragmentManager().popBackStack(); + } else { + Toast.makeText(getActivity(), R.string.incorrect_pin, Toast.LENGTH_SHORT).show(); + textView.setText(R.string.pin_enter_new); + step = 1; + } + break; + default: + break; + } + + } else { + pinLockView.resetPinLockView(); + Toast.makeText(getActivity(), R.string.incorrect_pin, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onEmpty() { } + + @Override + public void onPinChange(int pinLength, String intermediatePin) { } + }); + break; + default: + break; + } + + return fragmentView; + } + + private boolean checkPin(String pin) { + String val = preferences.getString("val", null); + if(val != null) { + return Safe.encryptDecrypt(val, new char[]{'B','I','T','S','H','A','R','E'}).equals(pin); + } + return false; + } + +} diff --git a/app/src/main/java/com/bitshares/bitshareswallet/PinSettingsFragment.java b/app/src/main/java/com/bitshares/bitshareswallet/PinSettingsFragment.java new file mode 100644 index 0000000..f3c64c7 --- /dev/null +++ b/app/src/main/java/com/bitshares/bitshareswallet/PinSettingsFragment.java @@ -0,0 +1,42 @@ +package com.bitshares.bitshareswallet; + + +import android.content.Context; +import android.os.Bundle; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceFragmentCompat; +import android.support.v14.preference.SwitchPreference; + +public class PinSettingsFragment extends PreferenceFragmentCompat { + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.preferences_pin, rootKey); + + + SwitchPreference switchPreference = (SwitchPreference) findPreference("pin_switch"); + Preference preference = findPreference("pin_set"); + + boolean status = getActivity().getSharedPreferences("data", Context.MODE_PRIVATE).contains("val"); + switchPreference.setChecked(status); + preference.setVisible(status); + + switchPreference.setOnPreferenceChangeListener((pref, newValue) -> { + boolean enabled = (Boolean) newValue; + preference.setVisible(enabled); + + if(enabled) { + getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, PinSetFragment.newInstance(PinSetFragment.SET)).addToBackStack(null).commit(); + } else { + getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, PinSetFragment.newInstance(PinSetFragment.REMOVE)).addToBackStack(null).commit(); + } + + return true; + }); + + preference.setOnPreferenceClickListener(pref -> { + getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, PinSetFragment.newInstance(PinSetFragment.CHANGE)).addToBackStack(null).commit(); + return true; + }); + } +} diff --git a/app/src/main/java/com/bitshares/bitshareswallet/ReceiveFragment.java b/app/src/main/java/com/bitshares/bitshareswallet/ReceiveFragment.java new file mode 100644 index 0000000..929bd71 --- /dev/null +++ b/app/src/main/java/com/bitshares/bitshareswallet/ReceiveFragment.java @@ -0,0 +1,57 @@ +package com.bitshares.bitshareswallet; + + +import android.graphics.Bitmap; +import android.graphics.Color; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import com.bitshares.bitshareswallet.wallet.BitsharesWalletWraper; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.WriterException; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.qrcode.QRCodeWriter; + +public class ReceiveFragment extends BaseFragment { + + public ReceiveFragment() {} + + public static ReceiveFragment newInstance() { + return new ReceiveFragment(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View fragmentView = inflater.inflate(R.layout.fragment_receive, container, false); + + ImageView qrView = fragmentView.findViewById(R.id.qrImageView); + + QRCodeWriter writer = new QRCodeWriter(); + try { + BitMatrix bitMatrix = writer.encode(BitsharesWalletWraper.getInstance().get_account().name, BarcodeFormat.QR_CODE, 1000, 1000); + int width = bitMatrix.getWidth(); + int height = bitMatrix.getHeight(); + Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + bmp.setPixel(x, y, bitMatrix.get(x, y) ? Color.parseColor("#263d70") : Color.WHITE); + } + } + qrView.setImageBitmap(bmp); + + } catch (WriterException e) { + e.printStackTrace(); + } + + return fragmentView; + } + +} diff --git a/app/src/main/java/com/bitshares/bitshareswallet/ScannerFragment.java b/app/src/main/java/com/bitshares/bitshareswallet/ScannerFragment.java new file mode 100644 index 0000000..63a0694 --- /dev/null +++ b/app/src/main/java/com/bitshares/bitshareswallet/ScannerFragment.java @@ -0,0 +1,122 @@ +package com.bitshares.bitshareswallet; + +import android.graphics.drawable.Drawable; +import android.media.Ringtone; +import android.media.RingtoneManager; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.support.v4.app.Fragment; +import android.support.v4.content.ContextCompat; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.Toast; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.Result; + +import java.util.ArrayList; +import java.util.List; + +import me.dm7.barcodescanner.zxing.ZXingScannerView; + +public class ScannerFragment extends Fragment implements ZXingScannerView.ResultHandler { + + private OnResultListener listener = null; + + private boolean mFlash = false; + private int mCameraId = 0; + + private ZXingScannerView mScannerView; + private ImageView flashView; + + private Drawable flashOn; + private Drawable flashOff; + + public static ScannerFragment newInstance() { + return new ScannerFragment(); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) { + View fragmentView = inflater.inflate(R.layout.fragment_camera, container, false); + mScannerView = fragmentView.findViewById(R.id.cameraView); + flashView = fragmentView.findViewById(R.id.flashAction); + + flashOn = ContextCompat.getDrawable(getActivity(), R.drawable.flash); + flashOff = ContextCompat.getDrawable(getActivity(), R.drawable.flash_off); + + mScannerView.setAspectTolerance(0.5f); + + List formats = new ArrayList<>(); + formats.add(BarcodeFormat.QR_CODE); + if(mScannerView != null) { + mScannerView.setFormats(formats); + } + + mScannerView.setResultHandler(this); + mScannerView.startCamera(mCameraId); + mScannerView.setFlash(mFlash); + mScannerView.setAutoFocus(true); + + + fragmentView.findViewById(R.id.switchAction).setOnClickListener(v -> { + mCameraId = ~mCameraId+2; + mFlash = false; + flashView.setImageDrawable(flashOff); + + mScannerView.startCamera(mCameraId); + mScannerView.setFlash(mFlash); + mScannerView.setAutoFocus(true); + }); + + + flashView.setOnClickListener(v -> { + mFlash = !mFlash; + flashView.setImageDrawable(mFlash ? flashOn : flashOff); + mScannerView.setFlash(mFlash); + }); + + return fragmentView; + } + + public void setOnResultListener(OnResultListener listener) { + this.listener = listener; + } + + @Override + public void onPause() { + super.onPause(); + mScannerView.stopCamera(); + } + + @Override + public void onResume() { + super.onResume(); + mScannerView.setResultHandler(this); + mScannerView.startCamera(mCameraId); + mScannerView.setFlash(mFlash); + mScannerView.setAspectTolerance(0.5f); + mScannerView.setAutoFocus(true); + } + + @Override + public void handleResult(Result rawResult) { + try { + Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); + Ringtone r = RingtoneManager.getRingtone(getActivity().getApplicationContext(), notification); + r.play(); + getActivity().getSupportFragmentManager().popBackStack(); + } catch (Exception ignored) {} + if(listener != null) { + listener.onResult(rawResult.getText()); + } + } + + interface OnResultListener { + void onResult(String data); + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/bitshares/bitshareswallet/SendFragment.java b/app/src/main/java/com/bitshares/bitshareswallet/SendFragment.java index 24ebd9f..1be6e76 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/SendFragment.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/SendFragment.java @@ -1,17 +1,29 @@ package com.bitshares.bitshareswallet; +import android.Manifest; import android.app.Activity; import android.arch.lifecycle.ViewModelProviders; import android.content.Context; import android.content.DialogInterface; +import android.content.pm.PackageManager; +import android.graphics.Camera; +import android.hardware.camera2.CameraAccessException; +import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CameraManager; import android.net.Uri; import android.os.Bundle; import android.os.Handler; +import android.support.annotation.NonNull; +import android.support.v4.app.ActivityCompat; import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; +import android.util.ArrayMap; +import android.util.Log; import android.util.Pair; import android.view.LayoutInflater; import android.view.View; @@ -19,8 +31,10 @@ import android.view.inputmethod.InputMethodManager; import android.webkit.WebSettings; import android.webkit.WebView; +import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.EditText; +import android.widget.ImageView; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; @@ -42,6 +56,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +import java.util.Map; import butterknife.BindView; import butterknife.ButterKnife; @@ -49,77 +64,51 @@ import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.exceptions.Exceptions; import io.reactivex.schedulers.Schedulers; +import io.sentry.Sentry; +import io.sentry.event.BreadcrumbBuilder; +import static android.content.Context.CAMERA_SERVICE; -/** - * A simple {@link Fragment} subclass. - * Activities that contain this fragment must implement the - * {@link OnFragmentInteractionListener} interface - * to handle interaction events. - * Use the {@link SendFragment#newInstance} factory method to - * create an instance of this fragment. - */ public class SendFragment extends BaseFragment { - // TODO: Rename parameter arguments, choose names that match - // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER - private static final String ARG_PARAM1 = "param1"; - private static final String ARG_PARAM2 = "param2"; + private KProgressHUD mProcessHud; private Spinner mSpinner; - // TODO: Rename and change types of parameters - private String mParam1; - private String mParam2; - - private OnFragmentInteractionListener mListener; - @BindView(R.id.editTextTo) EditText mEditTextTo; @BindView(R.id.textViewToId) TextView mTextViewId; + @BindView(R.id.qrScan) ImageView qrScan; + @BindView(R.id.editTextQuantity) EditText mEditTextQuantitiy; private View mView; - private Handler mHandler = new Handler(); + private SendViewModel viewModel; - public SendFragment() { - // Required empty public constructor + public SendFragment() {} + + public static SendFragment newInstance() { + return new SendFragment(); } - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @param param1 Parameter 1. - * @param param2 Parameter 2. - * @return A new instance of fragment SendFragment. - */ - // TODO: Rename and change types and number of parameters - public static SendFragment newInstance(String param1, String param2) { - SendFragment fragment = new SendFragment(); - Bundle args = new Bundle(); - args.putString(ARG_PARAM1, param1); - args.putString(ARG_PARAM2, param2); - fragment.setArguments(args); - return fragment; + @Override + public void onAttachFragment(Fragment childFragment) { + super.onAttachFragment(childFragment); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (getArguments() != null) { - mParam1 = getArguments().getString(ARG_PARAM1); - mParam2 = getArguments().getString(ARG_PARAM2); - } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - // Inflate the layout for this fragment mView = inflater.inflate(R.layout.fragment_send, container, false); ButterKnife.bind(this, mView); - EditText editTextFrom = (EditText)mView.findViewById(R.id.editTextFrom); + viewModel = ViewModelProviders.of(this).get(SendViewModel.class); + + EditText editTextFrom = mView.findViewById(R.id.editTextFrom); String strName = BitsharesWalletWraper.getInstance().get_account().name; editTextFrom.setText(strName); @@ -127,10 +116,10 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, sha256_object.encoder encoder = new sha256_object.encoder(); encoder.write(strName.getBytes()); - WebView webViewFrom = (WebView)mView.findViewById(R.id.webViewAvatarFrom); + WebView webViewFrom = mView.findViewById(R.id.webViewAvatarFrom); loadWebView(webViewFrom, 40, encoder.result().toString()); - TextView textView = (TextView)mView.findViewById(R.id.textViewFromId); + TextView textView = mView.findViewById(R.id.textViewFromId); String strId = String.format( Locale.ENGLISH, "#%d", BitsharesWalletWraper.getInstance().get_account().id.get_instance() @@ -144,34 +133,22 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, .setAnimationSpeed(2) .setDimAmount(0.5f); - mView.findViewById(R.id.btn_send).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - processSendClick(mView); - } - }); + mView.findViewById(R.id.btn_send).setOnClickListener(v -> processSendClick(mView)); - mEditTextTo.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - final String strText = mEditTextTo.getText().toString(); - if (hasFocus == false) { - processGetTransferToId(strText, mTextViewId); - } + mEditTextTo.setOnFocusChangeListener((v, hasFocus) -> { + final String strText = mEditTextTo.getText().toString(); + if (!hasFocus) { + processGetTransferToId(strText, mTextViewId); } }); - final WebView webViewTo = (WebView)mView.findViewById(R.id.webViewAvatarTo); + final WebView webViewTo = mView.findViewById(R.id.webViewAvatarTo); mEditTextTo.addTextChangedListener(new TextWatcher() { @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - - } + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - - } + public void onTextChanged(CharSequence s, int start, int before, int count) {} @Override public void afterTextChanged(Editable s) { @@ -181,39 +158,65 @@ public void afterTextChanged(Editable s) { } }); - - mEditTextQuantitiy.setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - if (hasFocus) { - return; + qrScan.setOnClickListener(v -> { + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { + CameraManager manager = (CameraManager) getActivity().getSystemService(CAMERA_SERVICE); + try { + Map data = new ArrayMap<>(); + for (String cameraId : manager.getCameraIdList()) { + CameraCharacteristics chars + = manager.getCameraCharacteristics(cameraId); + boolean flash = chars.get(CameraCharacteristics.FLASH_INFO_AVAILABLE); + int facing = chars.get(CameraCharacteristics.LENS_FACING); + + data.put("camera# " + cameraId, "Flash: " + flash + " | Facing: " + facing); + } + Sentry.getContext().recordBreadcrumb(new BreadcrumbBuilder() + .setCategory("CAMERA") + .setData(data) + .build()); + } catch (CameraAccessException e) { + e.printStackTrace(); } + } - String strQuantity = mEditTextQuantitiy.getText().toString(); - if (TextUtils.isEmpty(strQuantity)) { - return; - } + if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED) { + ActivityCompat.requestPermissions(getActivity(), new String[] {Manifest.permission.CAMERA}, 111); + } else { + ScannerFragment scannerFragment = ScannerFragment.newInstance(); + scannerFragment.setOnResultListener(data -> mEditTextTo.setText(data)); + getActivity().getSupportFragmentManager().beginTransaction().add(android.R.id.content, scannerFragment).addToBackStack(null).commit(); + } + }); - double quantity = NumericUtil.parseDouble(strQuantity, -1.0D); - if (Double.compare(quantity, 0.0D) < 0) { // 越界或者格式错误 - mEditTextQuantitiy.setText("0"); - // TODO toast - return; - } + mEditTextQuantitiy.setOnFocusChangeListener((v, hasFocus) -> { + if (hasFocus) { + return; + } + + String strQuantity = mEditTextQuantitiy.getText().toString(); + if (TextUtils.isEmpty(strQuantity)) { + return; + } - processCalculateFee(); + double quantity = NumericUtil.parseDouble(strQuantity, -1.0D); + if (Double.compare(quantity, 0.0D) < 0) { + mEditTextQuantitiy.setText("0"); + // TODO toast + return; } + + processCalculateFee(); }); - mSpinner = (Spinner) mView.findViewById(R.id.spinner_unit); + mSpinner = mView.findViewById(R.id.spinner_unit); - SendViewModel viewModel = ViewModelProviders.of(this).get(SendViewModel.class); viewModel.getBalancesList().observe(this, bitsharesBalanceAssetList -> { List symbolList = new ArrayList<>(); for (BitsharesBalanceAsset bitsharesBalanceAsset : bitsharesBalanceAssetList) { symbolList.add(bitsharesBalanceAsset.quote); - ArrayAdapter arrayAdapter = new ArrayAdapter( + ArrayAdapter arrayAdapter = new ArrayAdapter<>( getActivity(), android.R.layout.simple_spinner_item, symbolList @@ -227,28 +230,28 @@ public void onFocusChange(View v, boolean hasFocus) { return mView; } - // TODO: Rename method, update argument and hook method into UI event - public void onButtonPressed(Uri uri) { - if (mListener != null) { - mListener.onFragmentInteraction(uri); + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + if(requestCode == 111) { + if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { + ScannerFragment scannerFragment = ScannerFragment.newInstance(); + scannerFragment.setOnResultListener(data -> mEditTextTo.setText(data)); + getActivity().getSupportFragmentManager().beginTransaction().add(android.R.id.content, scannerFragment).addToBackStack(null).commit(); + } else { + ActivityCompat.requestPermissions(getActivity(), new String[] {Manifest.permission.CAMERA}, 111); + } } } @Override public void onAttach(Context context) { super.onAttach(context); - if (context instanceof OnFragmentInteractionListener) { - mListener = (OnFragmentInteractionListener) context; - } else { - throw new RuntimeException(context.toString() - + " must implement OnFragmentInteractionListener"); - } } @Override public void onDetach() { super.onDetach(); - mListener = null; } @Override @@ -317,35 +320,25 @@ private void processSendClick(final View view) { null); builder.setNegativeButton( - R.string.password_confirm_button_cancel, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - - } - } - ); + R.string.password_confirm_button_cancel, null); builder.setView(viewGroup); final AlertDialog dialog = builder.create(); dialog.show(); - dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - EditText editText = (EditText) viewGroup.findViewById(R.id.editTextPassword); - String strPassword = editText.getText().toString(); - int nRet = BitsharesWalletWraper.getInstance().unlock(strPassword); - if (nRet == 0) { - dialog.dismiss(); - String strFrom = ((EditText) view.findViewById(R.id.editTextFrom)).getText().toString(); - String strTo = ((EditText) view.findViewById(R.id.editTextTo)).getText().toString(); - String strQuantity = ((EditText) view.findViewById(R.id.editTextQuantity)).getText().toString(); - String strSymbol = (String)mSpinner.getSelectedItem(); - String strMemo = ((EditText)view.findViewById(R.id.editTextMemo)).getText().toString(); - processTransfer(strFrom, strTo, strQuantity, strSymbol, strMemo); - } else { - viewGroup.findViewById(R.id.textViewPasswordInvalid).setVisibility(View.VISIBLE); - } + dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> { + EditText editText = viewGroup.findViewById(R.id.editTextPassword); + String strPassword = editText.getText().toString(); + int nRet = BitsharesWalletWraper.getInstance().unlock(strPassword); + if (nRet == 0) { + dialog.dismiss(); + String strFrom = ((EditText) view.findViewById(R.id.editTextFrom)).getText().toString(); + String strTo = ((EditText) view.findViewById(R.id.editTextTo)).getText().toString(); + String strQuantity = ((EditText) view.findViewById(R.id.editTextQuantity)).getText().toString(); + String strSymbol = (String)mSpinner.getSelectedItem(); + String strMemo = ((EditText)view.findViewById(R.id.editTextMemo)).getText().toString(); + processTransfer(strFrom, strTo, strQuantity, strSymbol, strMemo); + } else { + viewGroup.findViewById(R.id.textViewPasswordInvalid).setVisibility(View.VISIBLE); } }); @@ -426,7 +419,6 @@ private void processCalculateFee() { strSymbol, strMemo ); - BitsharesAssetObject assetObject = BitsharesApplication.getInstance() .getBitsharesDatabase().getBitsharesDao().queryAssetObjectById(fee.asset_id.toString()); return new Pair<>(fee, assetObject); @@ -438,7 +430,7 @@ private void processCalculateFee() { }, throwable -> { if (throwable instanceof NetworkStatusException) { if (getActivity() != null && getActivity().isFinishing() == false) { - EditText editTextFee = (EditText) mView.findViewById(R.id.editTextFee); + EditText editTextFee = mView.findViewById(R.id.editTextFee); editTextFee.setText("N/A"); } } else { @@ -486,7 +478,7 @@ public void run() { } private void processDisplayFee(asset fee, BitsharesAssetObject assetObject) { - EditText editTextFee = (EditText) mView.findViewById(R.id.editTextFee); + EditText editTextFee = mView.findViewById(R.id.editTextFee); String strResult = String.format( Locale.ENGLISH, "%f (%s)", @@ -495,21 +487,43 @@ private void processDisplayFee(asset fee, BitsharesAssetObject assetObject) { ); editTextFee.setText(strResult); - Spinner spinner = (Spinner) mView.findViewById(R.id.spinner_fee_unit); + Spinner spinner = mView.findViewById(R.id.spinner_fee_unit); + + spinner.setOnItemClickListener((adapterView, view, i, l) -> { + processCalculateFee(); + }); + + viewModel.getBalancesList().observe(this, bitsharesBalanceAssetList -> { + List symbolList = new ArrayList<>(); + for (BitsharesBalanceAsset bitsharesBalanceAsset : bitsharesBalanceAssetList) { + symbolList.add(bitsharesBalanceAsset.quote); - List listSymbols = new ArrayList<>(); + ArrayAdapter arrayAdapter = new ArrayAdapter<>( + getActivity(), + android.R.layout.simple_spinner_item, + symbolList + ); + + if (mSpinner != null) { + arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinner.setAdapter(arrayAdapter); + } + } + }); + + /*List listSymbols = new ArrayList<>(); listSymbols.add(assetObject.symbol); ArrayAdapter arrayAdapter = new ArrayAdapter( getActivity(), android.R.layout.simple_spinner_item, listSymbols - ); + );*/ - if (mSpinner != null) { + /*if (mSpinner != null) { arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(arrayAdapter); - } + }*/ } private void loadWebView(WebView webView, int size, String encryptText) { diff --git a/app/src/main/java/com/bitshares/bitshareswallet/SettingsActivity.java b/app/src/main/java/com/bitshares/bitshareswallet/SettingsActivity.java index d2acd04..02d8621 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/SettingsActivity.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/SettingsActivity.java @@ -13,16 +13,13 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_settings); - mToolbar = (Toolbar) findViewById(R.id.toolbar); + mToolbar = findViewById(R.id.toolbar); setSupportActionBar(mToolbar); - mToolbar.setNavigationOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - onBackPressed(); - } - }); + mToolbar.setNavigationOnClickListener(v -> onBackPressed()); getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SettingsFragment()).commit(); + } } diff --git a/app/src/main/java/com/bitshares/bitshareswallet/SettingsFragment.java b/app/src/main/java/com/bitshares/bitshareswallet/SettingsFragment.java index 7e5f71a..0b491d5 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/SettingsFragment.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/SettingsFragment.java @@ -4,12 +4,8 @@ import android.app.Activity; import android.content.Intent; import android.os.Bundle; -import android.support.v4.app.Fragment; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceFragmentCompat; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; public class SettingsFragment extends PreferenceFragmentCompat { @@ -19,14 +15,17 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.preferences, rootKey); Preference preference = findPreference("currency_setting"); - preference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - Intent intent = new Intent(); - intent.putExtra("setting_changed", "currency_setting"); - getActivity().setResult(Activity.RESULT_OK, intent); - return true; - } + preference.setOnPreferenceChangeListener((preference1, newValue) -> { + Intent intent = new Intent(); + intent.putExtra("setting_changed", "currency_setting"); + getActivity().setResult(Activity.RESULT_OK, intent); + return true; + }); + + Preference pinPreference = findPreference("pin_settings"); + pinPreference.setOnPreferenceClickListener(p -> { + getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new PinSettingsFragment()).addToBackStack(null).commit(); + return true; }); } } diff --git a/app/src/main/java/com/bitshares/bitshareswallet/SignUpButtonActivity.java b/app/src/main/java/com/bitshares/bitshareswallet/SignUpButtonActivity.java index 8549d44..78b2851 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/SignUpButtonActivity.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/SignUpButtonActivity.java @@ -1,38 +1,23 @@ package com.bitshares.bitshareswallet; -import android.annotation.SuppressLint; import android.content.Intent; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatActivity; import android.os.Bundle; -import android.os.Handler; -import android.view.MotionEvent; -import android.view.View; +import android.support.v7.app.AppCompatActivity; -/** - * An example full-screen activity that shows and hides the system UI (i.e. - * status bar and navigation/system bar) with user interaction. - */ public class SignUpButtonActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sign_up_button); - findViewById(R.id.sign_up_button).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(SignUpButtonActivity.this, CreateAccountActivity.class); - startActivity(intent); - } + findViewById(R.id.sign_up_button).setOnClickListener(v -> { + Intent intent = new Intent(SignUpButtonActivity.this, CreateAccountActivity.class); + startActivity(intent); }); - findViewById(R.id.buttonLogin).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intent = new Intent(SignUpButtonActivity.this, ModelSelectActivity.class); - startActivity(intent); - } + findViewById(R.id.buttonLogin).setOnClickListener(v -> { + Intent intent = new Intent(SignUpButtonActivity.this, ModelSelectActivity.class); + startActivity(intent); }); } } diff --git a/app/src/main/java/com/bitshares/bitshareswallet/TransactionSellBuyFragment.java b/app/src/main/java/com/bitshares/bitshareswallet/TransactionSellBuyFragment.java index 1ed8c02..14b0395 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/TransactionSellBuyFragment.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/TransactionSellBuyFragment.java @@ -446,49 +446,28 @@ public void onReject() { private void initFee() { isAssetObjIsInit = false; - new Thread(new Runnable() { - @Override - public void run() { - try { - btsAssetObj = BitsharesWalletWraper.getInstance().lookup_asset_symbols("BTS"); - baseAssetObj = BitsharesWalletWraper.getInstance().lookup_asset_symbols(baseAsset); - quoteAssetObj = BitsharesWalletWraper.getInstance().lookup_asset_symbols(quoteAsset); - globalPropertyObject = BitsharesWalletWraper.getInstance().get_global_properties(); - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - isAssetObjIsInit = true; - } - }); - } catch (Exception e) { - e.printStackTrace(); - } + new Thread(() -> { + try { + btsAssetObj = BitsharesWalletWraper.getInstance().lookup_asset_symbols("BTS"); + baseAssetObj = BitsharesWalletWraper.getInstance().lookup_asset_symbols(baseAsset); + quoteAssetObj = BitsharesWalletWraper.getInstance().lookup_asset_symbols(quoteAsset); + globalPropertyObject = BitsharesWalletWraper.getInstance().get_global_properties(); + getActivity().runOnUiThread(() -> isAssetObjIsInit = true); + } catch (Exception e) { + e.printStackTrace(); } }).start(); } private void buy(final double rate, final double amount, final int timeSec) { mProcessHud.show(); - new Thread(new Runnable() { - @Override - public void run() { - try { - BitsharesWalletWraper.getInstance().buy(quoteAsset, baseAsset, rate, amount, timeSec); - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - mProcessHud.dismiss(); - } - }); - } catch (Exception e) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - mProcessHud.dismiss(); - } - }); - e.printStackTrace(); - } + new Thread(() -> { + try { + BitsharesWalletWraper.getInstance().buy(quoteAsset, baseAsset, rate, amount, timeSec); + getActivity().runOnUiThread(() -> mProcessHud.dismiss()); + } catch (Exception e) { + getActivity().runOnUiThread(() -> mProcessHud.dismiss()); + e.printStackTrace(); } }).start(); } diff --git a/app/src/main/java/com/bitshares/bitshareswallet/TransactionsFragment.java b/app/src/main/java/com/bitshares/bitshareswallet/TransactionsFragment.java index 090770d..8e3363b 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/TransactionsFragment.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/TransactionsFragment.java @@ -28,14 +28,6 @@ * create an instance of this fragment. */ public class TransactionsFragment extends BaseFragment { - // TODO: Rename parameter arguments, choose names that match - // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER - private static final String ARG_PARAM1 = "param1"; - private static final String ARG_PARAM2 = "param2"; - - // TODO: Rename and change types of parameters - private String mParam1; - private String mParam2; private OnFragmentInteractionListener mListener; @@ -81,31 +73,15 @@ public TransactionsFragment() { // Required empty public constructor } - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @param param1 Parameter 1. - * @param param2 Parameter 2. - * @return A new instance of fragment TransactionsFragment. - */ - // TODO: Rename and change types and number of parameters - public static TransactionsFragment newInstance(String param1, String param2) { + + public static TransactionsFragment newInstance() { TransactionsFragment fragment = new TransactionsFragment(); - Bundle args = new Bundle(); - args.putString(ARG_PARAM1, param1); - args.putString(ARG_PARAM2, param2); - fragment.setArguments(args); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (getArguments() != null) { - mParam1 = getArguments().getString(ARG_PARAM1); - mParam2 = getArguments().getString(ARG_PARAM2); - } } @Override diff --git a/app/src/main/java/com/bitshares/bitshareswallet/WalletFragment.java b/app/src/main/java/com/bitshares/bitshareswallet/WalletFragment.java index e3533c7..1a1ccae 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/WalletFragment.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/WalletFragment.java @@ -27,29 +27,8 @@ import butterknife.BindView; import butterknife.ButterKnife; - -/** - * A simple {@link Fragment} subclass. - * Activities that contain this fragment must implement the - * {@link OnFragmentInteractionListener} interface - * to handle interaction events. - * Use the {@link WalletFragment#newInstance} factory method to - * create an instance of this fragment. - */ public class WalletFragment extends BaseFragment { - // TODO: Rename parameter arguments, choose names that match - // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER - private static final String ARG_PARAM1 = "param1"; - private static final String ARG_PARAM2 = "param2"; - - // TODO: Rename and change types of parameters - private String mParam1; - private String mParam2; - - private OnFragmentInteractionListener mListener; - private BtsFragmentPageAdapter mWalletFragmentPageAdapter; - private Handler mHandler = new Handler(); private SendFragment mSendFragment; @@ -64,7 +43,7 @@ public WalletFragment() { public void onNewIntent(Intent intent){ String strAction = intent.getStringExtra("action"); - if (TextUtils.isEmpty(strAction) == false) { + if (!TextUtils.isEmpty(strAction)) { mViewPager.setCurrentItem(2); String strName = intent.getStringExtra("name"); int nAmount = Integer.valueOf(intent.getStringExtra("amount")); @@ -73,31 +52,13 @@ public void onNewIntent(Intent intent){ } } - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @param param1 Parameter 1. - * @param param2 Parameter 2. - * @return A new instance of fragment WalletFragment. - */ - // TODO: Rename and change types and number of parameters - public static WalletFragment newInstance(String param1, String param2) { - WalletFragment fragment = new WalletFragment(); - Bundle args = new Bundle(); - args.putString(ARG_PARAM1, param1); - args.putString(ARG_PARAM2, param2); - fragment.setArguments(args); - return fragment; + public static WalletFragment newInstance() { + return new WalletFragment(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (getArguments() != null) { - mParam1 = getArguments().getString(ARG_PARAM1); - mParam2 = getArguments().getString(ARG_PARAM2); - } } @Override @@ -187,10 +148,11 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, ButterKnife.bind(this, view); Resources res = getResources(); mWalletFragmentPageAdapter = new BtsFragmentPageAdapter(getFragmentManager()); - mWalletFragmentPageAdapter.addFragment(BalancesFragment.newInstance("", ""), res.getString(R.string.tab_balances)); - mWalletFragmentPageAdapter.addFragment(TransactionsFragment.newInstance("", ""), res.getString(R.string.tab_transactions)); - mSendFragment = SendFragment.newInstance("", ""); + mSendFragment = SendFragment.newInstance(); mWalletFragmentPageAdapter.addFragment(mSendFragment, res.getString(R.string.tab_send)); + mWalletFragmentPageAdapter.addFragment(TransactionsFragment.newInstance(), res.getString(R.string.tab_transactions)); + mWalletFragmentPageAdapter.addFragment(BalancesFragment.newInstance(), res.getString(R.string.tab_balances)); + mWalletFragmentPageAdapter.addFragment(ReceiveFragment.newInstance(), res.getString(R.string.tab_receive)); mViewPager.setAdapter(mWalletFragmentPageAdapter); initPager(mViewPager, mWalletFragmentPageAdapter); @@ -218,42 +180,13 @@ public void onTabReselected(TabLayout.Tab tab) { return view; } - // TODO: Rename method, update argument and hook method into UI event - public void onButtonPressed(Uri uri) { - if (mListener != null) { - mListener.onFragmentInteraction(uri); - } - } - @Override public void onAttach(Context context) { super.onAttach(context); - if (context instanceof OnFragmentInteractionListener) { - mListener = (OnFragmentInteractionListener) context; - } else { -// throw new RuntimeException(context.toString() -// + " must implement OnFragmentInteractionListener"); - } } @Override public void onDetach() { super.onDetach(); - mListener = null; - } - - /** - * This interface must be implemented by activities that contain this - * fragment to allow an interaction in this fragment to be communicated - * to the activity and potentially other fragments contained in that - * activity. - *

- * See the Android Training lesson Communicating with Other Fragments for more information. - */ - public interface OnFragmentInteractionListener { - // TODO: Update argument type and name - void onFragmentInteraction(Uri uri); } } diff --git a/app/src/main/java/com/bitshares/bitshareswallet/repository/MarketTickerRepository.java b/app/src/main/java/com/bitshares/bitshareswallet/repository/MarketTickerRepository.java index 2c40695..3b3c160 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/repository/MarketTickerRepository.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/repository/MarketTickerRepository.java @@ -2,20 +2,16 @@ import android.arch.lifecycle.LiveData; import android.arch.lifecycle.MediatorLiveData; -import android.util.Pair; import com.bitshares.bitshareswallet.BitsharesApplication; import com.bitshares.bitshareswallet.R; import com.bitshares.bitshareswallet.market.MarketTicker; import com.bitshares.bitshareswallet.room.BitsharesAssetObject; -import com.bitshares.bitshareswallet.room.BitsharesBalanceAsset; import com.bitshares.bitshareswallet.room.BitsharesDao; import com.bitshares.bitshareswallet.room.BitsharesMarketTicker; import com.bitshares.bitshareswallet.wallet.BitsharesWalletWraper; import com.bitshares.bitshareswallet.wallet.exception.NetworkStatusException; import com.bitshares.bitshareswallet.wallet.graphene.chain.asset_object; -import com.bitshares.bitshareswallet.wallet.graphene.chain.object_id; -import com.bitshares.bitshareswallet.wallet.graphene.chain.utils; import com.bituniverse.network.Resource; import java.util.ArrayList; @@ -27,12 +23,8 @@ import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.schedulers.Schedulers; -/** - * Created by lorne on 02/11/2017. - */ - public class MarketTickerRepository { - BitsharesDao bitsharesDao; + private BitsharesDao bitsharesDao; private MediatorLiveData>> result = new MediatorLiveData<>(); public MarketTickerRepository() { @@ -59,10 +51,9 @@ private boolean shouldFetch(List bitsharesMarketTickerLis private void fetchFromNetwork(final LiveData> dbSource) { result.addSource(dbSource, newData -> result.setValue(Resource.loading(newData))); - // 向远程获取数据,并进行存储 Flowable.just(0) .subscribeOn(Schedulers.io()) - .map(integer -> { // 获取asset list + .map(integer -> { fetchMarketTicker(); return 0; }).observeOn(AndroidSchedulers.mainThread()) diff --git a/app/src/main/java/com/bitshares/bitshareswallet/util/Safe.java b/app/src/main/java/com/bitshares/bitshareswallet/util/Safe.java new file mode 100644 index 0000000..8a9d53c --- /dev/null +++ b/app/src/main/java/com/bitshares/bitshareswallet/util/Safe.java @@ -0,0 +1,15 @@ +package com.bitshares.bitshareswallet.util; + +public class Safe { + + public static String encryptDecrypt(String input, char[] key) { + StringBuilder output = new StringBuilder(); + + for(int i = 0; i < input.length(); i++) { + output.append((char) (input.charAt(i) ^ key[i % key.length])); + } + + return output.toString(); + } + +} diff --git a/app/src/main/java/com/bitshares/bitshareswallet/viewmodel/SellBuyViewModel.java b/app/src/main/java/com/bitshares/bitshareswallet/viewmodel/SellBuyViewModel.java index 40fee06..9ac1d3e 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/viewmodel/SellBuyViewModel.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/viewmodel/SellBuyViewModel.java @@ -35,12 +35,8 @@ public void changeBalanceAsset(String currency) { public LiveData> getAvaliableBalance() { LiveData> balanceData = Transformations.switchMap( - Transformations.switchMap(currencyData, input -> { - return statusChangeLiveData; - }), - statusChange -> { - return new AvailableBalanceRepository().getTargetAvaliableBlance(currencyData.getValue()); - }); + Transformations.switchMap(currencyData, input -> statusChangeLiveData), + statusChange -> new AvailableBalanceRepository().getTargetAvaliableBlance(currencyData.getValue())); return balanceData; diff --git a/app/src/main/java/com/bitshares/bitshareswallet/viewmodel/WalletViewModel.java b/app/src/main/java/com/bitshares/bitshareswallet/viewmodel/WalletViewModel.java index e8cc639..8301b80 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/viewmodel/WalletViewModel.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/viewmodel/WalletViewModel.java @@ -32,9 +32,7 @@ public WalletViewModel() { retryData.setValue(retryData.getValue()); return retryData; }), - retryCount -> { - return new BalanceRepository().getBalances(currencyData.getValue()); - }); + retryCount -> new BalanceRepository().getBalances(currencyData.getValue())); resultData.addSource(balanceData, result -> resultData.setValue(result)); }); @@ -51,6 +49,6 @@ public LiveData>> getBalanceData() { public void retry() { int nValue = retryData.getValue(); - retryData.setValue(nValue++); + retryData.setValue(++nValue); } } diff --git a/app/src/main/java/com/bitshares/bitshareswallet/wallet/BitsharesWalletWraper.java b/app/src/main/java/com/bitshares/bitshareswallet/wallet/BitsharesWalletWraper.java index a8f202c..9450af5 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/wallet/BitsharesWalletWraper.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/wallet/BitsharesWalletWraper.java @@ -1,11 +1,6 @@ package com.bitshares.bitshareswallet.wallet; -import android.content.SharedPreferences; -import android.support.v7.preference.PreferenceManager; -import android.util.Pair; - import com.bitshares.bitshareswallet.BitsharesApplication; -import com.bitshares.bitshareswallet.R; import com.bitshares.bitshareswallet.market.MarketTicker; import com.bitshares.bitshareswallet.market.MarketTrade; import com.bitshares.bitshareswallet.wallet.common.ErrorCode; @@ -22,19 +17,16 @@ import com.bitshares.bitshareswallet.wallet.graphene.chain.operation_history_object; import com.bitshares.bitshareswallet.wallet.graphene.chain.operations; import com.bitshares.bitshareswallet.wallet.graphene.chain.signed_transaction; -import com.bitshares.bitshareswallet.wallet.graphene.chain.utils; import com.google.common.collect.Sets; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -43,6 +35,8 @@ import de.bitsharesmunich.graphenej.FileBin; import de.bitsharesmunich.graphenej.models.backup.LinkedAccount; import de.bitsharesmunich.graphenej.models.backup.WalletBackup; +import io.sentry.Sentry; +import io.sentry.event.UserBuilder; public class BitsharesWalletWraper { public interface BitsharesDataObserver { diff --git a/app/src/main/java/com/bitshares/bitshareswallet/wallet/graphene/chain/fee_schedule.java b/app/src/main/java/com/bitshares/bitshareswallet/wallet/graphene/chain/fee_schedule.java index 0b7da0a..a770e6d 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/wallet/graphene/chain/fee_schedule.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/wallet/graphene/chain/fee_schedule.java @@ -1,5 +1,7 @@ package com.bitshares.bitshareswallet.wallet.graphene.chain; +import android.util.Log; + import com.bitshares.bitshareswallet.wallet.asset; import com.google.gson.JsonArray; import com.google.gson.JsonDeserializationContext; @@ -61,11 +63,14 @@ public asset calculate_fee(operations.operation_type operationType, price core_e BigInteger bigScale = BigInteger.valueOf(scale); BigInteger bigScaled = bigFee.multiply(bigScale); BigInteger bigDefault = BigInteger.valueOf(GRAPHENE_100_PERCENT); + // // TODO: 07/09/2017 需要确保 FC_ASSERT( scaled <= GRAPHENE_MAX_SHARE_SUPPLY ); long lResult = bigScaled.divide(bigDefault).longValue(); - asset assetResult = new asset(lResult, new object_id(0, asset_object.class)).multipy(core_exchange_rate); + asset assetResult = new asset(lResult, new object_id(3275, asset_object.class)).multipy(core_exchange_rate); + + Log.w("FEE", assetResult.asset_id.toString()); while (assetResult.multipy(core_exchange_rate).amount < lResult) { assetResult.amount++; diff --git a/app/src/main/java/com/bitshares/bitshareswallet/wallet/wallet_api.java b/app/src/main/java/com/bitshares/bitshareswallet/wallet/wallet_api.java index d612ea3..b9c292b 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/wallet/wallet_api.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/wallet/wallet_api.java @@ -73,9 +73,6 @@ class wallet_object { List my_accounts = new ArrayList<>(); ByteBuffer cipher_keys; HashMap, List> extra_keys = new HashMap<>(); - String ws_server = ""; - String ws_user = ""; - String ws_password = ""; public void update_account(account_object accountObject) { boolean bUpdated = false; @@ -88,7 +85,7 @@ public void update_account(account_object accountObject) { } } - if (bUpdated == false) { + if (!bUpdated) { my_accounts.add(accountObject); } } @@ -213,11 +210,7 @@ private void encrypt_keys() { byte[] ivBytes = new byte[16]; System.arraycopy(mCheckSum.hash, 32, ivBytes, 0, ivBytes.length); - ByteBuffer byteResult = aes.encrypt(byteKey, ivBytes, encoder.getData()); - - mWalletObject.cipher_keys = byteResult; - - return; + mWalletObject.cipher_keys = aes.encrypt(byteKey, ivBytes, encoder.getData()); } @@ -366,7 +359,7 @@ public account_object get_account(String strAccountNameOrId) throws NetworkStatu // 判定这类型 object_id accountObjectId = object_id.create_from_string(strAccountNameOrId); - List listAccountObject = null; + List listAccountObject; if (accountObjectId == null) { listAccountObject = lookup_account_names(strAccountNameOrId); } else { @@ -571,10 +564,10 @@ public int import_account_password(String strAccountName, return ErrorCode.ERROR_NO_ACCOUNT_OBJECT; } - if (accountObject.active.is_public_key_type_exist(publicActiveKeyType) == false && - accountObject.owner.is_public_key_type_exist(publicActiveKeyType) == false && - accountObject.active.is_public_key_type_exist(publicOwnerKeyType) == false && - accountObject.owner.is_public_key_type_exist(publicOwnerKeyType) == false){ + if (!accountObject.active.is_public_key_type_exist(publicActiveKeyType) && + !accountObject.owner.is_public_key_type_exist(publicActiveKeyType) && + !accountObject.active.is_public_key_type_exist(publicOwnerKeyType) && + !accountObject.owner.is_public_key_type_exist(publicOwnerKeyType)){ return ErrorCode.ERROR_PASSWORD_INVALID; } @@ -635,7 +628,7 @@ public signed_transaction transfer(String strFrom, String strMemo) throws NetworkStatusException { object_id assetObjectId = object_id.create_from_string(strAssetSymbol); - asset_object assetObject = null; + asset_object assetObject; if (assetObjectId == null) { assetObject = lookup_asset_symbols(strAssetSymbol); } else { @@ -655,7 +648,7 @@ public signed_transaction transfer(String strFrom, transferOperation.to = accountObjectTo.id; transferOperation.amount = assetObject.amount_from_string(strAmount); transferOperation.extensions = new HashSet<>(); - if (TextUtils.isEmpty(strMemo) == false) { + if (!TextUtils.isEmpty(strMemo)) { transferOperation.memo = new memo_data(); transferOperation.memo.from = accountObjectFrom.options.memo_key; transferOperation.memo.to = accountObjectTo.options.memo_key; @@ -958,7 +951,7 @@ public List get_market_history(object_id assetObjec private void set_operation_fees(signed_transaction tx, fee_schedule feeSchedule) { for (operations.operation_type operationType : tx.operations) { - feeSchedule.set_fee(operationType, price.unit_price(new object_id(0, asset_object.class))); + feeSchedule.set_fee(operationType, price.unit_price(new object_id(3275, asset_object.class))); } } diff --git a/app/src/main/java/com/bitshares/bitshareswallet/wallet/websocket_api.java b/app/src/main/java/com/bitshares/bitshareswallet/wallet/websocket_api.java index f6e1f65..da9931a 100644 --- a/app/src/main/java/com/bitshares/bitshareswallet/wallet/websocket_api.java +++ b/app/src/main/java/com/bitshares/bitshareswallet/wallet/websocket_api.java @@ -1,6 +1,7 @@ package com.bitshares.bitshareswallet.wallet; import android.text.TextUtils; +import android.util.Log; import android.util.Pair; import com.bitshares.bitshareswallet.market.MarketTicker; @@ -295,7 +296,7 @@ public void onFailure(WebSocket webSocket, Throwable t, Response response) { @Override public void onMessage(WebSocket webSocket, String text) { //super.onMessage(webSocket, text); - + Log.w("WEBSOCKET", ">>> " + text); try { int nMethod = 0; JSONObject jsonObject = new JSONObject(text); @@ -977,6 +978,8 @@ private Reply sendForReplyImpl(Call callObject, Gson gson = global_config_object.getInstance().getGsonBuilder().create(); String strMessage = gson.toJson(callObject); + Log.w("WEBSOCKET", "<<< " + strMessage); + synchronized (mHashMapIdToProcess) { mHashMapIdToProcess.put(callObject.id, replyObjectProcess); } diff --git a/app/src/main/res/drawable/camera_rear.xml b/app/src/main/res/drawable/camera_rear.xml new file mode 100644 index 0000000..f740845 --- /dev/null +++ b/app/src/main/res/drawable/camera_rear.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/dot_filled_dark.xml b/app/src/main/res/drawable/dot_filled_dark.xml new file mode 100644 index 0000000..902411d --- /dev/null +++ b/app/src/main/res/drawable/dot_filled_dark.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/flash.xml b/app/src/main/res/drawable/flash.xml new file mode 100644 index 0000000..8463915 --- /dev/null +++ b/app/src/main/res/drawable/flash.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/flash_off.xml b/app/src/main/res/drawable/flash_off.xml new file mode 100644 index 0000000..856385f --- /dev/null +++ b/app/src/main/res/drawable/flash_off.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete.xml b/app/src/main/res/drawable/ic_delete.xml new file mode 100644 index 0000000..62eea2a --- /dev/null +++ b/app/src/main/res/drawable/ic_delete.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/qrcode_scan.xml b/app/src/main/res/drawable/qrcode_scan.xml new file mode 100644 index 0000000..8a3a7d5 --- /dev/null +++ b/app/src/main/res/drawable/qrcode_scan.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_lock.xml b/app/src/main/res/layout/activity_lock.xml new file mode 100644 index 0000000..ec7d731 --- /dev/null +++ b/app/src/main/res/layout/activity_lock.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 11a7558..126e46f 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -36,11 +36,6 @@ android:padding="8dp" app:layout_behavior="@string/appbar_scrolling_view_behavior"> - - diff --git a/app/src/main/res/layout/fragment_camera.xml b/app/src/main/res/layout/fragment_camera.xml new file mode 100644 index 0000000..208c5fe --- /dev/null +++ b/app/src/main/res/layout/fragment_camera.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_pin_set.xml b/app/src/main/res/layout/fragment_pin_set.xml new file mode 100644 index 0000000..3eaed09 --- /dev/null +++ b/app/src/main/res/layout/fragment_pin_set.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_receive.xml b/app/src/main/res/layout/fragment_receive.xml new file mode 100644 index 0000000..b30cdd3 --- /dev/null +++ b/app/src/main/res/layout/fragment_receive.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_send.xml b/app/src/main/res/layout/fragment_send.xml index bbec0f0..fcd0ded 100644 --- a/app/src/main/res/layout/fragment_send.xml +++ b/app/src/main/res/layout/fragment_send.xml @@ -2,6 +2,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" android:background="@android:color/white" tools:context="com.bitshares.bitshareswallet.SendFragment"> @@ -90,6 +91,9 @@ android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:layout_toRightOf="@+id/webViewAvatarTo" + android:layout_toEndOf="@+id/webViewAvatarTo" + android:layout_toLeftOf="@id/qrScan" + android:layout_toStartOf="@id/qrScan" android:inputType="text" android:hint="@string/send_account_to_hint" android:textSize="@dimen/send_fragment_text_size" @@ -102,10 +106,22 @@ android:layout_marginBottom="12dp" android:layout_height="wrap_content" android:layout_alignBottom="@+id/editTextTo" - android:layout_alignParentRight="true" + android:layout_toLeftOf="@+id/qrScan" + android:layout_toStartOf="@+id/qrScan" android:textSize="@dimen/send_fragment_text_size" android:text="#" /> + + - - - + android:title="@string/backup_wallet" /> Выбор текущей пары Количество + Получить + Неверный PIN код + Блокировка PIN кодом + Изменить PIN + PIN код + С возвращением + Введите текущий PIN код + Подтвердите новый PIN код + Введите новый PIN код + PIN код изменён + PIN код сохранён + PIN код удалён + Экспорт кошелька + Загрузка истории транзакций + Ошибка при загрузке данных. Попробуйте ещё раз через + Загрузка графика + Ошибка при загрузке данных. Попробуйте ещё раз через + Загрузить + Изменить: diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index eef50e1..1ad31d4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -124,6 +124,7 @@ To: Send + Receive Balance Transaction Currency Settings @@ -176,5 +177,17 @@ Failed to load data. Please try again later Loading transaction data + Backup Wallet + Incorrect PIN + Welcome back + PIN code + Change PIN + PIN lock + Confirm new PIN + Enter current PIN + Enter new PIN + PIN changed + PIN saved + PIN deleted diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index fe2cf65..5e088ff 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -1,6 +1,11 @@ + + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 857630f..a989022 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.0.0' + classpath 'com.android.tools.build:gradle:3.2.0-beta05' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index cea734b..b262e26 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Oct 19 14:04:29 CST 2017 +#Wed Aug 15 14:26:54 MSK 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip diff --git a/settings.gradle b/settings.gradle index dbb5f75..e7b4def 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app', ':graphenej:graphenej' +include ':app'