Address related improvements

- QR code is now shown in contact details and 'manage identity' view
- Contacts and identities can now be deleted
This commit is contained in:
2016-01-29 18:05:43 +01:00
parent adfb3a920a
commit 9275f5ca9c
18 changed files with 403 additions and 175 deletions

View File

@ -31,9 +31,9 @@ import android.view.MenuItem;
* in a {@link MainActivity}.
* <p/>
* This activity is mostly just a 'shell' activity containing nothing
* more than a {@link SubscriptionDetailFragment}.
* more than a {@link AddressDetailFragment}.
*/
public class SubscriptionDetailActivity extends AppCompatActivity {
public class AddressDetailActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -59,9 +59,9 @@ public class SubscriptionDetailActivity extends AppCompatActivity {
// Create the detail fragment and add it to the activity
// using a fragment transaction.
Bundle arguments = new Bundle();
arguments.putSerializable(SubscriptionDetailFragment.ARG_ITEM,
getIntent().getSerializableExtra(SubscriptionDetailFragment.ARG_ITEM));
SubscriptionDetailFragment fragment = new SubscriptionDetailFragment();
arguments.putSerializable(AddressDetailFragment.ARG_ITEM,
getIntent().getSerializableExtra(AddressDetailFragment.ARG_ITEM));
AddressDetailFragment fragment = new AddressDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.add(R.id.content, fragment)

View File

@ -0,0 +1,259 @@
/*
* Copyright 2015 Christian Basler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.dissem.apps.abit;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.ShareActionProvider;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.TextView;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.dissem.apps.abit.service.Singleton;
import ch.dissem.apps.abit.util.Drawables;
import ch.dissem.bitmessage.entity.BitmessageAddress;
import static android.graphics.Color.BLACK;
import static android.graphics.Color.WHITE;
/**
* A fragment representing a single Message detail screen.
* This fragment is either contained in a {@link MainActivity}
* in two-pane mode (on tablets) or a {@link MessageDetailActivity}
* on handsets.
*/
public class AddressDetailFragment extends Fragment {
private static final Logger LOG = LoggerFactory.getLogger(AddressDetailFragment.class);
/**
* The fragment argument representing the item ID that this fragment
* represents.
*/
public static final String ARG_ITEM = "item";
private static final int QR_CODE_SIZE = 350;
private ShareActionProvider shareActionProvider;
/**
* The content this fragment is presenting.
*/
private BitmessageAddress item;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public AddressDetailFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments().containsKey(ARG_ITEM)) {
// Load the dummy content specified by the fragment
// arguments. In a real-world scenario, use a Loader
// to load content from a content provider.
item = (BitmessageAddress) getArguments().getSerializable(ARG_ITEM);
}
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.address, menu);
Drawables.addIcon(getActivity(), menu, R.id.write_message, GoogleMaterial.Icon.gmd_mail);
Drawables.addIcon(getActivity(), menu, R.id.delete, GoogleMaterial.Icon.gmd_delete);
Drawables.addIcon(getActivity(), menu, R.id.share, GoogleMaterial.Icon.gmd_share);
shareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(
menu.findItem(R.id.share));
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
final Activity ctx = getActivity();
switch (menuItem.getItemId()) {
case R.id.write_message:
Intent intent = new Intent(ctx, ComposeMessageActivity.class);
intent.putExtra(ComposeMessageActivity.EXTRA_IDENTITY, Singleton.getIdentity(ctx));
intent.putExtra(ComposeMessageActivity.EXTRA_RECIPIENT, item);
startActivity(intent);
return true;
case R.id.delete:
int warning;
if (item.getPrivateKey() != null)
warning = R.string.delete_identity_warning;
else
warning = R.string.delete_contact_warning;
new AlertDialog.Builder(ctx)
.setMessage(warning)
.setPositiveButton(android.R.string.yes, new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Singleton.getAddressRepository(ctx).remove(item);
item = null;
ctx.onBackPressed();
}
})
.setNegativeButton(android.R.string.no, null)
.show();
return true;
case R.id.share:
new AlertDialog.Builder(ctx)
.setMessage("I have no fucking clue.")
.show();
default:
return false;
}
}
private void setShareIntent(Intent shareIntent) {
if (shareActionProvider != null) {
shareActionProvider.setShareIntent(shareIntent);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_address_detail, container, false);
// Show the dummy content as text in a TextView.
if (item != null) {
((ImageView) rootView.findViewById(R.id.avatar)).setImageDrawable(new Identicon(item));
TextView name = (TextView) rootView.findViewById(R.id.name);
name.setText(item.toString());
name.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Nothing to do
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Nothing to do
}
@Override
public void afterTextChanged(Editable s) {
item.setAlias(s.toString());
}
});
TextView address = (TextView) rootView.findViewById(R.id.address);
address.setText(item.getAddress());
address.setSelected(true);
((TextView) rootView.findViewById(R.id.stream_number)).setText(getActivity()
.getString(R.string.stream_number, item.getStream()));
if (item.getPrivateKey() == null) {
Switch active = (Switch) rootView.findViewById(R.id.active);
active.setChecked(item.isSubscribed());
active.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
item.setSubscribed(isChecked);
}
});
ImageView pubkeyAvailableImg = (ImageView) rootView.findViewById(R.id
.pubkey_available);
if (item.getPubkey() == null) {
pubkeyAvailableImg.setAlpha(0.3f);
TextView pubkeyAvailableDesc = (TextView) rootView.findViewById(R.id
.pubkey_available_desc);
pubkeyAvailableDesc.setText(R.string.pubkey_not_available);
}
} else {
rootView.findViewById(R.id.active).setVisibility(View.GONE);
rootView.findViewById(R.id.pubkey_available).setVisibility(View.GONE);
rootView.findViewById(R.id.pubkey_available_desc).setVisibility(View.GONE);
}
// QR code
ImageView qrCode = (ImageView) rootView.findViewById(R.id.qr_code);
qrCode.setImageBitmap(encodeAsBitmap(item));
}
return rootView;
}
Bitmap encodeAsBitmap(BitmessageAddress address) {
StringBuilder link = new StringBuilder("bitmessage:");
link.append(address.getAddress());
if (address.getAlias() != null) {
link.append("?label=").append(address.getAlias());
}
BitMatrix result;
try {
result = new MultiFormatWriter().encode(link.toString(),
BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, null);
} catch (WriterException e) {
LOG.error(e.getMessage(), e);
return null;
}
int w = result.getWidth();
int h = result.getHeight();
int[] pixels = new int[w * h];
for (int y = 0; y < h; y++) {
int offset = y * w;
for (int x = 0; x < w; x++) {
pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
}
}
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, QR_CODE_SIZE, 0, 0, w, h);
return bitmap;
}
@Override
public void onPause() {
if (item != null) {
Singleton.getAddressRepository(getContext()).save(item);
}
super.onPause();
}
}

