Fixed the 'full node' switch, activated the jack tools to support some Java 8 features, and fixed some lint issues

This commit is contained in:
Christian Basler 2016-10-16 23:16:38 +02:00
parent a5b3c33394
commit 2b1fb436a9
30 changed files with 367 additions and 436 deletions

View File

@ -9,6 +9,7 @@ if (project.hasProperty("project.configs")
apply from: project.property("project.configs") + appName + ".gradle"; apply from: project.property("project.configs") + appName + ".gradle";
} }
//noinspection GroovyMissingReturnStatement
android { android {
compileSdkVersion 24 compileSdkVersion 24
buildToolsVersion "24.0.3" buildToolsVersion "24.0.3"
@ -19,17 +20,23 @@ android {
targetSdkVersion 24 targetSdkVersion 24
versionCode 9 versionCode 9
versionName "1.0-beta9" versionName "1.0-beta9"
jackOptions.enabled = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
} }
buildTypes { buildTypes {
release { release {
minifyEnabled false minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release signingConfig signingConfigs.release
} }
} }
} }
ext.jabitVersion = '2.0.1' ext.jabitVersion = '2.0.2'
dependencies { dependencies {
compile fileTree(dir: 'libs', include: ['*.jar']) compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:24.2.1' compile 'com.android.support:appcompat-v7:24.2.1'
@ -58,8 +65,8 @@ dependencies {
compile 'com.google.zxing:core:3.3.0' compile 'com.google.zxing:core:3.3.0'
compile 'io.github.yavski:fab-speed-dial:1.0.4' compile 'io.github.yavski:fab-speed-dial:1.0.4'
compile 'com.github.amlcurran.showcaseview:library:5.4.3' compile 'com.github.amlcurran.showcaseview:library:5.4.3'
compile ('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.9.3@aar'){ compile('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.9.3@aar') {
transitive=true transitive = true
} }
compile 'com.github.angads25:filepicker:1.0.6' compile 'com.github.angads25:filepicker:1.0.6'

View File

@ -23,7 +23,6 @@ import android.view.View;
import android.widget.ListView; import android.widget.ListView;
import ch.dissem.apps.abit.listener.ListSelectionListener; import ch.dissem.apps.abit.listener.ListSelectionListener;
import ch.dissem.bitmessage.entity.valueobject.Label;
/** /**
* @author Christian Basler * @author Christian Basler
@ -38,11 +37,7 @@ public abstract class AbstractItemListFragment<T> extends ListFragment implement
* A dummy implementation of the {@link ListSelectionListener} interface that does * A dummy implementation of the {@link ListSelectionListener} interface that does
* nothing. Used only when this fragment is not attached to an activity. * nothing. Used only when this fragment is not attached to an activity.
*/ */
private static ListSelectionListener<Object> dummyCallbacks = new private static ListSelectionListener<Object> dummyCallbacks = plaintext -> {
ListSelectionListener<Object>() {
@Override
public void onItemSelected(Object plaintext) {
}
}; };
/** /**
* The fragment's current callback object, which is notified of list item * The fragment's current callback object, which is notified of list item

View File

@ -18,7 +18,6 @@ package ch.dissem.apps.abit;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.os.Bundle; import android.os.Bundle;
@ -31,7 +30,6 @@ import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.Switch; import android.widget.Switch;
import android.widget.TextView; import android.widget.TextView;
@ -131,10 +129,7 @@ public class AddressDetailFragment extends Fragment {
warning = R.string.delete_contact_warning; warning = R.string.delete_contact_warning;
new AlertDialog.Builder(ctx) new AlertDialog.Builder(ctx)
.setMessage(warning) .setMessage(warning)
.setPositiveButton(android.R.string.yes, new .setPositiveButton(android.R.string.yes, (dialog, which) -> {
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Singleton.getAddressRepository(ctx).remove(item); Singleton.getAddressRepository(ctx).remove(item);
MainActivity mainActivity = MainActivity.getInstance(); MainActivity mainActivity = MainActivity.getInstance();
if (item.getPrivateKey() != null && mainActivity != null) { if (item.getPrivateKey() != null && mainActivity != null) {
@ -142,7 +137,6 @@ public class AddressDetailFragment extends Fragment {
} }
item = null; item = null;
ctx.onBackPressed(); ctx.onBackPressed();
}
}) })
.setNegativeButton(android.R.string.no, null) .setNegativeButton(android.R.string.no, null)
.show(); .show();
@ -151,10 +145,7 @@ public class AddressDetailFragment extends Fragment {
case R.id.export: { case R.id.export: {
new AlertDialog.Builder(ctx) new AlertDialog.Builder(ctx)
.setMessage(R.string.confirm_export) .setMessage(R.string.confirm_export)
.setPositiveButton(android.R.string.yes, new .setPositiveButton(android.R.string.yes, (dialog, which) -> {
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent shareIntent = new Intent(Intent.ACTION_SEND); Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain"); shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TITLE, item + shareIntent.putExtra(Intent.EXTRA_TITLE, item +
@ -165,7 +156,6 @@ public class AddressDetailFragment extends Fragment {
shareIntent.putExtra(Intent.EXTRA_TEXT, exporter.toString shareIntent.putExtra(Intent.EXTRA_TEXT, exporter.toString
()); ());
startActivity(Intent.createChooser(shareIntent, null)); startActivity(Intent.createChooser(shareIntent, null));
}
}) })
.setNegativeButton(android.R.string.no, null) .setNegativeButton(android.R.string.no, null)
.show(); .show();
@ -216,12 +206,8 @@ public class AddressDetailFragment extends Fragment {
if (item.getPrivateKey() == null) { if (item.getPrivateKey() == null) {
Switch active = (Switch) rootView.findViewById(R.id.active); Switch active = (Switch) rootView.findViewById(R.id.active);
active.setChecked(item.isSubscribed()); active.setChecked(item.isSubscribed());
active.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { active.setOnCheckedChangeListener((buttonView, isChecked) ->
@Override item.setSubscribed(isChecked));
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
item.setSubscribed(isChecked);
}
});
ImageView pubkeyAvailableImg = (ImageView) rootView.findViewById(R.id ImageView pubkeyAvailableImg = (ImageView) rootView.findViewById(R.id
.pubkey_available); .pubkey_available);

View File

@ -20,6 +20,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem; import android.view.MenuItem;
@ -32,7 +33,6 @@ import android.widget.TextView;
import com.google.zxing.integration.android.IntentIntegrator; import com.google.zxing.integration.android.IntentIntegrator;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import ch.dissem.apps.abit.listener.ActionBarListener; import ch.dissem.apps.abit.listener.ActionBarListener;
@ -56,17 +56,11 @@ public class AddressListFragment extends AbstractItemListFragment<BitmessageAddr
public void updateList() { public void updateList() {
List<BitmessageAddress> addresses = Singleton.getAddressRepository(getContext()) List<BitmessageAddress> addresses = Singleton.getAddressRepository(getContext())
.getContacts(); .getContacts();
Collections.sort(addresses, new Comparator<BitmessageAddress>() { Collections.sort(addresses, (lhs, rhs) -> {
/** // Yields the following order:
* Yields the following order: // * Subscribed addresses come first
* <ol> // * Addresses with Aliases (alphabetically)
* <li>Subscribed addresses come first</li> // * Addresses (alphabetically)
* <li>Addresses with Aliases (alphabetically)</li>
* <li>Addresses (alphabetically)</li>
* </ol>
*/
@Override
public int compare(BitmessageAddress lhs, BitmessageAddress rhs) {
if (lhs.isSubscribed() == rhs.isSubscribed()) { if (lhs.isSubscribed() == rhs.isSubscribed()) {
if (lhs.getAlias() != null) { if (lhs.getAlias() != null) {
if (rhs.getAlias() != null) { if (rhs.getAlias() != null) {
@ -85,18 +79,18 @@ public class AddressListFragment extends AbstractItemListFragment<BitmessageAddr
} else { } else {
return 1; return 1;
} }
}
}); });
setListAdapter(new ArrayAdapter<BitmessageAddress>( setListAdapter(new ArrayAdapter<BitmessageAddress>(
getActivity(), getActivity(),
android.R.layout.simple_list_item_activated_1, android.R.layout.simple_list_item_activated_1,
android.R.id.text1, android.R.id.text1,
addresses) { addresses) {
@NonNull
@Override @Override
public View getView(int position, View convertView, ViewGroup parent) { public View getView(int position, View convertView, @NonNull ViewGroup parent) {
if (convertView == null) { if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(getContext()); LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.subscription_row, null, false); convertView = inflater.inflate(R.layout.subscription_row, parent, false);
} }
BitmessageAddress item = getItem(position); BitmessageAddress item = getItem(position);
((ImageView) convertView.findViewById(R.id.avatar)).setImageDrawable(new ((ImageView) convertView.findViewById(R.id.avatar)).setImageDrawable(new

View File

@ -18,7 +18,6 @@ package ch.dissem.apps.abit;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.text.Selection;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -90,12 +89,9 @@ public class ComposeMessageFragment extends Fragment {
recipientInput = (AutoCompleteTextView) rootView.findViewById(R.id.recipient); recipientInput = (AutoCompleteTextView) rootView.findViewById(R.id.recipient);
final ContactAdapter adapter = new ContactAdapter(getContext()); final ContactAdapter adapter = new ContactAdapter(getContext());
recipientInput.setAdapter(adapter); recipientInput.setAdapter(adapter);
recipientInput.setOnItemClickListener(new AdapterView.OnItemClickListener() { recipientInput.setOnItemClickListener(
@Override (parent, view, position, id) -> recipient = adapter.getItem(position)
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { );
recipient = adapter.getItem(position);
}
});
recipientInput.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { recipientInput.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override @Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

View File

@ -42,9 +42,6 @@ import ch.dissem.bitmessage.wif.WifImporter;
public class ImportIdentitiesFragment extends Fragment { public class ImportIdentitiesFragment extends Fragment {
public static final String WIF_DATA = "wif_data"; public static final String WIF_DATA = "wif_data";
private BitmessageContext bmc;
private RecyclerView recyclerView;
private LinearLayoutManager layoutManager;
private AddressSelectorAdapter adapter; private AddressSelectorAdapter adapter;
private WifImporter importer; private WifImporter importer;
@ -53,14 +50,15 @@ public class ImportIdentitiesFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) { savedInstanceState) {
String wifData = getArguments().getString(WIF_DATA); String wifData = getArguments().getString(WIF_DATA);
bmc = Singleton.getBitmessageContext(getActivity()); BitmessageContext bmc = Singleton.getBitmessageContext(getActivity());
View view = inflater.inflate(R.layout.fragment_import_select_identities, container, false); View view = inflater.inflate(R.layout.fragment_import_select_identities, container, false);
try { try {
importer = new WifImporter(bmc, wifData); importer = new WifImporter(bmc, wifData);
adapter = new AddressSelectorAdapter(importer.getIdentities()); adapter = new AddressSelectorAdapter(importer.getIdentities());
layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(),
LinearLayoutManager.VERTICAL,
false); false);
recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(layoutManager); recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
@ -69,9 +67,7 @@ public class ImportIdentitiesFragment extends Fragment {
} catch (IOException e) { } catch (IOException e) {
return super.onCreateView(inflater, container, savedInstanceState); return super.onCreateView(inflater, container, savedInstanceState);
} }
view.findViewById(R.id.finish).setOnClickListener(new View.OnClickListener() { view.findViewById(R.id.finish).setOnClickListener(v -> {
@Override
public void onClick(View v) {
importer.importAll(adapter.getSelected()); importer.importAll(adapter.getSelected());
MainActivity mainActivity = MainActivity.getInstance(); MainActivity mainActivity = MainActivity.getInstance();
if (mainActivity != null) { if (mainActivity != null) {
@ -80,7 +76,6 @@ public class ImportIdentitiesFragment extends Fragment {
} }
} }
getActivity().finish(); getActivity().finish();
}
}); });
return view; return view;
} }

View File

@ -19,7 +19,6 @@ package ch.dissem.apps.abit;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.graphics.Point; import android.graphics.Point;
@ -34,7 +33,6 @@ import android.widget.CompoundButton;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import com.github.amlcurran.showcaseview.ShowcaseView; import com.github.amlcurran.showcaseview.ShowcaseView;
import com.github.amlcurran.showcaseview.targets.Target;
import com.mikepenz.community_material_typeface_library.CommunityMaterial; import com.mikepenz.community_material_typeface_library.CommunityMaterial;
import com.mikepenz.google_material_typeface_library.GoogleMaterial; import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import com.mikepenz.iconics.IconicsDrawable; import com.mikepenz.iconics.IconicsDrawable;
@ -42,7 +40,6 @@ import com.mikepenz.materialdrawer.AccountHeader;
import com.mikepenz.materialdrawer.AccountHeaderBuilder; import com.mikepenz.materialdrawer.AccountHeaderBuilder;
import com.mikepenz.materialdrawer.Drawer; import com.mikepenz.materialdrawer.Drawer;
import com.mikepenz.materialdrawer.DrawerBuilder; import com.mikepenz.materialdrawer.DrawerBuilder;
import com.mikepenz.materialdrawer.interfaces.OnCheckedChangeListener;
import com.mikepenz.materialdrawer.model.DividerDrawerItem; import com.mikepenz.materialdrawer.model.DividerDrawerItem;
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
import com.mikepenz.materialdrawer.model.ProfileDrawerItem; import com.mikepenz.materialdrawer.model.ProfileDrawerItem;
@ -102,7 +99,8 @@ public class MainActivity extends AppCompatActivity
private static final Logger LOG = LoggerFactory.getLogger(MainActivity.class); private static final Logger LOG = LoggerFactory.getLogger(MainActivity.class);
private static final int ADD_IDENTITY = 1; private static final int ADD_IDENTITY = 1;
private static final int MANAGE_IDENTITY = 2; private static final int MANAGE_IDENTITY = 2;
private static final int ADD_CHAN = 3;
private static final long ID_NODE_SWITCH = 1;
private static WeakReference<MainActivity> instance; private static WeakReference<MainActivity> instance;
@ -134,7 +132,7 @@ public class MainActivity extends AppCompatActivity
private AccountHeader accountHeader; private AccountHeader accountHeader;
private Drawer drawer; private Drawer drawer;
private ShowcaseView showcaseView; private SwitchDrawerItem nodeSwitch;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -152,7 +150,9 @@ public class MainActivity extends AppCompatActivity
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
MessageListFragment listFragment = new MessageListFragment(); MessageListFragment listFragment = new MessageListFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.item_list, listFragment) getSupportFragmentManager()
.beginTransaction()
.replace(R.id.item_list, listFragment)
.commit(); .commit();
if (findViewById(R.id.message_detail_container) != null) { if (findViewById(R.id.message_detail_container) != null) {
@ -189,27 +189,23 @@ public class MainActivity extends AppCompatActivity
int margin = ((Number) (getResources().getDisplayMetrics().density * 12)).intValue(); int margin = ((Number) (getResources().getDisplayMetrics().density * 12)).intValue();
lps.setMargins(margin, margin, margin, margin); lps.setMargins(margin, margin, margin, margin);
showcaseView = new ShowcaseView.Builder(this) new ShowcaseView.Builder(this)
.withMaterialShowcase() .withMaterialShowcase()
.setStyle(R.style.CustomShowcaseTheme) .setStyle(R.style.CustomShowcaseTheme)
.setContentTitle(R.string.full_node) .setContentTitle(R.string.full_node)
.setContentText(R.string.full_node_description) .setContentText(R.string.full_node_description)
.setTarget(new Target() { .setTarget(() -> {
@Override
public Point getPoint() {
View view = drawer.getStickyFooter(); View view = drawer.getStickyFooter();
int[] location = new int[2]; int[] location = new int[2];
view.getLocationInWindow(location); view.getLocationInWindow(location);
int x = location[0] + 7 * view.getWidth() / 8; int x = location[0] + 7 * view.getWidth() / 8;
int y = location[1] + view.getHeight() / 2; int y = location[1] + view.getHeight() / 2;
return new Point(x, y); return new Point(x, y);
} })
}
)
.replaceEndButton(R.layout.showcase_button) .replaceEndButton(R.layout.showcase_button)
.hideOnTouchOutside() .hideOnTouchOutside()
.build(); .build()
showcaseView.setButtonPosition(lps); .setButtonPosition(lps);
} }
} }
@ -268,10 +264,7 @@ public class MainActivity extends AppCompatActivity
.withActivity(this) .withActivity(this)
.withHeaderBackground(R.drawable.header) .withHeaderBackground(R.drawable.header)
.withProfiles(profiles) .withProfiles(profiles)
.withOnAccountHeaderListener(new AccountHeader.OnAccountHeaderListener() { .withOnAccountHeaderListener((view, profile, currentProfile) -> {
@Override
public boolean onProfileChanged(View view, IProfile profile, boolean
currentProfile) {
switch ((int) profile.getIdentifier()) { switch ((int) profile.getIdentifier()) {
case ADD_IDENTITY: case ADD_IDENTITY:
addIdentityDialog(); addIdentityDialog();
@ -293,7 +286,6 @@ public class MainActivity extends AppCompatActivity
} }
// false if it should close the drawer // false if it should close the drawer
return false; return false;
}
}) })
.build(); .build();
if (profiles.size() > 2) { // There's always the add and manage identity items if (profiles.size() > 2) { // There's always the add and manage identity items
@ -346,32 +338,26 @@ public class MainActivity extends AppCompatActivity
.withName(R.string.settings) .withName(R.string.settings)
.withIcon(GoogleMaterial.Icon.gmd_settings)); .withIcon(GoogleMaterial.Icon.gmd_settings));
drawer = new DrawerBuilder() nodeSwitch = new SwitchDrawerItem()
.withActivity(this) .withIdentifier(ID_NODE_SWITCH)
.withToolbar(toolbar)
.withAccountHeader(accountHeader)
.withDrawerItems(drawerItems)
.addStickyDrawerItems(
new SwitchDrawerItem()
.withName(R.string.full_node) .withName(R.string.full_node)
.withIcon(CommunityMaterial.Icon.cmd_cloud_outline) .withIcon(CommunityMaterial.Icon.cmd_cloud_outline)
.withChecked(isRunning()) .withChecked(isRunning())
.withOnCheckedChangeListener(new OnCheckedChangeListener() { .withOnCheckedChangeListener((drawerItem, buttonView, isChecked) -> {
@Override
public void onCheckedChanged(IDrawerItem drawerItem,
CompoundButton buttonView,
boolean isChecked) {
if (isChecked) { if (isChecked) {
checkAndStartNode(buttonView); checkAndStartNode(buttonView);
} else { } else {
service.shutdownNode(); service.shutdownNode();
} }
} });
})
) drawer = new DrawerBuilder()
.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { .withActivity(this)
@Override .withToolbar(toolbar)
public boolean onItemClick(View view, int position, IDrawerItem item) { .withAccountHeader(accountHeader)
.withDrawerItems(drawerItems)
.addStickyDrawerItems(nodeSwitch)
.withOnDrawerItemClickListener((view, position, item) -> {
if (item.getTag() instanceof Label) { if (item.getTag() instanceof Label) {
selectedLabel = (Label) item.getTag(); selectedLabel = (Label) item.getTag();
showSelectedLabel(); showSelectedLabel();
@ -401,7 +387,6 @@ public class MainActivity extends AppCompatActivity
} }
} }
return false; return false;
}
}) })
.withShowDrawerOnFirstLaunch(true) .withShowDrawerOnFirstLaunch(true)
.build(); .build();
@ -415,6 +400,7 @@ public class MainActivity extends AppCompatActivity
@Override @Override
protected void onResume() { protected void onResume() {
updateUnread(); updateUnread();
updateNodeSwitch();
super.onResume(); super.onResume();
} }
@ -470,18 +456,14 @@ public class MainActivity extends AppCompatActivity
} else { } else {
new AlertDialog.Builder(MainActivity.this) new AlertDialog.Builder(MainActivity.this)
.setMessage(R.string.full_node_warning) .setMessage(R.string.full_node_warning)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { .setPositiveButton(
@Override android.R.string.yes,
public void onClick(DialogInterface dialog, int which) { (dialog, which) -> service.startupNode()
service.startupNode(); )
} .setNegativeButton(
}) android.R.string.no,
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { (dialog, which) -> updateNodeSwitch()
@Override )
public void onClick(DialogInterface dialog, int which) {
buttonView.setChecked(false);
}
})
.show(); .show();
} }
} }
@ -501,6 +483,13 @@ public class MainActivity extends AppCompatActivity
} }
} }
public void updateNodeSwitch() {
runOnUiThread(() -> {
nodeSwitch.withChecked(bmc.isRunning());
drawer.updateStickyFooterItem(nodeSwitch);
});
}
private void showSelectedLabel() { private void showSelectedLabel() {
if (getSupportFragmentManager().findFragmentById(R.id.item_list) instanceof if (getSupportFragmentManager().findFragmentById(R.id.item_list) instanceof
MessageListFragment) { MessageListFragment) {

View File

@ -1,8 +1,6 @@
package ch.dissem.apps.abit; package ch.dissem.apps.abit;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
/** /**
* @author Christian Basler * @author Christian Basler

View File

@ -20,7 +20,6 @@ import android.content.Context;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AppCompatDialogFragment; import android.support.v7.app.AppCompatDialogFragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -41,7 +40,6 @@ import ch.dissem.bitmessage.entity.payload.Pubkey;
/** /**
* @author Christian Basler * @author Christian Basler
*/ */
public class DeterministicIdentityDialogFragment extends AppCompatDialogFragment { public class DeterministicIdentityDialogFragment extends AppCompatDialogFragment {
private BitmessageContext bmc; private BitmessageContext bmc;
@ -58,9 +56,7 @@ public class DeterministicIdentityDialogFragment extends AppCompatDialogFragment
getDialog().setTitle(R.string.add_deterministic_address); getDialog().setTitle(R.string.add_deterministic_address);
View view = inflater.inflate(R.layout.dialog_add_deterministic_identity, container, false); View view = inflater.inflate(R.layout.dialog_add_deterministic_identity, container, false);
view.findViewById(R.id.ok) view.findViewById(R.id.ok)
.setOnClickListener(new View.OnClickListener() { .setOnClickListener(v -> {
@Override
public void onClick(View v) {
dismiss(); dismiss();
final Context context = getActivity().getBaseContext(); final Context context = getActivity().getBaseContext();
View dialogView = getView(); View dialogView = getView();
@ -119,15 +115,9 @@ public class DeterministicIdentityDialogFragment extends AppCompatDialogFragment
Integer.valueOf(numberOfAddresses.getText().toString()), Integer.valueOf(numberOfAddresses.getText().toString()),
shorter.isChecked() shorter.isChecked()
); );
}
}); });
view.findViewById(R.id.dismiss) view.findViewById(R.id.dismiss)
.setOnClickListener(new View.OnClickListener() { .setOnClickListener(v -> dismiss());
@Override
public void onClick(View v) {
dismiss();
}
});
return view; return view;
} }

View File

@ -17,7 +17,6 @@
package ch.dissem.apps.abit.notification; package ch.dissem.apps.abit.notification;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -28,7 +27,7 @@ import java.util.TimerTask;
import ch.dissem.apps.abit.MainActivity; import ch.dissem.apps.abit.MainActivity;
import ch.dissem.apps.abit.R; import ch.dissem.apps.abit.R;
import ch.dissem.bitmessage.BitmessageContext; import ch.dissem.apps.abit.service.BitmessageService;
import ch.dissem.bitmessage.utils.Property; import ch.dissem.bitmessage.utils.Property;
/** /**
@ -37,31 +36,32 @@ import ch.dissem.bitmessage.utils.Property;
public class NetworkNotification extends AbstractNotification { public class NetworkNotification extends AbstractNotification {
public static final int ONGOING_NOTIFICATION_ID = 2; public static final int ONGOING_NOTIFICATION_ID = 2;
private final BitmessageContext bmc;
private NotificationCompat.Builder builder; private NotificationCompat.Builder builder;
public NetworkNotification(Context ctx, BitmessageContext bmc) { public NetworkNotification(Context ctx) {
super(ctx); super(ctx);
this.bmc = bmc; Intent showMessageIntent = new Intent(ctx, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(ctx, 1, showMessageIntent, 0);
builder = new NotificationCompat.Builder(ctx); builder = new NotificationCompat.Builder(ctx);
builder.setSmallIcon(R.drawable.ic_notification_full_node) builder.setSmallIcon(R.drawable.ic_notification_full_node)
.setContentTitle(ctx.getString(R.string.bitmessage_full_node)) .setContentTitle(ctx.getString(R.string.bitmessage_full_node))
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC); .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
} .setShowWhen(false)
.setContentIntent(pendingIntent);
@Override
public Notification getNotification() {
update();
return notification;
} }
@SuppressLint("StringFormatMatches") @SuppressLint("StringFormatMatches")
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private boolean update() { private boolean update() {
boolean running = bmc.isRunning(); boolean running = BitmessageService.isRunning();
builder.setOngoing(running); builder.setOngoing(running);
Property connections = bmc.status().getProperty("network").getProperty("connections"); Property connections = BitmessageService.getStatus().getProperty("network", "connections");
if (!running) { if (!running) {
builder.setContentText(ctx.getString(R.string.connection_info_disconnected)); builder.setContentText(ctx.getString(R.string.connection_info_disconnected));
MainActivity mainActivity = MainActivity.getInstance();
if (mainActivity != null) {
mainActivity.updateNodeSwitch();
}
} else if (connections.getProperties().length == 0) { } else if (connections.getProperties().length == 0) {
builder.setContentText(ctx.getString(R.string.connection_info_pending)); builder.setContentText(ctx.getString(R.string.connection_info_pending));
} else { } else {
@ -80,20 +80,15 @@ public class NetworkNotification extends AbstractNotification {
} }
builder.setContentText(info); builder.setContentText(info);
} }
Intent showMessageIntent = new Intent(ctx, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(ctx, 1, showMessageIntent, 0);
builder.setContentIntent(pendingIntent);
notification = builder.build(); notification = builder.build();
return running; return running;
} }
@Override @Override
public void show() { public void show() {
update();
super.show(); super.show();
final Timer timer = new Timer(); new Timer().schedule(new TimerTask() {
timer.schedule(new TimerTask() {
@Override @Override
public void run() { public void run() {
if (!update()) { if (!update()) {
@ -108,4 +103,10 @@ public class NetworkNotification extends AbstractNotification {
protected int getNotificationId() { protected int getNotificationId() {
return ONGOING_NOTIFICATION_ID; return ONGOING_NOTIFICATION_ID;
} }
public void connecting() {
builder.setOngoing(true);
builder.setContentText(ctx.getString(R.string.connection_info_pending));
notification = builder.build();
}
} }

View File

@ -36,7 +36,7 @@ import ch.dissem.bitmessage.entity.Plaintext;
import static ch.dissem.apps.abit.util.Drawables.toBitmap; import static ch.dissem.apps.abit.util.Drawables.toBitmap;
public class NewMessageNotification extends AbstractNotification { public class NewMessageNotification extends AbstractNotification {
public static final int NEW_MESSAGE_NOTIFICATION_ID = 1; private static final int NEW_MESSAGE_NOTIFICATION_ID = 1;
private static final StyleSpan SPAN_EMPHASIS = new StyleSpan(Typeface.BOLD); private static final StyleSpan SPAN_EMPHASIS = new StyleSpan(Typeface.BOLD);
public NewMessageNotification(Context ctx) { public NewMessageNotification(Context ctx) {
@ -62,6 +62,7 @@ public class NewMessageNotification extends AbstractNotification {
PendingIntent.FLAG_UPDATE_CURRENT); PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent); builder.setContentIntent(pendingIntent);
// TODO: add proper intents to reply/delete
builder.addAction(R.drawable.ic_action_reply, ctx.getString(R.string.reply), pendingIntent); builder.addAction(R.drawable.ic_action_reply, ctx.getString(R.string.reply), pendingIntent);
builder.addAction(R.drawable.ic_action_delete, ctx.getString(R.string.delete), builder.addAction(R.drawable.ic_action_delete, ctx.getString(R.string.delete),
pendingIntent); pendingIntent);

View File

@ -196,7 +196,9 @@ public class AndroidAddressRepository implements AddressRepository {
SQLiteDatabase db = sql.getWritableDatabase(); SQLiteDatabase db = sql.getWritableDatabase();
// Create a new map of values, where column names are the keys // Create a new map of values, where column names are the keys
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
if (address.getAlias() != null) {
values.put(COLUMN_ALIAS, address.getAlias()); values.put(COLUMN_ALIAS, address.getAlias());
}
if (address.getPubkey() != null) { if (address.getPubkey() != null) {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
address.getPubkey().writeUnencrypted(out); address.getPubkey().writeUnencrypted(out);
@ -207,7 +209,9 @@ public class AndroidAddressRepository implements AddressRepository {
if (address.getPrivateKey() != null) { if (address.getPrivateKey() != null) {
values.put(COLUMN_PRIVATE_KEY, Encode.bytes(address.getPrivateKey())); values.put(COLUMN_PRIVATE_KEY, Encode.bytes(address.getPrivateKey()));
} }
values.put(COLUMN_CHAN, address.isChan()); if (address.isChan()) {
values.put(COLUMN_CHAN, true);
}
values.put(COLUMN_SUBSCRIBED, address.isSubscribed()); values.put(COLUMN_SUBSCRIBED, address.isSubscribed());
int update = db.update(TABLE_NAME, values, "address=?", int update = db.update(TABLE_NAME, values, "address=?",

View File

@ -33,7 +33,6 @@ import ch.dissem.bitmessage.entity.ObjectMessage;
import ch.dissem.bitmessage.factory.Factory; import ch.dissem.bitmessage.factory.Factory;
import ch.dissem.bitmessage.ports.ProofOfWorkRepository; import ch.dissem.bitmessage.ports.ProofOfWorkRepository;
import ch.dissem.bitmessage.utils.Encode; import ch.dissem.bitmessage.utils.Encode;
import ch.dissem.bitmessage.utils.Strings;
import static ch.dissem.bitmessage.utils.Singleton.cryptography; import static ch.dissem.bitmessage.utils.Singleton.cryptography;
import static ch.dissem.bitmessage.utils.Strings.hex; import static ch.dissem.bitmessage.utils.Strings.hex;

View File

@ -21,11 +21,9 @@ import android.content.Intent;
import android.os.Binder; import android.os.Binder;
import android.os.IBinder; import android.os.IBinder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.dissem.apps.abit.notification.NetworkNotification; import ch.dissem.apps.abit.notification.NetworkNotification;
import ch.dissem.bitmessage.BitmessageContext; import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.utils.Property;
import static ch.dissem.apps.abit.notification.NetworkNotification.ONGOING_NOTIFICATION_ID; import static ch.dissem.apps.abit.notification.NetworkNotification.ONGOING_NOTIFICATION_ID;
@ -35,12 +33,7 @@ import static ch.dissem.apps.abit.notification.NetworkNotification.ONGOING_NOTIF
* onPerformSync(). * onPerformSync().
*/ */
public class BitmessageService extends Service { public class BitmessageService extends Service {
public static final Logger LOG = LoggerFactory.getLogger(BitmessageService.class); private NetworkNotification notification = null;
// Object to use as a thread-safe lock
private static final Object lock = new Object();
private static NetworkNotification notification = null;
private static BitmessageContext bmc = null; private static BitmessageContext bmc = null;
private static volatile boolean running = false; private static volatile boolean running = false;
@ -51,11 +44,11 @@ public class BitmessageService extends Service {
@Override @Override
public void onCreate() { public void onCreate() {
synchronized (lock) { synchronized (BitmessageService.class) {
if (bmc == null) { if (bmc == null) {
bmc = Singleton.getBitmessageContext(this); bmc = Singleton.getBitmessageContext(this);
notification = new NetworkNotification(this, bmc);
} }
notification = new NetworkNotification(this);
} }
} }
@ -70,7 +63,6 @@ public class BitmessageService extends Service {
running = false; running = false;
} }
/** /**
* Return an object that allows the system to invoke * Return an object that allows the system to invoke
* the sync adapter. * the sync adapter.
@ -84,6 +76,7 @@ public class BitmessageService extends Service {
public void startupNode() { public void startupNode() {
startService(new Intent(BitmessageService.this, BitmessageService.class)); startService(new Intent(BitmessageService.this, BitmessageService.class));
running = true; running = true;
notification.connecting();
startForeground(ONGOING_NOTIFICATION_ID, notification.getNotification()); startForeground(ONGOING_NOTIFICATION_ID, notification.getNotification());
if (!bmc.isRunning()) { if (!bmc.isRunning()) {
bmc.startup(); bmc.startup();
@ -96,8 +89,17 @@ public class BitmessageService extends Service {
bmc.shutdown(); bmc.shutdown();
} }
running = false; running = false;
stopForeground(false); stopForeground(true);
notification.show();
stopSelf(); stopSelf();
} }
} }
public static Property getStatus() {
if (bmc != null) {
return bmc.status();
} else {
return new Property("bitmessage context", null);
}
}
} }

View File

@ -40,7 +40,7 @@ public class ProofOfWorkService extends Service {
private static ProofOfWorkEngine engine = new MultiThreadedPOWEngine(); private static ProofOfWorkEngine engine = new MultiThreadedPOWEngine();
private static boolean calculating; private static boolean calculating;
private static final Queue<PowItem> queue = new LinkedList<>(); private static final Queue<PowItem> queue = new LinkedList<>();
private static ProofOfWorkNotification notification; private ProofOfWorkNotification notification;
@Override @Override
public void onCreate() { public void onCreate() {
@ -55,12 +55,14 @@ public class ProofOfWorkService extends Service {
public static class PowBinder extends Binder { public static class PowBinder extends Binder {
private final ProofOfWorkService service; private final ProofOfWorkService service;
private final ProofOfWorkNotification notification;
private PowBinder(ProofOfWorkService service) { private PowBinder(ProofOfWorkService service) {
this.service = service; this.service = service;
this.notification = service.notification;
} }
public void process(PowItem item) { void process(PowItem item) {
synchronized (queue) { synchronized (queue) {
service.startService(new Intent(service, ProofOfWorkService.class)); service.startService(new Intent(service, ProofOfWorkService.class));
service.startForeground(ONGOING_NOTIFICATION_ID, service.startForeground(ONGOING_NOTIFICATION_ID,
@ -90,16 +92,14 @@ public class ProofOfWorkService extends Service {
} }
private void calculateNonce(final PowItem item) { private void calculateNonce(final PowItem item) {
engine.calculateNonce(item.initialHash, item.targetValue, new ProofOfWorkEngine.Callback() { engine.calculateNonce(item.initialHash, item.targetValue, (initialHash, nonce) -> {
@Override
public void onNonceCalculated(byte[] initialHash, byte[] nonce) {
try { try {
item.callback.onNonceCalculated(initialHash, nonce); item.callback.onNonceCalculated(initialHash, nonce);
} finally { } finally {
PowItem item; PowItem next;
synchronized (queue) { synchronized (queue) {
item = queue.poll(); next = queue.poll();
if (item == null) { if (next == null) {
calculating = false; calculating = false;
stopForeground(true); stopForeground(true);
stopSelf(); stopSelf();
@ -107,9 +107,8 @@ public class ProofOfWorkService extends Service {
notification.update(queue.size()).show(); notification.update(queue.size()).show();
} }
} }
if (item != null) { if (next != null) {
calculateNonce(item); calculateNonce(next);
}
} }
} }
}); });

View File

@ -46,7 +46,6 @@ import static ch.dissem.bitmessage.utils.UnixTime.DAY;
* Provides singleton objects across the application. * Provides singleton objects across the application.
*/ */
public class Singleton { public class Singleton {
public static final Object lock = new Object();
private static BitmessageContext bitmessageContext; private static BitmessageContext bitmessageContext;
private static MessageListener messageListener; private static MessageListener messageListener;
private static BitmessageAddress identity; private static BitmessageAddress identity;
@ -54,7 +53,7 @@ public class Singleton {
public static BitmessageContext getBitmessageContext(Context context) { public static BitmessageContext getBitmessageContext(Context context) {
if (bitmessageContext == null) { if (bitmessageContext == null) {
synchronized (lock) { synchronized (Singleton.class) {
if (bitmessageContext == null) { if (bitmessageContext == null) {
final Context ctx = context.getApplicationContext(); final Context ctx = context.getApplicationContext();
SqlHelper sqlHelper = new SqlHelper(ctx); SqlHelper sqlHelper = new SqlHelper(ctx);
@ -108,9 +107,10 @@ public class Singleton {
public static BitmessageAddress getIdentity(Context ctx) { public static BitmessageAddress getIdentity(Context ctx) {
if (identity == null) { if (identity == null) {
BitmessageContext bmc = getBitmessageContext(ctx);
synchronized (Singleton.class) { synchronized (Singleton.class) {
if (identity == null) { if (identity == null) {
BitmessageContext bmc = getBitmessageContext(ctx); // FIXME: this may block the UI, there must be a better way!
List<BitmessageAddress> identities = bmc.addresses() List<BitmessageAddress> identities = bmc.addresses()
.getIdentities(); .getIdentities();
if (identities.size() > 0) { if (identities.size() > 0) {

View File

@ -25,7 +25,6 @@ import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException;
import ch.dissem.apps.abit.R; import ch.dissem.apps.abit.R;
import ch.dissem.apps.abit.listener.WifiReceiver; import ch.dissem.apps.abit.listener.WifiReceiver;
@ -39,8 +38,6 @@ import static ch.dissem.apps.abit.util.Constants.PREFERENCE_WIFI_ONLY;
* @author Christian Basler * @author Christian Basler
*/ */
public class Preferences { public class Preferences {
private static Logger LOG = LoggerFactory.getLogger(Preferences.class);
public static boolean useTrustedNode(Context ctx) { public static boolean useTrustedNode(Context ctx) {
String trustedNode = getPreference(ctx, PREFERENCE_TRUSTED_NODE); String trustedNode = getPreference(ctx, PREFERENCE_TRUSTED_NODE);
return trustedNode != null && !trustedNode.trim().isEmpty(); return trustedNode != null && !trustedNode.trim().isEmpty();

View File

@ -51,7 +51,8 @@
android:layout_margin="16dp" android:layout_margin="16dp"
android:background="@color/contentBackground" android:background="@color/contentBackground"
android:elevation="2dp" android:elevation="2dp"
tools:layout="@layout/fragment_message_detail"/> tools:layout="@layout/fragment_message_detail"
tools:ignore="InconsistentLayout,UnusedAttribute"/>
</FrameLayout> </FrameLayout>
</LinearLayout> </LinearLayout>

View File

@ -15,7 +15,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/to" android:hint="@string/to"
android:inputType="textNoSuggestions" android:inputType="textNoSuggestions"
android:singleLine="true"/> android:maxLines="1"/>
</android.support.design.widget.TextInputLayout> </android.support.design.widget.TextInputLayout>

View File

@ -1,14 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android" <Button xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Got it"
android:textStyle="bold"
android:background="@drawable/material_showcase_button_bg" android:background="@drawable/material_showcase_button_bg"
android:textSize="13sp" android:text="Got it"
android:textAllCaps="true" android:textAllCaps="true"
android:textColor="@android:color/white" android:textColor="@android:color/white"
> android:textSize="13sp"
android:textStyle="bold">
</Button> </Button>

View File

@ -34,10 +34,11 @@
<TextView <TextView
android:id="@+id/name" android:id="@+id/name"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignTop="@+id/avatar" android:layout_alignTop="@+id/avatar"
android:layout_toEndOf="@+id/avatar" android:layout_toEndOf="@+id/avatar"
android:layout_toStartOf="@+id/subscribed"
android:ellipsize="end" android:ellipsize="end"
android:lines="1" android:lines="1"
android:paddingBottom="0dp" android:paddingBottom="0dp"
@ -60,7 +61,8 @@
android:paddingLeft="8dp" android:paddingLeft="8dp"
android:paddingRight="8dp" android:paddingRight="8dp"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
tools:text="Stream #"/> tools:text="Stream #"
tools:ignore="RelativeOverlap"/>
<com.mikepenz.iconics.view.IconicsImageView <com.mikepenz.iconics.view.IconicsImageView
android:id="@+id/subscribed" android:id="@+id/subscribed"

View File

@ -5,19 +5,15 @@
<string name="title_message_detail">Nachricht</string> <string name="title_message_detail">Nachricht</string>
<string name="title_subscription_detail">Abonnement</string> <string name="title_subscription_detail">Abonnement</string>
<string name="bitmessage_full_node">Bitmessage Netzknoten</string> <string name="bitmessage_full_node">Bitmessage Netzknoten</string>
<string name="wifi_mode">Art der WLAN-Verbindung</string>
<string name="settings">Einstellungen</string> <string name="settings">Einstellungen</string>
<string name="wifi_only">Nur WLAN</string> <string name="wifi_only">Nur WLAN</string>
<string name="wifi_only_summary">Nicht mit Mobilfunknetz verbinden</string> <string name="wifi_only_summary">Nicht mit Mobilfunknetz verbinden</string>
<string name="subscriptions">Abonnements</string>
<string name="to">An</string> <string name="to">An</string>
<string name="subject">Betreff</string> <string name="subject">Betreff</string>
<string name="manage_identity">Identität verwalten</string> <string name="manage_identity">Identität verwalten</string>
<string name="add_identity">Identität hinzufügen</string> <string name="add_identity">Identität hinzufügen</string>
<string name="add_identity_summary">Eine neue Identität erstellen</string> <string name="add_identity_summary">Eine neue Identität erstellen</string>
<string name="create_identity">Erstellen</string>
<string name="create_identity_description">Eine neue, zufällige Identität erstellen</string> <string name="create_identity_description">Eine neue, zufällige Identität erstellen</string>
<string name="import_identity">Importieren</string>
<string name="import_identity_description">Eine existierende Identität von PyBitmessage oder einem Export importieren</string> <string name="import_identity_description">Eine existierende Identität von PyBitmessage oder einem Export importieren</string>
<string name="add_deterministic_address">Deterministische Identität</string> <string name="add_deterministic_address">Deterministische Identität</string>
<string name="add_deterministic_address_description">Eine deterministische Identität erstellen oder wiederherstellen</string> <string name="add_deterministic_address_description">Eine deterministische Identität erstellen oder wiederherstellen</string>
@ -25,11 +21,8 @@
<string name="add_chan_description">Einen Chan erstellen oder einem beitreten</string> <string name="add_chan_description">Einen Chan erstellen oder einem beitreten</string>
<string name="title_activity_open_bitmessage_link">Kontakt importieren</string> <string name="title_activity_open_bitmessage_link">Kontakt importieren</string>
<string name="action_settings">Einstellungen</string>
<string name="connection_info_1">Stream %1$d: eine Verbindung</string> <string name="connection_info_1">Stream %1$d: eine Verbindung</string>
<string name="connection_info_n">Stream %1$d: %2$d Verbindungen</string> <string name="connection_info_n">Stream %1$d: %2$d Verbindungen</string>
<string name="import_address">Adresse importieren</string>
<string name="import_contact">Kontakt hinzufügen</string>
<string name="label">Label</string> <string name="label">Label</string>
<string name="subscribe">Abonnieren</string> <string name="subscribe">Abonnieren</string>
<string name="do_import">Importieren</string> <string name="do_import">Importieren</string>
@ -42,7 +35,6 @@
<string name="archive">Archiv</string> <string name="archive">Archiv</string>
<string name="empty_trash">Papierkorb leeren</string> <string name="empty_trash">Papierkorb leeren</string>
<string name="stream_number">Stream %d</string> <string name="stream_number">Stream %d</string>
<string name="enabled">Aktiv</string>
<string name="trusted_node">Vertrauenswürdiger Knoten</string> <string name="trusted_node">Vertrauenswürdiger Knoten</string>
<string name="trusted_node_summary">Diese Adresse wird für die Synchronisation verwendet</string> <string name="trusted_node_summary">Diese Adresse wird für die Synchronisation verwendet</string>
<string name="sync_timeout">Zeitbeschränkung der Synchronisierung</string> <string name="sync_timeout">Zeitbeschränkung der Synchronisierung</string>
@ -56,7 +48,6 @@
<string name="proof_of_work_text_0">Arbeite am Versenden</string> <string name="proof_of_work_text_0">Arbeite am Versenden</string>
<string name="proof_of_work_text_n">Arbeite am Versenden (%1$d in Warteschlange)</string> <string name="proof_of_work_text_n">Arbeite am Versenden (%1$d in Warteschlange)</string>
<string name="error_invalid_sync_port">Ungültiger Port in den Synchronisationseinstellungen: %s</string> <string name="error_invalid_sync_port">Ungültiger Port in den Synchronisationseinstellungen: %s</string>
<string name="error_invalid_sync_host">Synchronisation fehlgeschlagen: der vertrauenswürdige Knoten konnte nicht erreicht werden.</string>
<string name="compose_body_hint">Nachricht schreiben</string> <string name="compose_body_hint">Nachricht schreiben</string>
<string name="contacts_and_subscriptions">Kontakte</string> <string name="contacts_and_subscriptions">Kontakte</string>
<string name="subscribed">Abonniert</string> <string name="subscribed">Abonniert</string>
@ -78,10 +69,9 @@
<string name="delete_contact_warning">Bist Du sicher dass dieser Kontakt gelöscht werden soll?</string> <string name="delete_contact_warning">Bist Du sicher dass dieser Kontakt gelöscht werden soll?</string>
<string name="scan_qr_code">QR-Code scannen</string> <string name="scan_qr_code">QR-Code scannen</string>
<string name="create_contact">Kontakt erfassen</string> <string name="create_contact">Kontakt erfassen</string>
<string name="full_node_description">Solange kein aktiver Knoten gestartet ist, werden keine Meldungen empfangen oder gesendet. Dies braucht jedoch viele Resourcen und Daten. <string name="full_node_description">Solange kein aktiver Knoten gestartet ist, werden keine Meldungen empfangen oder gesendet. Dies braucht jedoch viele Ressourcen und Daten.
Als Alternative kann in den Einstellungen ein vertrauenswürdiger Knoten konfiguriert werden, aber im Moment muss dieser selbst bereitgestellt werden.</string> Als Alternative kann in den Einstellungen ein vertrauenswürdiger Knoten konfiguriert werden, aber im Moment muss dieser selbst bereitgestellt werden.</string>
<string name="got_it">Alles klar</string>
<string name="address">Bitmessage-Adresse</string> <string name="address">Bitmessage-Adresse</string>
<string name="error_illegal_address">Vielleicht hat es einen Tippfehler</string> <string name="error_illegal_address">Vielleicht hat es einen Tippfehler</string>
<string name="export">Exportieren</string> <string name="export">Exportieren</string>
@ -95,7 +85,7 @@ Als Alternative kann in den Einstellungen ein vertrauenswürdiger Knoten konfigu
<string name="toast_identity_created">Identität erstellt</string> <string name="toast_identity_created">Identität erstellt</string>
<string name="toast_identities_created">Identitäten erstellt</string> <string name="toast_identities_created">Identitäten erstellt</string>
<string name="toast_chan_created">Chan erstellt</string> <string name="toast_chan_created">Chan erstellt</string>
<string name="deterministic_address_warning">Merke dir diese Enstellungen und stelle sicher dass sie korrekt sind wenn du eine deterministische Addresse wiederherstellst.</string> <string name="deterministic_address_warning">Merke dir diese Enstellungen und stelle sicher dass sie korrekt sind wenn du eine deterministische Adresse wiederherstellst.</string>
<string name="number_of_identities">Anzahl zu generierender Identitäten</string> <string name="number_of_identities">Anzahl zu generierender Identitäten</string>
<string name="shorter">Kürzere Adressen suchen</string> <string name="shorter">Kürzere Adressen suchen</string>
<string name="wif_string">WIF / Inhalt von keys.dat</string> <string name="wif_string">WIF / Inhalt von keys.dat</string>
@ -106,5 +96,4 @@ Als Alternative kann in den Einstellungen ein vertrauenswürdiger Knoten konfigu
<string name="select_file_title">Datei auswählen</string> <string name="select_file_title">Datei auswählen</string>
<string name="select_identities_to_import">Bitte wähle die zu importierenden Identitäten:</string> <string name="select_identities_to_import">Bitte wähle die zu importierenden Identitäten:</string>
<string name="import_input_description">Du kannst einfach den Inhalt eines Exports oder einer keys.dat-Datei einfügen</string> <string name="import_input_description">Du kannst einfach den Inhalt eines Exports oder einer keys.dat-Datei einfügen</string>
<string name="name">Name</string>
</resources> </resources>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Palette generated by Material Palette - materialpalette.com/blue-grey/orange --> <!-- Palette generated by Material Palette - materialpalette.com/blue-grey/orange -->
<resources> <resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
<color name="colorPrimary">#FFC107</color> <color name="colorPrimary">#FFC107</color>
<color name="colorPrimaryDark">#FFA000</color> <color name="colorPrimaryDark">#FFA000</color>
<color name="colorPrimaryDarkText">#DEFFFFFF</color> <color name="colorPrimaryDarkText">#DEFFFFFF</color>

View File

@ -15,7 +15,7 @@
~ limitations under the License. ~ limitations under the License.
--> -->
<resources> <resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
<string name="define_fab_speed_dial" translatable="false"/> <string name="define_fab_speed_dial" translatable="false"/>
<!-- Author section --> <!-- Author section -->
<string name="library_fab_speed_dial_author" translatable="false">Yavor Ivanov</string> <string name="library_fab_speed_dial_author" translatable="false">Yavor Ivanov</string>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
<string name="define_int_filepicker" translatable="false"/> <string name="define_int_filepicker" translatable="false"/>
<!-- Author section --> <!-- Author section -->
<string name="library_filepicker_author" translatable="false">Angad Singh</string> <string name="library_filepicker_author" translatable="false">Angad Singh</string>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
<string name="define_jabit" translatable="false"/> <string name="define_jabit" translatable="false"/>
<!-- Author section --> <!-- Author section -->
<string name="library_jabit_author" translatable="false">Christian Basler</string> <string name="library_jabit_author" translatable="false">Christian Basler</string>

View File

@ -15,7 +15,7 @@
~ limitations under the License. ~ limitations under the License.
--> -->
<resources> <resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
<string name="define_zxing" translatable="false"/> <string name="define_zxing" translatable="false"/>
<!-- Author section --> <!-- Author section -->
<string name="library_zxing_author" translatable="false">Google, Inc.</string> <string name="library_zxing_author" translatable="false">Google, Inc.</string>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
<string name="define_int_zxingandroidembedded" translatable="false"/> <string name="define_int_zxingandroidembedded" translatable="false"/>
<!-- Author section --> <!-- Author section -->
<string name="library_zxingandroidembedded_author" translatable="false">JourneyApps</string> <string name="library_zxingandroidembedded_author" translatable="false">JourneyApps</string>

View File

@ -1,22 +1,18 @@
<resources> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name">Abit</string> <string name="app_name">Abit</string>
<string name="about_app">A Bitmessage client for Android</string> <string name="about_app">A Bitmessage client for Android</string>
<string name="title_message_detail">Message Detail</string> <string name="title_message_detail">Message Detail</string>
<string name="title_subscription_detail">Subscription Detail</string> <string name="title_subscription_detail">Subscription Detail</string>
<string name="bitmessage_full_node">Bitmessage Node</string> <string name="bitmessage_full_node">Bitmessage Node</string>
<string name="wifi_mode">Wi-Fi Connection Mode</string>
<string name="settings">Settings</string> <string name="settings">Settings</string>
<string name="wifi_only">Wi-Fi only</string> <string name="wifi_only">Wi-Fi only</string>
<string name="wifi_only_summary">Don\'t connect to the mobile network</string> <string name="wifi_only_summary">Don\'t connect to the mobile network</string>
<string name="subscriptions">Subscriptions</string>
<string name="to">To</string> <string name="to">To</string>
<string name="subject">Subject</string> <string name="subject">Subject</string>
<string name="manage_identity">Manage Identity</string> <string name="manage_identity">Manage Identity</string>
<string name="add_identity">Add Identity</string> <string name="add_identity">Add Identity</string>
<string name="add_identity_summary">Create new identity</string> <string name="add_identity_summary">Create new identity</string>
<string name="create_identity">Create new</string>
<string name="create_identity_description">Create a new, random identity</string> <string name="create_identity_description">Create a new, random identity</string>
<string name="import_identity">Import existing</string>
<string name="import_identity_description">Import an existing identity from PyBitmessage or from an export</string> <string name="import_identity_description">Import an existing identity from PyBitmessage or from an export</string>
<string name="add_deterministic_address">Deterministic identity</string> <string name="add_deterministic_address">Deterministic identity</string>
<string name="add_deterministic_address_description">Create or recreate a deterministic identity</string> <string name="add_deterministic_address_description">Create or recreate a deterministic identity</string>
@ -24,24 +20,20 @@
<string name="add_chan_description">Create or join a chan</string> <string name="add_chan_description">Create or join a chan</string>
<string name="title_activity_open_bitmessage_link">Import Contact</string> <string name="title_activity_open_bitmessage_link">Import Contact</string>
<string name="action_settings">Settings</string>
<string name="connection_info_1">Stream #%1$d: one connection</string> <string name="connection_info_1">Stream #%1$d: one connection</string>
<string name="connection_info_n">Stream #%1$d: %2$d connections</string> <string name="connection_info_n" tools:ignore="PluralsCandidate">Stream #%1$d: %2$d connections</string>
<string name="import_address">Import Address</string>
<string name="import_contact">Add to contacts</string>
<string name="label">Label</string> <string name="label">Label</string>
<string name="subscribe">Subscribe</string> <string name="subscribe">Subscribe</string>
<string name="do_import">Import</string> <string name="do_import">Import</string>
<string name="cancel">Cancel</string> <string name="cancel">Cancel</string>
<string name="broadcast">Broadcast</string> <string name="broadcast">Broadcast</string>
<string name="n_new_messages">%d new messages</string> <string name="n_new_messages" tools:ignore="PluralsCandidate">%d new messages</string>
<string name="reply">Reply</string> <string name="reply">Reply</string>
<string name="delete">Delete</string> <string name="delete">Delete</string>
<string name="mark_unread">Mark unread</string> <string name="mark_unread">Mark unread</string>
<string name="archive">Archive</string> <string name="archive">Archive</string>
<string name="empty_trash">Empty Trash</string> <string name="empty_trash">Empty Trash</string>
<string name="stream_number">Stream #%d</string> <string name="stream_number">Stream #%d</string>
<string name="enabled">Enabled</string>
<string name="trusted_node">Trusted node</string> <string name="trusted_node">Trusted node</string>
<string name="trusted_node_summary">Use this node for synchronization</string> <string name="trusted_node_summary">Use this node for synchronization</string>
<string name="sync_timeout">Synchronization Timeout</string> <string name="sync_timeout">Synchronization Timeout</string>
@ -53,9 +45,8 @@
<string name="connection_info_pending">Connecting…</string> <string name="connection_info_pending">Connecting…</string>
<string name="proof_of_work_title">Proof of Work</string> <string name="proof_of_work_title">Proof of Work</string>
<string name="proof_of_work_text_0">Doing work to send message</string> <string name="proof_of_work_text_0">Doing work to send message</string>
<string name="proof_of_work_text_n">Doing work to send message (%1$d queued)</string> <string name="proof_of_work_text_n" tools:ignore="PluralsCandidate">Doing work to send message (%1$d queued)</string>
<string name="error_invalid_sync_port">Invalid port in synchronization settings: %s</string> <string name="error_invalid_sync_port">Invalid port in synchronization settings: %s</string>
<string name="error_invalid_sync_host">Synchronization failed: Trusted node could not be reached.</string>
<string name="compose_body_hint">Write message</string> <string name="compose_body_hint">Write message</string>
<string name="contacts_and_subscriptions">Contacts</string> <string name="contacts_and_subscriptions">Contacts</string>
<string name="subscribed">Subscribed</string> <string name="subscribed">Subscribed</string>
@ -80,7 +71,6 @@
<string name="full_node_description">You can\'t receive or send messages unless you start a full node. But be aware that this uses a lot of resources and internet traffic. <string name="full_node_description">You can\'t receive or send messages unless you start a full node. But be aware that this uses a lot of resources and internet traffic.
As an alternative you could configure a trusted node in the settings, but as of now you\'ll need to deploy your own.</string> As an alternative you could configure a trusted node in the settings, but as of now you\'ll need to deploy your own.</string>
<string name="got_it">Got it</string>
<string name="address">Bitmessage Address</string> <string name="address">Bitmessage Address</string>
<string name="error_illegal_address">There might be a typo</string> <string name="error_illegal_address">There might be a typo</string>
<string name="export">Export</string> <string name="export">Export</string>
@ -105,5 +95,4 @@ As an alternative you could configure a trusted node in the settings, but as of
<string name="select_file_title">Select a File</string> <string name="select_file_title">Select a File</string>
<string name="select_identities_to_import">Please select the identities you want to import:</string> <string name="select_identities_to_import">Please select the identities you want to import:</string>
<string name="import_input_description">You can just paste the contents of an export or a keys.dat file</string> <string name="import_input_description">You can just paste the contents of an export or a keys.dat file</string>
<string name="name">Name</string>
</resources> </resources>

View File

@ -9,7 +9,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:2.2.0' classpath 'com.android.tools.build:gradle:2.2.1'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files