fix cold wallet backup
MODIFY
bither-android/res/layout/dialog_sign_message_select_type.xml
bither-android/res/layout/dialog_sign_message_select_type.xml
android:id="@+id/ll_bitpie_cold"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:visibility="gone"
android:orientation="vertical" >
<LinearLayout

MODIFY
bither-android/res/values/strings.xml
bither-android/res/values/strings.xml
<string name="generate_address_count_label">How many private keys to generate?</string>
<string name="recover_from_backup_of_cold">Find previous back up of Bither Cold on SD card. Recover from it?</string>
<string name="first_add_private_key_check_suggest">Would you check your private keys now?</string>
+ <string name="no_backup">No Backup</string>
+ <string name="backup_failed">Backup failed, please check if you have permission to open</string>
<!-- warm wallet -->
<string name="prepare_tx">Init Transaction</string>

MODIFY
bither-android/src/net/bither/BCCAssetsDetectListActivity.java
bither-android/src/net/bither/BCCAssetsDetectListActivity.java
@@ -5,6 +5,7 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
@@ -24,6 +25,7 @@ import net.bither.util.UnitUtilWrapper;
import net.bither.util.WalletUtils;
import java.util.ArrayList;
+import java.util.List;
/**
* Created by ltq on 2017/9/20.
@@ -36,6 +38,10 @@ public class BCCAssetsDetectListActivity extends SwipeRightFragmentActivity {
public static final String IsDetectBcc = "IsDetectBcc";
public static final String IsMonitored = "IsMonitored";
+ private int page = 1;
+ private boolean hasMore = true;
+ private boolean isLoading = false;
+
private CharSequence password;
private SignMessageTypeSelect signMessageTypeSelect;
private AbstractHD.PathType pathType;
@@ -81,6 +87,7 @@ public class BCCAssetsDetectListActivity extends SwipeRightFragmentActivity {
new IBackClickListener(0, R.anim.slide_out_right));
lv = (ListView) findViewById(R.id.lv);
flTitleBar = (FrameLayout) findViewById(R.id.fl_title_bar);
+ lv.setAdapter(adapter);
switch (signMessageTypeSelect) {
case HdReceive:
pathType = AbstractHD.PathType.EXTERNAL_ROOT_PATH;
@@ -89,29 +96,73 @@ public class BCCAssetsDetectListActivity extends SwipeRightFragmentActivity {
pathType = AbstractHD.PathType.INTERNAL_ROOT_PATH;
break;
}
- lv.setAdapter(adapter);
+ loadHdAddress();
}
- private BaseAdapter adapter = new BaseAdapter() {
+ private void loadHdAddress() {
+ lv.setOnScrollListener(new AbsListView.OnScrollListener() {
+ private int lastFirstVisibleItem;
@Override
- public int getCount() {
- if (pathType == AbstractHD.PathType.EXTERNAL_ROOT_PATH || pathType == AbstractHD.PathType.EXTERNAL_BIP49_PATH) {
- return issuedExternalAddressCount(pathType);
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+
+ }
+
+ @Override
+ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
+ if (firstVisibleItem + visibleItemCount >= totalItemCount - 6
+ && hasMore && !isLoading
+ && lastFirstVisibleItem < firstVisibleItem) {
+ page++;
+ loadAddress();
+ }
+ lastFirstVisibleItem = firstVisibleItem;
+
+ }
+ });
+ loadData();
+ }
+
+ private void loadData() {
+ page = 1;
+ hasMore = true;
+ loadAddress();
+ }
+
+ private void loadAddress() {
+ if (!isLoading && hasMore) {
+ isLoading = true;
+ List<HDAccount.HDAccountAddress> address;
+ if (isMonitored) {
+ address = hdAccountMonitored.getHdHotAddresses(page, pathType, password);
+ } else {
+ address = hdAccount.getHdHotAddresses(page, pathType, password);
+ }
+ if (page == 1) {
+ hdAccountAddresses.clear();
+ }
+ if (address != null && address.size() > 0) {
+ hdAccountAddresses.addAll(address);
+ hasMore = true;
} else {
- return issuedInternalAddressCount(pathType);
+ hasMore = false;
+ }
+ adapter.notifyDataSetChanged();
+ isLoading = false;
}
}
+ private BaseAdapter adapter = new BaseAdapter() {
@Override
- public Object getItem(int position) {
- HDAccount.HDAccountAddress a = addressForIndex(position);
- if (hdAccountAddresses.size() >= MAX_CACHE_SIZE) {
- hdAccountAddresses.clear();
+ public int getCount() {
+ return hdAccountAddresses == null ? 0 : hdAccountAddresses.size();
}
- hdAccountAddresses.add(a);
- return a;
+
+
+ @Override
+ public Object getItem(int position) {
+ return hdAccountAddresses.get(position);
}
@@ -133,42 +184,12 @@ public class BCCAssetsDetectListActivity extends SwipeRightFragmentActivity {
};
- private int issuedExternalAddressCount(AbstractHD.PathType pathType) {
- if (isMonitored) {
- return hdAccountMonitored.issuedExternalIndex(pathType) + 1;
- } else {
- return hdAccount.issuedExternalIndex(pathType) + 1;
- }
- }
-
- private int issuedInternalAddressCount(AbstractHD.PathType pathType) {
- if (isMonitored) {
- return hdAccountMonitored.issuedInternalIndex(pathType) + 1;
- } else {
- return hdAccount.issuedInternalIndex(pathType) + 1;
- }
- }
-
- private HDAccount.HDAccountAddress addressForIndex(int index) {
- if (isMonitored) {
- return hdAccountMonitored.addressForPath(pathType, index);
- } else {
- return hdAccount.addressForPath(pathType, index);
- }
- }
-
- private void showMsg(int msg) {
- DropdownMessage.showDropdownMessage(BCCAssetsDetectListActivity.this, msg);
- }
-
private class Item extends FrameLayout {
TextView tvAddress;
TextView tvIndex;
TextView tvBalance;
LinearLayout llBalance;
- private HDAccount.HDAccountAddress address;
-
public Item(Context context) {
super(context);
removeAllViews();
@@ -183,7 +204,6 @@ public class BCCAssetsDetectListActivity extends SwipeRightFragmentActivity {
}
public void setAddress(HDAccount.HDAccountAddress address) {
- this.address = address;
tvAddress.setText(WalletUtils.formatHash(address.getAddress(), 4, 20));
tvIndex.setText(String.valueOf(address.getIndex()));
tvBalance.setText(UnitUtilWrapper.formatValue(address.getBalance()));

MODIFY
bither-android/src/net/bither/BitherSetting.java
bither-android/src/net/bither/BitherSetting.java
@@ -49,6 +49,7 @@ public class BitherSetting {
public static final int REQUEST_CODE_CAMERA = 1008;
public static final int REQUEST_CODE_CROP_IMAGE = 1009;
public static final int REQUEST_CODE_PERMISSION_CAMERA = 1010;
+ public static final int REQUEST_CODE_PERMISSION_WRITE_EXTERNAL_STORAGE = 1011;
public static final long LAST_USAGE_THRESHOLD_JUST_MS = DateUtils.HOUR_IN_MILLIS;
public static final long LAST_USAGE_THRESHOLD_RECENTLY_MS = 2 * DateUtils.DAY_IN_MILLIS;

MODIFY
bither-android/src/net/bither/SignMessageAddressListActivity.java
bither-android/src/net/bither/SignMessageAddressListActivity.java
@@ -148,7 +148,7 @@ public class SignMessageAddressListActivity extends SwipeRightFragmentActivity {
address = bitpieHDAccountCold.getHdColdAddresses(page, pathType, password);
} else {
if (isHot) {
- address = hdAccount.getHdHotAddresses(page, pathType);
+ address = hdAccount.getHdHotAddresses(page, pathType, password);
} else {
address = hdAccountCold.getHdColdAddresses(page, pathType, password);
}

MODIFY
bither-android/src/net/bither/activity/cold/ColdActivity.java
bither-android/src/net/bither/activity/cold/ColdActivity.java
@@ -20,7 +20,10 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.net.Uri;
import android.os.Bundle;
+import android.provider.Settings;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
@@ -68,6 +71,7 @@ import net.bither.util.BackupUtil;
import net.bither.util.FileUtil;
import net.bither.util.KeyUtil;
import net.bither.util.LogUtil;
+import net.bither.util.PermissionUtil;
import net.bither.util.StringUtil;
import net.bither.util.ThreadUtil;
import net.bither.util.UIUtil;
@@ -326,6 +330,11 @@ public class ColdActivity extends BaseFragmentActivity {
}
private void checkBackup() {
+ if (AddressManager.getInstance().getPrivKeyAddresses() != null && AddressManager
+ .getInstance().getPrivKeyAddresses().size() == 0 && AddressManager
+ .getInstance().getHdmKeychain() == null
+ && !AddressManager.getInstance().hasHDAccountCold()
+ && !AddressManager.getInstance().hasBitpieHDAccountCold()) {
new Thread(new Runnable() {
@Override
public void run() {
@@ -335,7 +344,7 @@ public class ColdActivity extends BaseFragmentActivity {
}
}
}).start();
-
+ }
}
private void showDialogOfColdBackup() {
@@ -432,11 +441,11 @@ public class ColdActivity extends BaseFragmentActivity {
String encryptString = Utils.joinString(new String[]{passwordSeeds[1], passwordSeeds[2], passwordSeeds[3]}, QRCodeUtil.QR_CODE_SPLIT);
if (MnemonicWordList.isHDQrCode(keyString)) {
new HDAccountCold(mnemonicCode, new EncryptedData(encryptString), password);
+ AppSharedPreference.getInstance().setMnemonicWordList(mnemonicCode.getMnemonicWordList());
+ MnemonicCode.setInstance(mnemonicCode);
} else if (MnemonicWordList.isBitpieColdQrCode(keyString)) {
new BitpieHDAccountCold(mnemonicCode, new EncryptedData(encryptString), password);
}
- AppSharedPreference.getInstance().setMnemonicWordList(mnemonicCode.getMnemonicWordList());
- MnemonicCode.setInstance(mnemonicCode);
} catch (Exception e) {
e.printStackTrace();
}
@@ -469,6 +478,9 @@ public class ColdActivity extends BaseFragmentActivity {
private MnemonicCode getMnemonicCode(String string) {
MnemonicWordList mnemonicWordList = MnemonicWordList.getMnemonicWordListForHdSeed(string);
+ if (mnemonicWordList == null && string.equals(MnemonicWordList.getBitpieColdQrCodeFlag())) {
+ mnemonicWordList = MnemonicWordList.English;
+ }
MnemonicCode mnemonicCode = null;
if (mnemonicWordList != null) {
try {
@@ -527,13 +539,39 @@ public class ColdActivity extends BaseFragmentActivity {
if (fragment != null && fragment instanceof ColdAddressFragment) {
((ColdAddressFragment) fragment).refresh();
}
- if (AddressManager.getInstance().getPrivKeyAddresses() != null && AddressManager
- .getInstance().getPrivKeyAddresses().size() == 0 && AddressManager
- .getInstance().getHdmKeychain() == null
- && !AddressManager.getInstance().hasHDAccountCold()
- && !AddressManager.getInstance().hasBitpieHDAccountCold()) {
+ if (!PermissionUtil.isWriteExternalStoragePermission(ColdActivity.this, BitherSetting.REQUEST_CODE_PERMISSION_WRITE_EXTERNAL_STORAGE)) {
+ return;
+ }
+ checkBackup();
+ }
+ }
+
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ switch (requestCode) {
+ case BitherSetting.REQUEST_CODE_PERMISSION_WRITE_EXTERNAL_STORAGE:
+ if (grantResults != null && grantResults.length > 0) {
+ if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
+ DialogConfirmTask dialogConfirmTask = new DialogConfirmTask(
+ this, getString(R.string.permissions_no_grant), new Runnable() {
+ @Override
+ public void run() {
+ Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+ Uri uri = Uri.fromParts("package", getPackageName(), null);
+ intent.setData(uri);
+ startActivity(intent);
+ }
+ });
+ dialogConfirmTask.show();
+ } else {
checkBackup();
}
}
+ default:
+ break;
}
}
+
+}

MODIFY
bither-android/src/net/bither/fragment/cold/OptionColdFragment.java
bither-android/src/net/bither/fragment/cold/OptionColdFragment.java
@@ -77,8 +77,10 @@ import net.bither.util.BackupUtil.BackupListener;
import net.bither.util.DateTimeUtil;
import net.bither.util.FileUtil;
import net.bither.util.KeyUtil;
+import net.bither.util.PermissionUtil;
import net.bither.util.UnitUtilWrapper;
+import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
@@ -235,6 +237,9 @@ public class OptionColdFragment extends Fragment implements Selectable {
@Override
public void onClick(View v) {
if (FileUtil.existSdCardMounted()) {
+ if (!PermissionUtil.isWriteExternalStoragePermission(getActivity(), BitherSetting.REQUEST_CODE_PERMISSION_WRITE_EXTERNAL_STORAGE)) {
+ return;
+ }
long backupTime = AppSharedPreference.getInstance().getLastBackupkeyTime().getTime();
if (backupTime + ONE_HOUR < System.currentTimeMillis()) {
backupPrivateKey();
@@ -383,9 +388,14 @@ public class OptionColdFragment extends Fragment implements Selectable {
flBackTime.setVisibility(View.GONE);
} else {
flBackTime.setVisibility(View.VISIBLE);
+ final List<File> files = FileUtil.getBackupFileListOfCold();
+ if (files != null && files.size() > 0) {
String relativeDate = DateTimeUtil.getRelativeDate(getActivity(), date).toString();
tvBackupTime.setText(Utils.format(getString(R.string.last_time_of_back_up)
+ " ", relativeDate));
+ } else {
+ tvBackupTime.setText(R.string.no_backup);
+ }
tvBackupPath.setText(FileUtil.getBackupSdCardDir().getAbsolutePath());
}
} else {
@@ -407,7 +417,12 @@ public class OptionColdFragment extends Fragment implements Selectable {
private void backupFinish() {
pbBackTime.setVisibility(View.INVISIBLE);
+ final List<File> files = FileUtil.getBackupFileListOfCold();
+ if (files != null && files.size() > 0) {
tvBackupTime.setText(R.string.backup_finish);
+ } else {
+ tvBackupTime.setText(R.string.backup_failed);
+ }
AnimationUtil.fadeOut(tvBackupTime, new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {

MODIFY
bither-android/src/net/bither/ui/base/dialog/DialogFancyQrCode.java
bither-android/src/net/bither/ui/base/dialog/DialogFancyQrCode.java
@@ -28,6 +28,7 @@ import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.ProgressBar;
+import net.bither.BitherSetting;
import net.bither.R;
import net.bither.preference.AppSharedPreference;
import net.bither.qrcode.Qr;
@@ -35,6 +36,7 @@ import net.bither.runnable.FancyQrCodeThread;
import net.bither.ui.base.DropdownMessage;
import net.bither.util.FileUtil;
import net.bither.util.ImageFileUtil;
+import net.bither.util.PermissionUtil;
import net.bither.util.ThreadUtil;
import net.bither.util.UIUtil;
@@ -122,7 +124,7 @@ public class DialogFancyQrCode extends Dialog implements View.OnClickListener,
}
private void save() {
- if (qrCode != null) {
+ if (qrCode != null && PermissionUtil.isWriteExternalStoragePermission(activity, BitherSetting.REQUEST_CODE_PERMISSION_WRITE_EXTERNAL_STORAGE)) {
new SaveThread().start();
}
}

MODIFY
bither-android/src/net/bither/ui/base/dialog/DialogFragmentFancyQrCodePager.java
bither-android/src/net/bither/ui/base/dialog/DialogFragmentFancyQrCodePager.java
@@ -45,6 +45,7 @@ import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.TextView;
+import net.bither.BitherSetting;
import net.bither.R;
import net.bither.preference.AppSharedPreference;
import net.bither.qrcode.Qr;
@@ -53,6 +54,7 @@ import net.bither.util.FileUtil;
import net.bither.util.ImageFileUtil;
import net.bither.util.ImageManageUtil;
import net.bither.util.LogUtil;
+import net.bither.util.PermissionUtil;
import net.bither.util.StringUtil;
import net.bither.util.ThreadUtil;
import net.bither.util.UIUtil;
@@ -171,8 +173,10 @@ public class DialogFragmentFancyQrCodePager extends DialogFragment implements Vi
}
private void save() {
+ if (PermissionUtil.isWriteExternalStoragePermission(activity, BitherSetting.REQUEST_CODE_PERMISSION_WRITE_EXTERNAL_STORAGE)) {
new SaveThread().start();
}
+ }
@Override
public void onClick(View v) {

MODIFY
bither-android/src/net/bither/ui/base/dialog/DialogSignMessageSelectType.java
bither-android/src/net/bither/ui/base/dialog/DialogSignMessageSelectType.java
@@ -31,7 +31,7 @@ public class DialogSignMessageSelectType extends CenterDialog {
private LinearLayout llHd;
private LinearLayout llHdReceive;
private LinearLayout llHdChange;
- private LinearLayout llBitpieCode;
+ private LinearLayout llBitpieCold;
private LinearLayout llBitpieColdReceive;
private LinearLayout llBitpieColdChange;
private View vHotLine;
@@ -48,7 +48,7 @@ public class DialogSignMessageSelectType extends CenterDialog {
llHd = findViewById(R.id.ll_hd);
llHdReceive = findViewById(R.id.ll_hd_receive);
llHdChange = findViewById(R.id.ll_hd_change);
- llBitpieCode = findViewById(R.id.ll_bitpie_cold);
+ llBitpieCold = findViewById(R.id.ll_bitpie_cold);
llBitpieColdReceive = findViewById(R.id.ll_bitpie_cold_receive);
llBitpieColdChange = findViewById(R.id.ll_bitpie_cold_change);
vHotLine = findViewById(R.id.v_hot_line);
@@ -69,8 +69,8 @@ public class DialogSignMessageSelectType extends CenterDialog {
if (hdAccountCold == null) {
llHd.setVisibility(View.GONE);
}
- if (bitpieHDAccountCold == null) {
- llBitpieCode.setVisibility(View.GONE);
+ if (bitpieHDAccountCold != null) {
+ llBitpieCold.setVisibility(View.VISIBLE);
}
}

MODIFY
bither-android/src/net/bither/util/ImageFileUtil.java
bither-android/src/net/bither/util/ImageFileUtil.java
@@ -36,8 +36,7 @@ public class ImageFileUtil {
private static final String AVATAR_FILE_NAME = "a%d.jpg";
public static File getImageForGallery(long timeMillis) {
- String pictureName = getImageNameForGallery(
- timeMillis);
+ String pictureName = getImageNameForGallery(timeMillis);
File dcimFile = new File(Environment.getExternalStorageDirectory()
+ File.separator + Environment.DIRECTORY_DCIM, "Camera");
if (!dcimFile.exists()) {
@@ -60,7 +59,6 @@ public class ImageFileUtil {
timeMillis);
File file = getImageForGallery(timeMillis);
try {
-
NativeUtil.compressBitmap(bit, 100, file.getAbsolutePath(), true);
saveExifInterface(file, orientation);
addPicutureToResolver(file, pictureName, orientation, timeMillis);

MODIFY
bither-android/src/net/bither/util/PermissionUtil.java
bither-android/src/net/bither/util/PermissionUtil.java
@@ -8,6 +8,7 @@ import android.os.Build;
public class PermissionUtil {
private static String PERMISSION_CAMERA = Manifest.permission.CAMERA;
+ private static String PERMISSION_WRITE_EXTERNAL_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE;
public static boolean isCameraPermission(Activity activity, int requestCode) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
@@ -19,4 +20,14 @@ public class PermissionUtil {
return true;
}
+ public static boolean isWriteExternalStoragePermission(Activity activity, int requestCode) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ if (activity.checkSelfPermission(PERMISSION_WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
+ activity.requestPermissions(new String[]{PERMISSION_WRITE_EXTERNAL_STORAGE}, requestCode);
+ return false;
+ }
+ }
+ return true;
+ }
+
}

MODIFY
bitherj
bitherj
-Subproject commit c67cba95405405e526554a3b30beb6f958138087
+Subproject commit 16a70c657821dedaa87c50585c97b01a2d83b9c7

fix cold wallet backup