View File

@ -38,7 +38,7 @@ import java.util.List;
/**
* Fragment that shows a list of all contacts, the ones we subscribed to first.
*/
public class SubscriptionListFragment extends AbstractItemListFragment<BitmessageAddress> {
public class AddressListFragment extends AbstractItemListFragment<BitmessageAddress> {
@Override
public void onResume() {
super.onResume();
@ -113,7 +113,7 @@ public class SubscriptionListFragment extends AbstractItemListFragment<Bitmessag
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_contact_list, container, false);
return inflater.inflate(R.layout.fragment_address_list, container, false);
}
@Override

View File

@ -26,6 +26,7 @@ import android.support.v7.widget.Toolbar;
public class ComposeMessageActivity extends AppCompatActivity {
public static final String EXTRA_IDENTITY = "ch.dissem.abit.Message.SENDER";
public static final String EXTRA_RECIPIENT = "ch.dissem.abit.Message.RECIPIENT";
public static final String EXTRA_SUBJECT = "ch.dissem.abit.Message.SUBJECT";
@Override
protected void onCreate(Bundle savedInstanceState) {

View File

@ -36,6 +36,7 @@ import ch.dissem.bitmessage.entity.BitmessageAddress;
import static ch.dissem.apps.abit.ComposeMessageActivity.EXTRA_IDENTITY;
import static ch.dissem.apps.abit.ComposeMessageActivity.EXTRA_RECIPIENT;
import static ch.dissem.apps.abit.ComposeMessageActivity.EXTRA_SUBJECT;
/**
* Compose a new message.
@ -43,6 +44,7 @@ import static ch.dissem.apps.abit.ComposeMessageActivity.EXTRA_RECIPIENT;
public class ComposeMessageFragment extends Fragment {
private BitmessageAddress identity;
private BitmessageAddress recipient;
private String subject;
private AutoCompleteTextView recipientInput;
private EditText subjectInput;
private EditText bodyInput;
@ -66,6 +68,9 @@ public class ComposeMessageFragment extends Fragment {
if (getArguments().containsKey(EXTRA_RECIPIENT)) {
recipient = (BitmessageAddress) getArguments().getSerializable(EXTRA_RECIPIENT);
}
if (getArguments().containsKey(EXTRA_SUBJECT)) {
subject = getArguments().getString(EXTRA_SUBJECT);
}
} else {
throw new RuntimeException("No identity set for ComposeMessageFragment");
}
@ -99,9 +104,9 @@ public class ComposeMessageFragment extends Fragment {
recipientInput.setText(recipient.toString());
}
subjectInput = (EditText) rootView.findViewById(R.id.subject);
subjectInput.setText(subject);
bodyInput = (EditText) rootView.findViewById(R.id.body);
// bodyInput.setInputType(EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE);
// bodyInput.setImeOptions(EditorInfo.IME_ACTION_SEND | EditorInfo.IME_FLAG_NO_ENTER_ACTION);
return rootView;
}
@ -120,7 +125,8 @@ public class ComposeMessageFragment extends Fragment {
try {
recipient = new BitmessageAddress(inputString);
} catch (Exception e) {
List<BitmessageAddress> contacts = Singleton.getAddressRepository(getContext()).getContacts();
List<BitmessageAddress> contacts = Singleton.getAddressRepository
(getContext()).getContacts();
for (BitmessageAddress contact : contacts) {
if (inputString.equalsIgnoreCase(contact.getAlias())) {
recipient = contact;

View File

@ -94,6 +94,7 @@ public class MainActivity extends AppCompatActivity
private static final Logger LOG = LoggerFactory.getLogger(MainActivity.class);
private static final int ADD_IDENTITY = 1;
private static final int MANAGE_IDENTITY = 2;
/**
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
@ -120,7 +121,6 @@ public class MainActivity extends AppCompatActivity
private Label selectedLabel;
private BitmessageContext bmc;
private BitmessageAddress selectedIdentity;
private AccountHeader accountHeader;
@Override
@ -190,6 +190,7 @@ public class MainActivity extends AppCompatActivity
profiles.add(new ProfileDrawerItem()
.withIcon(new Identicon(identity))
.withName(identity.toString())
.withNameShown(true)
.withEmail(identity.getAddress())
.withTag(identity)
);
@ -216,6 +217,7 @@ public class MainActivity extends AppCompatActivity
profiles.add(new ProfileSettingDrawerItem()
.withName(getString(R.string.manage_identity))
.withIcon(GoogleMaterial.Icon.gmd_settings)
.withIdentifier(MANAGE_IDENTITY)
);
// Create the AccountHeader
accountHeader = new AccountHeaderBuilder()
@ -226,25 +228,46 @@ public class MainActivity extends AppCompatActivity
@Override
public boolean onProfileChanged(View view, IProfile profile, boolean
currentProfile) {
if (profile.getIdentifier() == ADD_IDENTITY) {
BitmessageAddress identity = bmc.createIdentity(false);
IProfile newProfile = new ProfileDrawerItem()
.withName(identity.toString())
.withEmail(identity.getAddress())
.withTag(identity);
if (accountHeader.getProfiles() != null) {
// we know that there are 2 setting elements.
// Set the new profile above them ;)
accountHeader.addProfile(
newProfile, accountHeader.getProfiles().size() - 2);
} else {
accountHeader.addProfiles(newProfile);
}
} else if (profile instanceof ProfileDrawerItem) {
Object tag = ((ProfileDrawerItem) profile).getTag();
if (tag instanceof BitmessageAddress) {
selectedIdentity = (BitmessageAddress) tag;
}
switch (profile.getIdentifier()) {
case ADD_IDENTITY:
new AlertDialog.Builder(MainActivity.this)
.setMessage(R.string.add_identity_warning)
.setPositiveButton(android.R.string.yes, new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
BitmessageAddress identity = bmc.createIdentity(false);
IProfile newProfile = new ProfileDrawerItem()
.withName(identity.toString())
.withEmail(identity.getAddress())
.withTag(identity);
if (accountHeader.getProfiles() != null) {
// we know that there are 2 setting elements.
// Set the new profile above them ;)
accountHeader.addProfile(
newProfile, accountHeader.getProfiles().size() - 2);
} else {
accountHeader.addProfiles(newProfile);
}
}
})
.setNegativeButton(android.R.string.no, null)
.show();
break;
case MANAGE_IDENTITY:
Intent show = new Intent(MainActivity.this,
AddressDetailActivity.class);
show.putExtra(AddressDetailFragment.ARG_ITEM,
Singleton.getIdentity(getApplicationContext()));
startActivity(show);
break;
default:
if (profile instanceof ProfileDrawerItem) {
Object tag = ((ProfileDrawerItem) profile).getTag();
if (tag instanceof BitmessageAddress) {
Singleton.setIdentity((BitmessageAddress) tag);
}
}
}
// false if it should close the drawer
return false;
@ -336,10 +359,10 @@ public class MainActivity extends AppCompatActivity
switch (ni.getNameRes()) {
case R.string.contacts_and_subscriptions:
if (!(getSupportFragmentManager().findFragmentById(R.id
.item_list) instanceof SubscriptionListFragment)) {
changeList(new SubscriptionListFragment());
.item_list) instanceof AddressListFragment)) {
changeList(new AddressListFragment());
} else {
((SubscriptionListFragment) getSupportFragmentManager()
((AddressListFragment) getSupportFragmentManager()
.findFragmentById(R.id.item_list)).updateList();
}
@ -415,7 +438,7 @@ public class MainActivity extends AppCompatActivity
if (item instanceof Plaintext)
fragment = new MessageDetailFragment();
else if (item instanceof BitmessageAddress)
fragment = new SubscriptionDetailFragment();
fragment = new AddressDetailFragment();
else
throw new IllegalArgumentException("Plaintext or BitmessageAddress expected, but " +
"was "
@ -431,7 +454,7 @@ public class MainActivity extends AppCompatActivity
if (item instanceof Plaintext)
detailIntent = new Intent(this, MessageDetailActivity.class);
else if (item instanceof BitmessageAddress)
detailIntent = new Intent(this, SubscriptionDetailActivity.class);
detailIntent = new Intent(this, AddressDetailActivity.class);
else
throw new IllegalArgumentException("Plaintext or BitmessageAddress expected, but " +
"was "
@ -468,8 +491,4 @@ public class MainActivity extends AppCompatActivity
}
super.onStop();
}
public BitmessageAddress getSelectedIdentity() {
return selectedIdentity;
}
}

View File

@ -43,6 +43,9 @@ import ch.dissem.bitmessage.entity.valueobject.Label;
import ch.dissem.bitmessage.ports.MessageRepository;
import static android.text.util.Linkify.WEB_URLS;
import static ch.dissem.apps.abit.ComposeMessageActivity.EXTRA_IDENTITY;
import static ch.dissem.apps.abit.ComposeMessageActivity.EXTRA_RECIPIENT;
import static ch.dissem.apps.abit.ComposeMessageActivity.EXTRA_SUBJECT;
import static ch.dissem.apps.abit.util.Constants.BITMESSAGE_ADDRESS_PATTERN;
import static ch.dissem.apps.abit.util.Constants.BITMESSAGE_URL_SCHEMA;
@ -152,8 +155,12 @@ public class MessageDetailFragment extends Fragment {
case R.id.reply:
Intent replyIntent = new Intent(getActivity().getApplicationContext(),
ComposeMessageActivity.class);
replyIntent.putExtra(ComposeMessageActivity.EXTRA_RECIPIENT, item.getFrom());
replyIntent.putExtra(ComposeMessageActivity.EXTRA_IDENTITY, item.getTo());
replyIntent.putExtra(EXTRA_RECIPIENT, item.getFrom());
replyIntent.putExtra(EXTRA_IDENTITY, item.getTo());
replyIntent.putExtra(EXTRA_SUBJECT,
(item.getSubject().substring(0, 3).equalsIgnoreCase("RE:") ? "" : "RE: ")
+ item.getSubject()
);
startActivity(replyIntent);
return true;
case R.id.delete:

View File

@ -132,7 +132,7 @@ public class MessageListFragment extends AbstractItemListFragment<Plaintext> {
@Override
public void onClick(View view) {
Intent intent = new Intent(getActivity().getApplicationContext(), ComposeMessageActivity.class);
intent.putExtra(ComposeMessageActivity.EXTRA_IDENTITY, ((MainActivity) getActivity()).getSelectedIdentity());
intent.putExtra(ComposeMessageActivity.EXTRA_IDENTITY, Singleton.getIdentity(getActivity()));
startActivity(intent);
}
});

View File

@ -1,131 +0,0 @@
/*
* Copyright 2015 Christian Basler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.dissem.apps.abit;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.TextView;
import ch.dissem.apps.abit.service.Singleton;
import ch.dissem.bitmessage.entity.BitmessageAddress;
/**
* A fragment representing a single Message detail screen.
* This fragment is either contained in a {@link MainActivity}
* in two-pane mode (on tablets) or a {@link MessageDetailActivity}
* on handsets.
*/
public class SubscriptionDetailFragment extends Fragment {
/**
* The fragment argument representing the item ID that this fragment
* represents.
*/
public static final String ARG_ITEM = "item";
/**
* The content this fragment is presenting.
*/
private BitmessageAddress item;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public SubscriptionDetailFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments().containsKey(ARG_ITEM)) {
// Load the dummy content specified by the fragment
// arguments. In a real-world scenario, use a Loader
// to load content from a content provider.
item = (BitmessageAddress) getArguments().getSerializable(ARG_ITEM);
}
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_contact_detail, container, false);
// Show the dummy content as text in a TextView.
if (item != null) {
((ImageView) rootView.findViewById(R.id.avatar)).setImageDrawable(new Identicon(item));
TextView name = (TextView) rootView.findViewById(R.id.name);
name.setText(item.toString());
name.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Nothing to do
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Nothing to do
}
@Override
public void afterTextChanged(Editable s) {
item.setAlias(s.toString());
}
});
TextView address = (TextView) rootView.findViewById(R.id.address);
address.setText(item.getAddress());
address.setSelected(true);
((TextView) rootView.findViewById(R.id.stream_number)).setText(getActivity()
.getString(R.string.stream_number, item.getStream()));
Switch active = (Switch) rootView.findViewById(R.id.active);
active.setChecked(item.isSubscribed());
active.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
item.setSubscribed(isChecked);
}
});
ImageView pubkeyAvailableImg = (ImageView) rootView.findViewById(R.id.pubkey_available);
if (item.getPubkey() == null) {
pubkeyAvailableImg.setAlpha(0.3f);
TextView pubkeyAvailableDesc = (TextView) rootView.findViewById(R.id
.pubkey_available_desc);
pubkeyAvailableDesc.setText(R.string.pubkey_not_available);
}
}
return rootView;
}
@Override
public void onPause() {
Singleton.getAddressRepository(getContext()).save(item);
super.onPause();
}
}

View File

@ -239,7 +239,7 @@ public class AndroidAddressRepository implements AddressRepository {
@Override
public void remove(BitmessageAddress address) {
SQLiteDatabase db = sql.getWritableDatabase();
db.delete(TABLE_NAME, "address = " + address.getAddress(), null);
db.delete(TABLE_NAME, "address = ?", new String[]{address.getAddress()});
}
@Override

View File

@ -124,4 +124,10 @@ public class Singleton {
}
return identity;
}
public static void setIdentity(BitmessageAddress identity) {
if (identity.getPrivateKey() == null)
throw new IllegalArgumentException("Identity expected, but no private key available");
Singleton.identity = identity;
}
}