diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6594c5e0c..82201e061 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
###Changelog
###Version 0.18.0
+* All new GUI for the control center
* Add Portuguese pt_PT and pt_BR translations
* Add Czech translation
* Add Hebrew translation and transliteration
diff --git a/app/build.gradle b/app/build.gradle
index f044daa54..40c95594f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -28,6 +28,7 @@ android {
// note: always bump BOTH versionCode and versionName!
versionName "0.18.0"
versionCode 87
+ vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
@@ -64,6 +65,8 @@ dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:25.2.0'
+ compile 'com.android.support:cardview-v7:25.2.0'
+ compile 'com.android.support:recyclerview-v7:25.2.0'
compile 'com.android.support:support-v4:25.2.0'
compile 'com.android.support:design:25.2.0'
compile 'com.github.tony19:logback-android-classic:1.1.1-4'
@@ -73,10 +76,11 @@ dependencies {
compile 'de.cketti.library.changelog:ckchangelog:1.2.2'
compile 'net.e175.klaus:solarpositioning:0.0.9'
compile 'com.github.freeyourgadget:greendao:1998d7cd2d21f662c6044f6ccf3b3a251bbad341'
- compile 'com.github.woxthebox:draglistview:1.2.6'
+ compile 'com.github.woxthebox:draglistview:1.2.9'
compile 'org.apache.commons:commons-lang3:3.4'
// compile project(":DaoCore")
+ compile 'com.android.support.constraint:constraint-layout:1.0.2'
}
preBuild.dependsOn(":GBDaoGenerator:genSources")
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 94117daaf..3922dd0f0 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -37,18 +37,19 @@
android:label="@string/app_name"
android:theme="@style/GadgetbridgeTheme">
+ android:name=".activities.ControlCenterv2"
+ android:label="@string/title_activity_controlcenter"
+ android:theme="@style/GadgetbridgeTheme.NoActionBar">
+
-
+ android:parentActivityName=".activities.ControlCenterv2" />
+ android:parentActivityName=".activities.ControlCenterv2" />
+ android:parentActivityName=".activities.ControlCenterv2">
@@ -303,19 +304,19 @@
+ android:parentActivityName=".activities.ControlCenterv2" />
+ android:parentActivityName=".activities.ControlCenterv2" />
+ android:parentActivityName=".activities.ControlCenterv2" />
+ android:value="nodomain.freeyourgadget.gadgetbridge.activities.ControlCenterv2" />
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java
index 3e68638db..1a3a9a20c 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java
@@ -445,7 +445,7 @@ public class GBApplication extends Application {
public static int getTextColor(Context context) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = context.getTheme();
- theme.resolveAttribute(android.R.attr.textColor, typedValue, true);
+ theme.resolveAttribute(android.R.attr.textColorPrimary, typedValue, true);
return typedValue.data;
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenter.java
deleted file mode 100644
index 0359eb434..000000000
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenter.java
+++ /dev/null
@@ -1,451 +0,0 @@
-/* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer, Daniele
- Gobbetti, Lem Dulfo
-
- This file is part of Gadgetbridge.
-
- Gadgetbridge is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Gadgetbridge is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see . */
-package nodomain.freeyourgadget.gadgetbridge.activities;
-
-import android.Manifest;
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.ProgressDialog;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.design.widget.FloatingActionButton;
-import android.support.v4.app.ActivityCompat;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.content.LocalBroadcastManager;
-import android.support.v4.widget.SwipeRefreshLayout;
-import android.view.ContextMenu;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.AdapterView;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import de.cketti.library.changelog.ChangeLog;
-import nodomain.freeyourgadget.gadgetbridge.GBApplication;
-import nodomain.freeyourgadget.gadgetbridge.R;
-import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity;
-import nodomain.freeyourgadget.gadgetbridge.adapter.GBDeviceAdapter;
-import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
-import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager;
-import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
-import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
-import nodomain.freeyourgadget.gadgetbridge.util.GB;
-import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
-
-public class ControlCenter extends GBActivity {
-
- private static final Logger LOG = LoggerFactory.getLogger(ControlCenter.class);
-
- private TextView hintTextView;
- private FloatingActionButton fab;
- private ImageView background;
-
- private SwipeRefreshLayout swipeLayout;
- private GBDeviceAdapter mGBDeviceAdapter;
- private DeviceManager deviceManager;
- /**
- * Temporary field for the context menu
- */
- private GBDevice selectedDevice;
-
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- switch (action) {
- case GBApplication.ACTION_QUIT:
- finish();
- break;
- case DeviceManager.ACTION_DEVICES_CHANGED:
- refreshPairedDevices();
- GBDevice selectedDevice = deviceManager.getSelectedDevice();
- if (selectedDevice != null) {
- refreshBusyState(selectedDevice);
- enableSwipeRefresh(selectedDevice);
- }
- break;
- }
- }
- };
-
- private void refreshBusyState(GBDevice dev) {
- if (dev != null && dev.isBusy()) {
- swipeLayout.setRefreshing(true);
- } else {
- boolean wasBusy = swipeLayout.isRefreshing();
- if (wasBusy) {
- swipeLayout.setRefreshing(false);
- }
- }
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_controlcenter);
-
- deviceManager = ((GBApplication)getApplication()).getDeviceManager();
-
- hintTextView = (TextView) findViewById(R.id.hintTextView);
- ListView deviceListView = (ListView) findViewById(R.id.deviceListView);
- fab = (FloatingActionButton) findViewById(R.id.fab);
- background = (ImageView) findViewById(R.id.no_items_bg);
-
- fab.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- launchDiscoveryActivity();
- }
- });
-
- final List deviceList = deviceManager.getDevices();
- mGBDeviceAdapter = new GBDeviceAdapter(this, deviceList);
- deviceListView.setAdapter(this.mGBDeviceAdapter);
- deviceListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView parent, View v, int position, long id) {
- GBDevice gbDevice = mGBDeviceAdapter.getItem(position);
- if (gbDevice.isInitialized()) {
- DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(gbDevice);
- Class extends Activity> primaryActivity = coordinator.getPrimaryActivity();
- if (primaryActivity != null) {
- Intent startIntent = new Intent(ControlCenter.this, primaryActivity);
- startIntent.putExtra(GBDevice.EXTRA_DEVICE, gbDevice);
- startActivity(startIntent);
- }
- } else {
- GBApplication.deviceService().connect(gbDevice);
- }
- }
- });
-
- swipeLayout = (SwipeRefreshLayout) findViewById(R.id.controlcenter_swipe_layout);
- swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
- @Override
- public void onRefresh() {
- fetchActivityData();
- }
- });
-
- registerForContextMenu(deviceListView);
-
- IntentFilter filterLocal = new IntentFilter();
- filterLocal.addAction(GBApplication.ACTION_QUIT);
- filterLocal.addAction(DeviceManager.ACTION_DEVICES_CHANGED);
- LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal);
-
- refreshPairedDevices();
- /*
- * Ask for permission to intercept notifications on first run.
- */
- Prefs prefs = GBApplication.getPrefs();
- if (prefs.getBoolean("firstrun", true)) {
- prefs.getPreferences().edit().putBoolean("firstrun", false).apply();
- Intent enableIntent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
- startActivity(enableIntent);
- }
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- checkAndRequestPermissions();
- }
-
- ChangeLog cl = new ChangeLog(this);
- if (cl.isFirstRun()) {
- cl.getLogDialog().show();
- }
-
- GBApplication.deviceService().start();
-
- enableSwipeRefresh(deviceManager.getSelectedDevice());
- if (GB.isBluetoothEnabled() && deviceList.isEmpty() && Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
- startActivity(new Intent(this, DiscoveryActivity.class));
- } else {
- GBApplication.deviceService().requestDeviceInfo();
- }
- }
-
- @Override
- public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
- super.onCreateContextMenu(menu, v, menuInfo);
- AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo) menuInfo;
- selectedDevice = mGBDeviceAdapter.getItem(acmi.position);
- if (selectedDevice != null && selectedDevice.isBusy()) {
- // no context menu when device is busy
- return;
- }
- getMenuInflater().inflate(R.menu.controlcenter_context, menu);
-
- DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(selectedDevice);
- if (!coordinator.supportsActivityDataFetching()) {
- menu.removeItem(R.id.controlcenter_fetch_activity_data);
- }
- if (!coordinator.supportsScreenshots()) {
- menu.removeItem(R.id.controlcenter_take_screenshot);
- }
- if (!coordinator.supportsAlarmConfiguration()) {
- menu.removeItem(R.id.controlcenter_configure_alarms);
- }
- if (!coordinator.supportsActivityTracking()) {
- menu.removeItem(R.id.controlcenter_start_sleepmonitor);
- }
-
- if (selectedDevice.getState() == GBDevice.State.NOT_CONNECTED) {
- menu.removeItem(R.id.controlcenter_disconnect);
- }
- if (!selectedDevice.isInitialized()) {
- menu.removeItem(R.id.controlcenter_find_device);
- menu.removeItem(R.id.controlcenter_fetch_activity_data);
- menu.removeItem(R.id.controlcenter_configure_alarms);
- menu.removeItem(R.id.controlcenter_take_screenshot);
- }
-
- menu.setHeaderTitle(selectedDevice.getName());
- }
-
- private void enableSwipeRefresh(GBDevice device) {
- if (device == null) {
- swipeLayout.setEnabled(false);
- } else {
- DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device);
- boolean enable = coordinator.allowFetchActivityData(device);
- swipeLayout.setEnabled(enable);
- }
- }
-
- private void fetchActivityData() {
- GBDevice selectedDevice = deviceManager.getSelectedDevice();
- if (selectedDevice == null) {
- return;
- }
- if (selectedDevice.isInitialized()) {
- GBApplication.deviceService().onFetchActivityData();
- } else {
- swipeLayout.setRefreshing(false);
- GB.toast(this, getString(R.string.device_not_connected), Toast.LENGTH_SHORT, GB.ERROR);
- }
- }
-
- @Override
- public boolean onContextItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.controlcenter_start_sleepmonitor:
- if (selectedDevice != null) {
- Intent startIntent;
- startIntent = new Intent(ControlCenter.this, ChartsActivity.class);
- startIntent.putExtra(GBDevice.EXTRA_DEVICE, selectedDevice);
- startActivity(startIntent);
- }
- return true;
- case R.id.controlcenter_fetch_activity_data:
- fetchActivityData();
- return true;
- case R.id.controlcenter_disconnect:
- if (selectedDevice != null) {
- selectedDevice = null;
- GBApplication.deviceService().disconnect();
- }
- return true;
- case R.id.controlcenter_find_device:
- if (selectedDevice != null) {
- findDevice(true);
- ProgressDialog.show(
- this,
- getString(R.string.control_center_find_lost_device),
- getString(R.string.control_center_cancel_to_stop_vibration),
- true, true,
- new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- findDevice(false);
- }
- });
- }
- return true;
- case R.id.controlcenter_configure_alarms:
- if (selectedDevice != null) {
- Intent startIntent;
- startIntent = new Intent(ControlCenter.this, ConfigureAlarms.class);
- startIntent.putExtra(GBDevice.EXTRA_DEVICE, selectedDevice);
- startActivity(startIntent);
- }
- return true;
- case R.id.controlcenter_take_screenshot:
- if (selectedDevice != null) {
- GBApplication.deviceService().onScreenshotReq();
- }
- return true;
- case R.id.controlcenter_delete_device:
- if (selectedDevice != null) {
- confirmDeleteDevice(selectedDevice);
- }
- return true;
- default:
- return super.onContextItemSelected(item);
- }
- }
-
- private void findDevice(boolean start) {
- GBApplication.deviceService().onFindDevice(start);
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.menu_main, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
-
- switch (item.getItemId()) {
- case R.id.action_settings:
- Intent settingsIntent = new Intent(this, SettingsActivity.class);
- startActivity(settingsIntent);
- return true;
- case R.id.action_debug:
- Intent debugIntent = new Intent(this, DebugActivity.class);
- startActivity(debugIntent);
- return true;
- case R.id.action_db_management:
- Intent dbIntent = new Intent(this, DbManagementActivity.class);
- startActivity(dbIntent);
- return true;
- case R.id.action_quit:
- GBApplication.quit();
- return true;
- }
-
- return super.onOptionsItemSelected(item);
- }
-
- private void launchDiscoveryActivity() {
- startActivity(new Intent(this, DiscoveryActivity.class));
- }
-
- private void confirmDeleteDevice(final GBDevice gbDevice) {
- new AlertDialog.Builder(this)
- .setCancelable(true)
- .setTitle(getString(R.string.controlcenter_delete_device_name, gbDevice.getName()))
- .setMessage(R.string.controlcenter_delete_device_dialogmessage)
- .setPositiveButton(R.string.Delete, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- try {
- DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(gbDevice);
- if (coordinator != null) {
- coordinator.deleteDevice(selectedDevice);
- }
- DeviceHelper.getInstance().removeBond(selectedDevice);
- } catch (Exception ex) {
- GB.toast(ControlCenter.this, "Error deleting device: " + ex.getMessage(), Toast.LENGTH_LONG, GB.ERROR, ex);
- } finally {
- selectedDevice = null;
- Intent refreshIntent = new Intent(DeviceManager.ACTION_REFRESH_DEVICELIST);
- LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(refreshIntent);
- }
- }
- })
- .setNegativeButton(R.string.Cancel, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // do nothing
- }
- })
- .show();
- }
-
- @Override
- protected void onDestroy() {
- LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
- super.onDestroy();
- }
-
- private void refreshPairedDevices() {
- List deviceList = deviceManager.getDevices();
- GBDevice connectedDevice = null;
-
- for (GBDevice device : deviceList) {
- if (device.isConnected() || device.isConnecting()) {
- connectedDevice = device;
- break;
- }
- }
-
- if (deviceList.isEmpty()) {
- background.setVisibility(View.VISIBLE);
- } else {
- background.setVisibility(View.INVISIBLE);
- }
-
- if (connectedDevice != null) {
- DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(connectedDevice);
- hintTextView.setText(coordinator.getTapString());
- } else if (!deviceList.isEmpty()) {
- hintTextView.setText(R.string.tap_a_device_to_connect);
- }
-
- mGBDeviceAdapter.notifyDataSetChanged();
- }
-
- @TargetApi(Build.VERSION_CODES.M)
- private void checkAndRequestPermissions() {
- List wantedPermissions = new ArrayList<>();
-
- if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_DENIED)
- wantedPermissions.add(Manifest.permission.BLUETOOTH);
- if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN) == PackageManager.PERMISSION_DENIED)
- wantedPermissions.add(Manifest.permission.BLUETOOTH_ADMIN);
- if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_DENIED)
- wantedPermissions.add(Manifest.permission.READ_CONTACTS);
- if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_DENIED)
- wantedPermissions.add(Manifest.permission.CALL_PHONE);
- if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED)
- wantedPermissions.add(Manifest.permission.READ_PHONE_STATE);
- if (ContextCompat.checkSelfPermission(this, Manifest.permission.PROCESS_OUTGOING_CALLS) == PackageManager.PERMISSION_DENIED)
- wantedPermissions.add(Manifest.permission.PROCESS_OUTGOING_CALLS);
- if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) == PackageManager.PERMISSION_DENIED)
- wantedPermissions.add(Manifest.permission.READ_SMS);
- if (ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_DENIED)
- wantedPermissions.add(Manifest.permission.SEND_SMS);
- if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED)
- wantedPermissions.add(Manifest.permission.READ_EXTERNAL_STORAGE);
- if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_DENIED)
- wantedPermissions.add(Manifest.permission.READ_CALENDAR);
-
- if (!wantedPermissions.isEmpty())
- ActivityCompat.requestPermissions(this, wantedPermissions.toArray(new String[wantedPermissions.size()]), 0);
- }
-
-
-}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java
new file mode 100644
index 000000000..cfd4ed154
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenterv2.java
@@ -0,0 +1,284 @@
+package nodomain.freeyourgadget.gadgetbridge.activities;
+
+import android.Manifest;
+import android.annotation.TargetApi;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.graphics.Canvas;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.design.widget.FloatingActionButton;
+import android.support.design.widget.NavigationView;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.ContextCompat;
+import android.support.v4.content.LocalBroadcastManager;
+import android.support.v4.view.GravityCompat;
+import android.support.v4.widget.DrawerLayout;
+import android.support.v7.app.ActionBarDrawerToggle;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.app.AppCompatDelegate;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.Toolbar;
+import android.support.v7.widget.helper.ItemTouchHelper;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import de.cketti.library.changelog.ChangeLog;
+import nodomain.freeyourgadget.gadgetbridge.GBApplication;
+import nodomain.freeyourgadget.gadgetbridge.R;
+import nodomain.freeyourgadget.gadgetbridge.adapter.GBDeviceAdapterv2;
+import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager;
+import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
+import nodomain.freeyourgadget.gadgetbridge.util.GB;
+import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
+
+//TODO: extend GBActivity, but it requires actionbar that is not available
+public class ControlCenterv2 extends AppCompatActivity
+ implements NavigationView.OnNavigationItemSelectedListener {
+
+ //needed for KK compatibility
+ static {
+ AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
+ }
+
+ private DeviceManager deviceManager;
+ private ImageView background;
+
+ private List deviceList;
+ private GBDeviceAdapterv2 mGBDeviceAdapter;
+ private RecyclerView deviceListView;
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ switch (action) {
+ case GBApplication.ACTION_QUIT:
+ finish();
+ break;
+ case DeviceManager.ACTION_DEVICES_CHANGED:
+ refreshPairedDevices();
+ break;
+ }
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ if (GBApplication.isDarkThemeEnabled()) {
+ setTheme(R.style.GadgetbridgeThemeDark_NoActionBar);
+ } else {
+ setTheme(R.style.GadgetbridgeTheme_NoActionBar);
+ }
+
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_controlcenterv2);
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
+
+ FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
+ fab.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ launchDiscoveryActivity();
+ }
+ });
+
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
+ this, drawer, toolbar, R.string.controlcenter_navigation_drawer_open, R.string.controlcenter_navigation_drawer_close);
+ drawer.setDrawerListener(toggle);
+ toggle.syncState();
+
+ NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
+ navigationView.setNavigationItemSelectedListener(this);
+
+ //end of material design boilerplate
+ deviceManager = ((GBApplication) getApplication()).getDeviceManager();
+
+ deviceListView = (RecyclerView) findViewById(R.id.deviceListView);
+ deviceListView.setHasFixedSize(true);
+ deviceListView.setLayoutManager(new LinearLayoutManager(this));
+ background = (ImageView) findViewById(R.id.no_items_bg);
+
+ deviceList = deviceManager.getDevices();
+ mGBDeviceAdapter = new GBDeviceAdapterv2(this, deviceList);
+
+ deviceListView.setAdapter(this.mGBDeviceAdapter);
+
+ ItemTouchHelper swipeToDismissTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
+ ItemTouchHelper.LEFT , ItemTouchHelper.RIGHT) {
+ @Override
+ public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
+ if(dX>50)
+ dX = 50;
+ super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
+
+ }
+
+ @Override
+ public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
+ GB.toast(getBaseContext(), "onMove", Toast.LENGTH_LONG, GB.ERROR);
+
+ return false;
+ }
+
+ @Override
+ public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
+ GB.toast(getBaseContext(), "onSwiped", Toast.LENGTH_LONG, GB.ERROR);
+
+ }
+
+ @Override
+ public void onChildDrawOver(Canvas c, RecyclerView recyclerView,
+ RecyclerView.ViewHolder viewHolder, float dX, float dY,
+ int actionState, boolean isCurrentlyActive) {
+ }
+ });
+
+ //uncomment to enable fixed-swipe to reveal more actions
+ //swipeToDismissTouchHelper.attachToRecyclerView(deviceListView);
+
+
+ registerForContextMenu(deviceListView);
+
+ IntentFilter filterLocal = new IntentFilter();
+ filterLocal.addAction(GBApplication.ACTION_QUIT);
+ filterLocal.addAction(DeviceManager.ACTION_DEVICES_CHANGED);
+ LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filterLocal);
+
+ refreshPairedDevices();
+
+ /*
+ * Ask for permission to intercept notifications on first run.
+ */
+ Prefs prefs = GBApplication.getPrefs();
+ if (prefs.getBoolean("firstrun", true)) {
+ prefs.getPreferences().edit().putBoolean("firstrun", false).apply();
+ Intent enableIntent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
+ startActivity(enableIntent);
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ checkAndRequestPermissions();
+ }
+
+ ChangeLog cl = new ChangeLog(this);
+ if (cl.isFirstRun()) {
+ cl.getLogDialog().show();
+ }
+
+ GBApplication.deviceService().start();
+
+ if (GB.isBluetoothEnabled() && deviceList.isEmpty() && Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+ startActivity(new Intent(this, DiscoveryActivity.class));
+ } else {
+ GBApplication.deviceService().requestDeviceInfo();
+ }
+ }
+
+ @Override
+ public void onBackPressed() {
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ if (drawer.isDrawerOpen(GravityCompat.START)) {
+ drawer.closeDrawer(GravityCompat.START);
+ } else {
+ super.onBackPressed();
+ }
+ }
+
+ @Override
+ public boolean onNavigationItemSelected(MenuItem item) {
+
+ DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
+ drawer.closeDrawer(GravityCompat.START);
+
+ switch (item.getItemId()) {
+ case R.id.action_settings:
+ Intent settingsIntent = new Intent(this, SettingsActivity.class);
+ startActivity(settingsIntent);
+ return true;
+ case R.id.action_debug:
+ Intent debugIntent = new Intent(this, DebugActivity.class);
+ startActivity(debugIntent);
+ return true;
+ case R.id.action_db_management:
+ Intent dbIntent = new Intent(this, DbManagementActivity.class);
+ startActivity(dbIntent);
+ return true;
+ case R.id.action_quit:
+ GBApplication.quit();
+ return true;
+ case R.id.external_changelog:
+ ChangeLog cl = new ChangeLog(this);
+ cl.getFullLogDialog().show();
+ return true;
+ }
+
+ return true;
+ }
+
+ private void launchDiscoveryActivity() {
+ startActivity(new Intent(this, DiscoveryActivity.class));
+ }
+
+ private void refreshPairedDevices() {
+ List deviceList = deviceManager.getDevices();
+ GBDevice connectedDevice = null;
+
+ for (GBDevice device : deviceList) {
+ if (device.isConnected() || device.isConnecting()) {
+ connectedDevice = device;
+ break;
+ }
+ }
+
+ if (deviceList.isEmpty()) {
+ background.setVisibility(View.VISIBLE);
+ } else {
+ background.setVisibility(View.INVISIBLE);
+ }
+
+ mGBDeviceAdapter.notifyDataSetChanged();
+ }
+
+ @TargetApi(Build.VERSION_CODES.M)
+ private void checkAndRequestPermissions() {
+ List wantedPermissions = new ArrayList<>();
+
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_DENIED)
+ wantedPermissions.add(Manifest.permission.BLUETOOTH);
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN) == PackageManager.PERMISSION_DENIED)
+ wantedPermissions.add(Manifest.permission.BLUETOOTH_ADMIN);
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_DENIED)
+ wantedPermissions.add(Manifest.permission.READ_CONTACTS);
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_DENIED)
+ wantedPermissions.add(Manifest.permission.CALL_PHONE);
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_DENIED)
+ wantedPermissions.add(Manifest.permission.READ_PHONE_STATE);
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.PROCESS_OUTGOING_CALLS) == PackageManager.PERMISSION_DENIED)
+ wantedPermissions.add(Manifest.permission.PROCESS_OUTGOING_CALLS);
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) == PackageManager.PERMISSION_DENIED)
+ wantedPermissions.add(Manifest.permission.READ_SMS);
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_DENIED)
+ wantedPermissions.add(Manifest.permission.SEND_SMS);
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED)
+ wantedPermissions.add(Manifest.permission.READ_EXTERNAL_STORAGE);
+ if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_DENIED)
+ wantedPermissions.add(Manifest.permission.READ_CALENDAR);
+ if (ContextCompat.checkSelfPermission(this, "com.fsck.k9.permission.READ_MESSAGES") == PackageManager.PERMISSION_DENIED)
+ wantedPermissions.add("com.fsck.k9.permission.READ_MESSAGES");
+
+ if (!wantedPermissions.isEmpty())
+ ActivityCompat.requestPermissions(this, wantedPermissions.toArray(new String[wantedPermissions.size()]), 0);
+ }
+
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapter.java
deleted file mode 100644
index 42661e8b2..000000000
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapter.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/* Copyright (C) 2015-2017 Andreas Shimokawa, Carsten Pfeiffer, Daniele
- Gobbetti, João Paulo Barraca, Lem Dulfo
-
- This file is part of Gadgetbridge.
-
- Gadgetbridge is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Gadgetbridge is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see . */
-package nodomain.freeyourgadget.gadgetbridge.adapter;
-
-import android.content.Context;
-import android.graphics.Color;
-import android.support.v4.content.ContextCompat;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import java.util.Collections;
-import java.util.List;
-
-import nodomain.freeyourgadget.gadgetbridge.R;
-import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
-import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
-import nodomain.freeyourgadget.gadgetbridge.model.ItemWithDetails;
-
-/**
- * Adapter for displaying GBDevice instances.
- */
-public class GBDeviceAdapter extends ArrayAdapter {
-
- private final Context context;
-
- public GBDeviceAdapter(Context context, List deviceList) {
- super(context, 0, deviceList);
-
- this.context = context;
- }
-
- @Override
- public View getView(int position, View view, ViewGroup parent) {
- final GBDevice device = getItem(position);
-
- if (view == null) {
- LayoutInflater inflater = (LayoutInflater) context
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- view = inflater.inflate(R.layout.device_item, parent, false);
- }
- TextView deviceStatusLabel = (TextView) view.findViewById(R.id.device_status);
- TextView deviceNameLabel = (TextView) view.findViewById(R.id.device_name);
- final ListView deviceInfoList = (ListView) view.findViewById(R.id.device_item_infos);
- ItemWithDetailsAdapter infoAdapter = new ItemWithDetailsAdapter(context, device.getDeviceInfos());
- infoAdapter.setHorizontalAlignment(true);
- deviceInfoList.setAdapter(infoAdapter);
- TextView batteryLabel = (TextView) view.findViewById(R.id.battery_label);
- TextView batteryStatusLabel = (TextView) view.findViewById(R.id.battery_status);
- final ImageView deviceImageView = (ImageView) view.findViewById(R.id.device_image);
- ImageView deviceInfoView = (ImageView) view.findViewById(R.id.device_info_image);
- ProgressBar busyIndicator = (ProgressBar) view.findViewById(R.id.device_busy_indicator);
-
- deviceNameLabel.setText(getUniqueDeviceName(device));
-
- if (device.isBusy()) {
- deviceStatusLabel.setText(device.getBusyTask());
- busyIndicator.setVisibility(View.VISIBLE);
- batteryLabel.setVisibility(View.INVISIBLE);
- batteryStatusLabel.setVisibility(View.INVISIBLE);
- } else {
- deviceStatusLabel.setText(device.getStateString());
- busyIndicator.setVisibility(View.INVISIBLE);
- batteryLabel.setVisibility(View.VISIBLE);
- batteryStatusLabel.setVisibility(View.VISIBLE);
- }
-
- boolean showInfoIcon = device.hasDeviceInfos() && !device.isBusy();
- deviceInfoView.setVisibility(showInfoIcon ? View.VISIBLE : View.GONE);
- deviceInfoView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (deviceInfoList.getVisibility() == View.VISIBLE) {
- deviceInfoList.setVisibility(View.GONE);
- } else {
- ArrayAdapter adapter = (ArrayAdapter) deviceInfoList.getAdapter();
- adapter.clear();
- List infos = device.getDeviceInfos();
- Collections.sort(infos);
- adapter.addAll(infos);
- justifyListViewHeightBasedOnChildren(deviceInfoList);
- deviceInfoList.setVisibility(View.VISIBLE);
- deviceInfoList.setFocusable(false);
- }
- }
- });
-
- short batteryLevel = device.getBatteryLevel();
- if (batteryLevel != GBDevice.BATTERY_UNKNOWN) {
- batteryLabel.setText("BAT:");
- batteryStatusLabel.setText(device.getBatteryLevel() + "%");
- BatteryState batteryState = device.getBatteryState();
- if (BatteryState.BATTERY_LOW.equals(batteryState)) {
- batteryLabel.setTextColor(Color.RED);
- batteryStatusLabel.setTextColor(Color.RED);
- } else {
- batteryLabel.setTextColor(ContextCompat.getColor(getContext(), R.color.secondarytext));
- batteryStatusLabel.setTextColor(ContextCompat.getColor(getContext(), R.color.secondarytext));
-
- if (BatteryState.BATTERY_CHARGING.equals(batteryState) ||
- BatteryState.BATTERY_CHARGING_FULL.equals(batteryState)) {
- batteryStatusLabel.append(" CHG");
- }
- }
- } else {
- batteryLabel.setText("");
- batteryStatusLabel.setText("");
- }
-
- if (device.isConnected()) {
- deviceImageView.setImageResource(device.getType().getIcon());
- } else {
- deviceImageView.setImageResource(device.getType().getDisabledIcon());
- }
-
- return view;
- }
-
- public void justifyListViewHeightBasedOnChildren(ListView listView) {
- ArrayAdapter adapter = (ArrayAdapter) listView.getAdapter();
-
- if (adapter == null) {
- return;
- }
- ViewGroup vg = listView;
- int totalHeight = 0;
- for (int i = 0; i < adapter.getCount(); i++) {
- View listItem = adapter.getView(i, null, vg);
- listItem.measure(0, 0);
- totalHeight += listItem.getMeasuredHeight();
- }
-
- ViewGroup.LayoutParams par = listView.getLayoutParams();
- par.height = totalHeight + (listView.getDividerHeight() * (adapter.getCount() - 1));
- listView.setLayoutParams(par);
- listView.requestLayout();
- }
-
- private String getUniqueDeviceName(GBDevice device) {
- String deviceName = device.getName();
- if (!isUniqueDeviceName(device, deviceName)) {
- if (device.getModel() != null) {
- deviceName = deviceName + " " + device.getModel();
- if (!isUniqueDeviceName(device, deviceName)) {
- deviceName = deviceName + " " + device.getShortAddress();
- }
- } else {
- deviceName = deviceName + " " + device.getShortAddress();
- }
- }
- return deviceName;
- }
-
- private boolean isUniqueDeviceName(GBDevice device, String deviceName) {
- for (int i = 0; i < getCount(); i++) {
- GBDevice item = getItem(i);
- if (item == device) {
- continue;
- }
- if (deviceName.equals(item.getName())) {
- return false;
- }
- }
- return true;
- }
-}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java
new file mode 100644
index 000000000..c92d63348
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAdapterv2.java
@@ -0,0 +1,413 @@
+package nodomain.freeyourgadget.gadgetbridge.adapter;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.support.design.widget.Snackbar;
+import android.support.v4.content.LocalBroadcastManager;
+import android.support.v7.widget.CardView;
+import android.support.v7.widget.RecyclerView;
+import android.transition.TransitionManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.ProgressBar;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.List;
+
+import nodomain.freeyourgadget.gadgetbridge.GBApplication;
+import nodomain.freeyourgadget.gadgetbridge.R;
+import nodomain.freeyourgadget.gadgetbridge.activities.ConfigureAlarms;
+import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity;
+import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
+import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager;
+import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
+import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
+import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
+import nodomain.freeyourgadget.gadgetbridge.util.GB;
+
+/**
+ * Adapter for displaying GBDevice instances.
+ */
+public class GBDeviceAdapterv2 extends RecyclerView.Adapter {
+
+ private final Context context;
+ private List deviceList;
+ private int expandedDevicePosition = RecyclerView.NO_POSITION;
+ private ViewGroup parent;
+
+ public GBDeviceAdapterv2(Context context, List deviceList) {
+ this.context = context;
+ this.deviceList = deviceList;
+ }
+
+ @Override
+ public GBDeviceAdapterv2.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ this.parent = parent;
+ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.device_itemv2, parent, false);
+ ViewHolder vh = new ViewHolder(view);
+ return vh;
+ }
+
+ @Override
+ public void onBindViewHolder(ViewHolder holder, final int position) {
+ final GBDevice device = deviceList.get(position);
+ DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device);
+
+ holder.container.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ if (device.isInitialized() || device.isConnected()) {
+ showTransientSnackbar(R.string.controlcenter_snackbar_need_longpress);
+ } else {
+ showTransientSnackbar(R.string.controlcenter_snackbar_connecting);
+ GBApplication.deviceService().connect(device);
+ }
+ }
+ });
+
+ holder.container.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ if (device.isInitialized() || device.isConnected()) {
+ showTransientSnackbar(R.string.controlcenter_snackbar_disconnecting);
+ GBApplication.deviceService().disconnect();
+ }
+ return true;
+ }
+ });
+ holder.deviceImageView.setImageResource(R.drawable.level_list_device);
+ //level-list does not allow negative values, hence we always add 100 to the key.
+ holder.deviceImageView.setImageLevel(device.getType().getKey() + 100 + (device.isInitialized() ? 100 : 0));
+
+ holder.deviceNameLabel.setText(getUniqueDeviceName(device));
+
+ if (device.isBusy()) {
+ holder.deviceStatusLabel.setText(device.getBusyTask());
+ holder.busyIndicator.setVisibility(View.VISIBLE);
+ } else {
+ holder.deviceStatusLabel.setText(device.getStateString());
+ holder.busyIndicator.setVisibility(View.INVISIBLE);
+ }
+
+ //begin of action row
+ //battery
+ holder.batteryStatusBox.setVisibility(View.GONE);
+ short batteryLevel = device.getBatteryLevel();
+ if (batteryLevel != GBDevice.BATTERY_UNKNOWN) {
+ holder.batteryStatusBox.setVisibility(View.VISIBLE);
+ holder.batteryStatusLabel.setText(device.getBatteryLevel() + "%");
+ BatteryState batteryState = device.getBatteryState();
+ if (BatteryState.BATTERY_CHARGING.equals(batteryState) ||
+ BatteryState.BATTERY_CHARGING_FULL.equals(batteryState)) {
+ holder.batteryIcon.setImageLevel(device.getBatteryLevel() + 100);
+ } else {
+ holder.batteryIcon.setImageLevel(device.getBatteryLevel());
+ }
+ }
+
+ //fetch activity data
+ holder.fetchActivityDataBox.setVisibility((device.isInitialized() && coordinator.supportsActivityDataFetching()) ? View.VISIBLE : View.GONE);
+ holder.fetchActivityData.setOnClickListener(new View.OnClickListener()
+
+ {
+ @Override
+ public void onClick(View v) {
+ showTransientSnackbar(R.string.busy_task_fetch_activity_data);
+ GBApplication.deviceService().onFetchActivityData();
+ }
+ }
+ );
+
+
+ //take screenshot
+ holder.takeScreenshotView.setVisibility((device.isInitialized() && coordinator.supportsScreenshots()) ? View.VISIBLE : View.GONE);
+ holder.takeScreenshotView.setOnClickListener(new View.OnClickListener()
+
+ {
+ @Override
+ public void onClick(View v) {
+ showTransientSnackbar(R.string.controlcenter_snackbar_requested_screenshot);
+ GBApplication.deviceService().onScreenshotReq();
+ }
+ }
+ );
+
+ //manage apps
+ holder.manageAppsView.setVisibility((device.isInitialized() && coordinator.supportsAppsManagement()) ? View.VISIBLE : View.GONE);
+ holder.manageAppsView.setOnClickListener(new View.OnClickListener()
+
+ {
+ @Override
+ public void onClick(View v) {
+ DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device);
+ Class extends Activity> appsManagementActivity = coordinator.getAppsManagementActivity();
+ if (appsManagementActivity != null) {
+ Intent startIntent = new Intent(context, appsManagementActivity);
+ startIntent.putExtra(GBDevice.EXTRA_DEVICE, device);
+ context.startActivity(startIntent);
+ }
+ }
+ }
+ );
+
+ //set alarms
+ holder.setAlarmsView.setVisibility(coordinator.supportsAlarmConfiguration() ? View.VISIBLE : View.GONE);
+ holder.setAlarmsView.setOnClickListener(new View.OnClickListener()
+
+ {
+ @Override
+ public void onClick(View v) {
+ Intent startIntent;
+ startIntent = new Intent(context, ConfigureAlarms.class);
+ context.startActivity(startIntent);
+ }
+ }
+ );
+
+ //show graphs
+ holder.showActivityGraphs.setVisibility(coordinator.supportsActivityTracking() ? View.VISIBLE : View.GONE);
+ holder.showActivityGraphs.setOnClickListener(new View.OnClickListener()
+
+ {
+ @Override
+ public void onClick(View v) {
+ Intent startIntent;
+ startIntent = new Intent(context, ChartsActivity.class);
+ startIntent.putExtra(GBDevice.EXTRA_DEVICE, device);
+ context.startActivity(startIntent);
+ }
+ }
+ );
+
+ ItemWithDetailsAdapter infoAdapter = new ItemWithDetailsAdapter(context, device.getDeviceInfos());
+ infoAdapter.setHorizontalAlignment(true);
+ holder.deviceInfoList.setAdapter(infoAdapter);
+ justifyListViewHeightBasedOnChildren(holder.deviceInfoList);
+ holder.deviceInfoList.setFocusable(false);
+
+ final boolean detailsShown = position == expandedDevicePosition;
+ boolean showInfoIcon = device.hasDeviceInfos() && !device.isBusy();
+ holder.deviceInfoView.setVisibility(showInfoIcon ? View.VISIBLE : View.GONE);
+ holder.deviceInfoBox.setActivated(detailsShown);
+ holder.deviceInfoBox.setVisibility(detailsShown ? View.VISIBLE : View.GONE);
+ holder.deviceInfoView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ expandedDevicePosition = detailsShown ? -1 : position;
+ TransitionManager.beginDelayedTransition(parent);
+ notifyDataSetChanged();
+ }
+ }
+
+ );
+
+ holder.findDevice.setVisibility(device.isInitialized() ? View.VISIBLE : View.GONE);
+ holder.findDevice.setOnClickListener(new View.OnClickListener()
+
+ {
+ @Override
+ public void onClick(View v) {
+ GBApplication.deviceService().onFindDevice(true);
+ //TODO: extract string resource if we like this solution.
+ Snackbar.make(parent, R.string.control_center_find_lost_device, Snackbar.LENGTH_INDEFINITE).setAction("Found it!", new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ GBApplication.deviceService().onFindDevice(false);
+ }
+ }).setCallback(new Snackbar.Callback() {
+ @Override
+ public void onDismissed(Snackbar snackbar, int event) {
+ GBApplication.deviceService().onFindDevice(false);
+ super.onDismissed(snackbar, event);
+ }
+ }).show();
+// ProgressDialog.show(
+// context,
+// context.getString(R.string.control_center_find_lost_device),
+// context.getString(R.string.control_center_cancel_to_stop_vibration),
+// true, true,
+// new DialogInterface.OnCancelListener() {
+// @Override
+// public void onCancel(DialogInterface dialog) {
+// GBApplication.deviceService().onFindDevice(false);
+// }
+// });
+ }
+ }
+
+ );
+
+ //remove device, hidden under details
+ holder.removeDevice.setOnClickListener(new View.OnClickListener()
+
+ {
+ @Override
+ public void onClick(View v) {
+ new AlertDialog.Builder(context)
+ .setCancelable(true)
+ .setTitle(context.getString(R.string.controlcenter_delete_device_name, device.getName()))
+ .setMessage(R.string.controlcenter_delete_device_dialogmessage)
+ .setPositiveButton(R.string.Delete, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ try {
+ DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device);
+ if (coordinator != null) {
+ coordinator.deleteDevice(device);
+ }
+ DeviceHelper.getInstance().removeBond(device);
+ } catch (Exception ex) {
+ GB.toast(context, "Error deleting device: " + ex.getMessage(), Toast.LENGTH_LONG, GB.ERROR, ex);
+ } finally {
+ Intent refreshIntent = new Intent(DeviceManager.ACTION_REFRESH_DEVICELIST);
+ LocalBroadcastManager.getInstance(context).sendBroadcast(refreshIntent);
+ }
+ }
+ })
+ .setNegativeButton(R.string.Cancel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // do nothing
+ }
+ })
+ .show();
+ }
+ });
+
+ }
+
+ @Override
+ public int getItemCount() {
+ return deviceList.size();
+ }
+
+ static class ViewHolder extends RecyclerView.ViewHolder {
+
+ CardView container;
+
+ ImageView deviceImageView;
+ TextView deviceNameLabel;
+ TextView deviceStatusLabel;
+
+ //actions
+ LinearLayout batteryStatusBox;
+ TextView batteryStatusLabel;
+ ImageView batteryIcon;
+ LinearLayout fetchActivityDataBox;
+ ImageView fetchActivityData;
+ ProgressBar busyIndicator;
+ ImageView takeScreenshotView;
+ ImageView manageAppsView;
+ ImageView setAlarmsView;
+ ImageView showActivityGraphs;
+
+ ImageView deviceInfoView;
+ //overflow
+ final RelativeLayout deviceInfoBox;
+ ListView deviceInfoList;
+ ImageView findDevice;
+ ImageView removeDevice;
+
+ ViewHolder(View view) {
+ super(view);
+ container = (CardView) view.findViewById(R.id.card_view);
+
+ deviceImageView = (ImageView) view.findViewById(R.id.device_image);
+ deviceNameLabel = (TextView) view.findViewById(R.id.device_name);
+ deviceStatusLabel = (TextView) view.findViewById(R.id.device_status);
+
+ //actions
+ batteryStatusBox = (LinearLayout) view.findViewById(R.id.device_battery_status_box);
+ batteryStatusLabel = (TextView) view.findViewById(R.id.battery_status);
+ batteryIcon = (ImageView) view.findViewById(R.id.device_battery_status);
+ fetchActivityDataBox = (LinearLayout) view.findViewById(R.id.device_action_fetch_activity_box);
+ fetchActivityData = (ImageView) view.findViewById(R.id.device_action_fetch_activity);
+ busyIndicator = (ProgressBar) view.findViewById(R.id.device_busy_indicator);
+ takeScreenshotView = (ImageView) view.findViewById(R.id.device_action_take_screenshot);
+ manageAppsView = (ImageView) view.findViewById(R.id.device_action_manage_apps);
+ setAlarmsView = (ImageView) view.findViewById(R.id.device_action_set_alarms);
+ showActivityGraphs = (ImageView) view.findViewById(R.id.device_action_show_activity_graphs);
+ deviceInfoView = (ImageView) view.findViewById(R.id.device_info_image);
+
+ deviceInfoBox = (RelativeLayout) view.findViewById(R.id.device_item_infos_box);
+ //overflow
+ deviceInfoList = (ListView) view.findViewById(R.id.device_item_infos);
+ findDevice = (ImageView) view.findViewById(R.id.device_action_find);
+ removeDevice = (ImageView) view.findViewById(R.id.device_action_remove);
+ }
+
+ }
+
+ public void justifyListViewHeightBasedOnChildren(ListView listView) {
+ ArrayAdapter adapter = (ArrayAdapter) listView.getAdapter();
+
+ if (adapter == null) {
+ return;
+ }
+ ViewGroup vg = listView;
+ int totalHeight = 0;
+ for (int i = 0; i < adapter.getCount(); i++) {
+ View listItem = adapter.getView(i, null, vg);
+ listItem.measure(0, 0);
+ totalHeight += listItem.getMeasuredHeight();
+ }
+
+ ViewGroup.LayoutParams par = listView.getLayoutParams();
+ par.height = totalHeight + (listView.getDividerHeight() * (adapter.getCount() - 1));
+ listView.setLayoutParams(par);
+ listView.requestLayout();
+ }
+
+ private String getUniqueDeviceName(GBDevice device) {
+ String deviceName = device.getName();
+ if (!isUniqueDeviceName(device, deviceName)) {
+ if (device.getModel() != null) {
+ deviceName = deviceName + " " + device.getModel();
+ if (!isUniqueDeviceName(device, deviceName)) {
+ deviceName = deviceName + " " + device.getShortAddress();
+ }
+ } else {
+ deviceName = deviceName + " " + device.getShortAddress();
+ }
+ }
+ return deviceName;
+ }
+
+ private boolean isUniqueDeviceName(GBDevice device, String deviceName) {
+ for (int i = 0; i < deviceList.size(); i++) {
+ GBDevice item = deviceList.get(i);
+ if (item == device) {
+ continue;
+ }
+ if (deviceName.equals(item.getName())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private void showTransientSnackbar(int resource) {
+ Snackbar snackbar = Snackbar.make(parent, resource, Snackbar.LENGTH_SHORT);
+
+ View snackbarView = snackbar.getView();
+
+// change snackbar text color
+ int snackbarTextId = android.support.design.R.id.snackbar_text;
+ TextView textView = (TextView) snackbarView.findViewById(snackbarTextId);
+ //textView.setTextColor();
+ //snackbarView.setBackgroundColor(Color.MAGENTA);
+ snackbar.show();
+ }
+
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java
index e24315689..9451190e6 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java
@@ -26,7 +26,7 @@ import android.support.annotation.Nullable;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBException;
-import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter;
+import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenterv2;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
@@ -114,7 +114,7 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator {
@Override
public Class extends Activity> getPairingActivity() {
- return ControlCenter.class;
+ return ControlCenterv2.class;
}
@Override
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java
index c3b1348e5..5e5a33f33 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java
@@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
-import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter;
+import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenterv2;
import nodomain.freeyourgadget.gadgetbridge.activities.DiscoveryActivity;
import nodomain.freeyourgadget.gadgetbridge.activities.GBActivity;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
@@ -219,7 +219,7 @@ public class MiBandPairingActivity extends GBActivity {
Prefs prefs = GBApplication.getPrefs();
prefs.getPreferences().edit().putString(MiBandConst.PREF_MIBAND_ADDRESS, macAddress).apply();
}
- Intent intent = new Intent(this, ControlCenter.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ Intent intent = new Intent(this, ControlCenterv2.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
finish();
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebblePairingActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebblePairingActivity.java
index cb7833f21..017a60504 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebblePairingActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebblePairingActivity.java
@@ -23,7 +23,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
-import android.os.Parcelable;
import android.support.v4.content.LocalBroadcastManager;
import android.widget.TextView;
import android.widget.Toast;
@@ -36,7 +35,7 @@ import java.util.List;
import de.greenrobot.dao.query.Query;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
-import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter;
+import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenterv2;
import nodomain.freeyourgadget.gadgetbridge.activities.DiscoveryActivity;
import nodomain.freeyourgadget.gadgetbridge.activities.GBActivity;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
@@ -184,7 +183,7 @@ public class PebblePairingActivity extends GBActivity {
unregisterReceiver(mBondingReceiver);
if (pairedSuccessfully) {
- Intent intent = new Intent(this, ControlCenter.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ Intent intent = new Intent(this, ControlCenterv2.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
finish();
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java
index 3a0863037..fc2f1ae4b 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java
@@ -43,7 +43,7 @@ import java.nio.ByteOrder;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.GBEnvironment;
import nodomain.freeyourgadget.gadgetbridge.R;
-import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter;
+import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenterv2;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventScreenshot;
public class GB {
@@ -66,7 +66,7 @@ public class GB {
if (env().isLocalTest()) {
return null;
}
- Intent notificationIntent = new Intent(context, ControlCenter.class);
+ Intent notificationIntent = new Intent(context, ControlCenterv2.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
@@ -265,7 +265,7 @@ public class GB {
private static Notification createTransferNotification(String text, boolean ongoing,
int percentage, Context context) {
- Intent notificationIntent = new Intent(context, ControlCenter.class);
+ Intent notificationIntent = new Intent(context, ControlCenterv2.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
@@ -306,7 +306,7 @@ public class GB {
private static Notification createInstallNotification(String text, boolean ongoing,
int percentage, Context context) {
- Intent notificationIntent = new Intent(context, ControlCenter.class);
+ Intent notificationIntent = new Intent(context, ControlCenterv2.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
@@ -336,7 +336,7 @@ public class GB {
}
private static Notification createBatteryNotification(String text, String bigText, Context context) {
- Intent notificationIntent = new Intent(context, ControlCenter.class);
+ Intent notificationIntent = new Intent(context, ControlCenterv2.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
diff --git a/app/src/main/res/drawable/ic_action_fetch_activity_data.xml b/app/src/main/res/drawable/ic_action_fetch_activity_data.xml
new file mode 100644
index 000000000..8229a9a64
--- /dev/null
+++ b/app/src/main/res/drawable/ic_action_fetch_activity_data.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_action_find_lost_device.xml b/app/src/main/res/drawable/ic_action_find_lost_device.xml
new file mode 100644
index 000000000..74f549430
--- /dev/null
+++ b/app/src/main/res/drawable/ic_action_find_lost_device.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_action_manage_apps.xml b/app/src/main/res/drawable/ic_action_manage_apps.xml
new file mode 100644
index 000000000..8a894a3bc
--- /dev/null
+++ b/app/src/main/res/drawable/ic_action_manage_apps.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_activity_graphs.xml b/app/src/main/res/drawable/ic_activity_graphs.xml
new file mode 100644
index 000000000..5048a587e
--- /dev/null
+++ b/app/src/main/res/drawable/ic_activity_graphs.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_battery_20.xml b/app/src/main/res/drawable/ic_battery_20.xml
new file mode 100644
index 000000000..d9a1e6468
--- /dev/null
+++ b/app/src/main/res/drawable/ic_battery_20.xml
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_battery_50.xml b/app/src/main/res/drawable/ic_battery_50.xml
new file mode 100644
index 000000000..8236b239c
--- /dev/null
+++ b/app/src/main/res/drawable/ic_battery_50.xml
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_battery_80.xml b/app/src/main/res/drawable/ic_battery_80.xml
new file mode 100644
index 000000000..600ad7784
--- /dev/null
+++ b/app/src/main/res/drawable/ic_battery_80.xml
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_battery_charging_20.xml b/app/src/main/res/drawable/ic_battery_charging_20.xml
new file mode 100644
index 000000000..c3bf3b703
--- /dev/null
+++ b/app/src/main/res/drawable/ic_battery_charging_20.xml
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_battery_charging_50.xml b/app/src/main/res/drawable/ic_battery_charging_50.xml
new file mode 100644
index 000000000..d794783a5
--- /dev/null
+++ b/app/src/main/res/drawable/ic_battery_charging_50.xml
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_battery_charging_80.xml b/app/src/main/res/drawable/ic_battery_charging_80.xml
new file mode 100644
index 000000000..e004a0a61
--- /dev/null
+++ b/app/src/main/res/drawable/ic_battery_charging_80.xml
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_battery_charging_full.xml b/app/src/main/res/drawable/ic_battery_charging_full.xml
new file mode 100644
index 000000000..9389e7ce2
--- /dev/null
+++ b/app/src/main/res/drawable/ic_battery_charging_full.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_battery_full.xml b/app/src/main/res/drawable/ic_battery_full.xml
new file mode 100644
index 000000000..b0e57fe2c
--- /dev/null
+++ b/app/src/main/res/drawable/ic_battery_full.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_database_management.xml b/app/src/main/res/drawable/ic_database_management.xml
new file mode 100644
index 000000000..6a990aff7
--- /dev/null
+++ b/app/src/main/res/drawable/ic_database_management.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_debug.xml b/app/src/main/res/drawable/ic_debug.xml
new file mode 100644
index 000000000..c98c256a7
--- /dev/null
+++ b/app/src/main/res/drawable/ic_debug.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_device_set_alarms.xml b/app/src/main/res/drawable/ic_device_set_alarms.xml
new file mode 100644
index 000000000..5f742d33a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_device_set_alarms.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_more_vert.xml b/app/src/main/res/drawable/ic_more_vert.xml
new file mode 100644
index 000000000..5176d8a4b
--- /dev/null
+++ b/app/src/main/res/drawable/ic_more_vert.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_quit.xml b/app/src/main/res/drawable/ic_quit.xml
new file mode 100644
index 000000000..26272ab8d
--- /dev/null
+++ b/app/src/main/res/drawable/ic_quit.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_remove_device.xml b/app/src/main/res/drawable/ic_remove_device.xml
new file mode 100644
index 000000000..39e64d698
--- /dev/null
+++ b/app/src/main/res/drawable/ic_remove_device.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_screenshot.xml b/app/src/main/res/drawable/ic_screenshot.xml
new file mode 100644
index 000000000..9e2340bd2
--- /dev/null
+++ b/app/src/main/res/drawable/ic_screenshot.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_settings.xml b/app/src/main/res/drawable/ic_settings.xml
new file mode 100644
index 000000000..ace746c40
--- /dev/null
+++ b/app/src/main/res/drawable/ic_settings.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/level_list_battery.xml b/app/src/main/res/drawable/level_list_battery.xml
new file mode 100644
index 000000000..0a2d643d1
--- /dev/null
+++ b/app/src/main/res/drawable/level_list_battery.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/level_list_device.xml b/app/src/main/res/drawable/level_list_device.xml
new file mode 100644
index 000000000..7de9a84f2
--- /dev/null
+++ b/app/src/main/res/drawable/level_list_device.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/side_nav_bar.xml b/app/src/main/res/drawable/side_nav_bar.xml
new file mode 100644
index 000000000..22942cd4a
--- /dev/null
+++ b/app/src/main/res/drawable/side_nav_bar.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_controlcenter.xml b/app/src/main/res/layout/activity_controlcenter.xml
deleted file mode 100644
index 1be7d667c..000000000
--- a/app/src/main/res/layout/activity_controlcenter.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/activity_controlcenterv2.xml b/app/src/main/res/layout/activity_controlcenterv2.xml
new file mode 100644
index 000000000..8114dbf5c
--- /dev/null
+++ b/app/src/main/res/layout/activity_controlcenterv2.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_controlcenterv2_app_bar_main.xml b/app/src/main/res/layout/activity_controlcenterv2_app_bar_main.xml
new file mode 100644
index 000000000..cc01eb596
--- /dev/null
+++ b/app/src/main/res/layout/activity_controlcenterv2_app_bar_main.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_controlcenterv2_content_main.xml b/app/src/main/res/layout/activity_controlcenterv2_content_main.xml
new file mode 100644
index 000000000..0c4c48949
--- /dev/null
+++ b/app/src/main/res/layout/activity_controlcenterv2_content_main.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_db_management.xml b/app/src/main/res/layout/activity_db_management.xml
index 0bf641ccf..a66eba216 100644
--- a/app/src/main/res/layout/activity_db_management.xml
+++ b/app/src/main/res/layout/activity_db_management.xml
@@ -2,7 +2,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context="nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter">
+ tools:context="nodomain.freeyourgadget.gadgetbridge.activities.ControlCenterv2">
+ tools:context="nodomain.freeyourgadget.gadgetbridge.activities.ControlCenterv2">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/device_itemv2.xml b/app/src/main/res/layout/device_itemv2.xml
new file mode 100644
index 000000000..b2911ac86
--- /dev/null
+++ b/app/src/main/res/layout/device_itemv2.xml
@@ -0,0 +1,253 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/nav_header_main.xml b/app/src/main/res/layout/nav_header_main.xml
new file mode 100644
index 000000000..a21195320
--- /dev/null
+++ b/app/src/main/res/layout/nav_header_main.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/menu/activity_controlcenterv2_main_drawer.xml b/app/src/main/res/menu/activity_controlcenterv2_main_drawer.xml
new file mode 100644
index 000000000..588b3a839
--- /dev/null
+++ b/app/src/main/res/menu/activity_controlcenterv2_main_drawer.xml
@@ -0,0 +1,28 @@
+
+
diff --git a/app/src/main/res/menu/controlcenter_context.xml b/app/src/main/res/menu/controlcenter_context.xml
deleted file mode 100644
index 9d36933d7..000000000
--- a/app/src/main/res/menu/controlcenter_context.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml
deleted file mode 100644
index a27653150..000000000
--- a/app/src/main/res/menu/menu_main.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index da70600dc..93d322fe6 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -29,6 +29,7 @@
Disattiva il monitor del battito cardiaco
Attiva l\'applicazione meteo
Disattiva l\'applicazione meteo
+ Installa l\'applicazione \"notifiche meteo\"
Configura
Sposta in cima
@@ -44,6 +45,7 @@
Impostazioni
Impostazioni globali
Collegati al dispositivo quando il bluetooth viene acceso
+ Avvio automatico
Riconnessione automatica
Applicazione musicale preferita
Default
@@ -54,6 +56,7 @@
Chiaro
Scuro
Lingua
+ Nascondi l\'icona di Gadgetbridge nell\'area delle notifiche
L\'icona nella barra di stato e la notifica nella schermata di blocco vengono mostrate
L\'icona nella barra di stato e la notifica nella schermata di blocco non vengono mostrate
Notifiche
@@ -66,9 +69,15 @@
… anche se lo schermo è acceso
Non disturbare
Non inviare notifiche nei periodi configurati come \"non disturbare\"
+ Traslitterazione
+ Abilita questa opzione se il tuo dispositivo non supporta tutti i caratteri della tua lingua
sempre
se lo schermo è spento
mai
+ Impostazioni privacy chiamate
+ Mostra nome e numero chiamante
+ Nascondi il nome ma mostra il numero del chiamante
+ Nascondi nome e numero del chiamante
Blocca applicazioni
Messaggi preimpostati
Risposte
@@ -89,6 +98,12 @@
Attiva l\'accesso sperimentale ad applicazioni Android che usano PebbleKit
Alba e tramonto
Mostra gli orari calcolati per l\'alba e il tramonto sulla timeline
+ Rimuovi automaticamente le notifiche
+ Le notifiche vengono rimosse automaticamente dal Pebble dopo averle nascoste sul dispositivo Android
+ Impostazioni privacy
+ Notifiche normali
+ Sposta il testo delle notifiche fuori dallo schermo
+ Mostra solo l\'icona della notifica
Posizione
Acquisisci posizione
Latitudine
@@ -107,7 +122,14 @@
Se il tuo Pebble 2/LE non funziona come dovrebbe, prova a impostare un limite alla MTU (range valido 20-512)
Abilita il log delle applicazioni che girano su Pebble
Il log delle applicazioni che girano su Pebble verrà aggiunto a quello di Gadgetbridge (richiede riconessione)
+ Invia l\'ACK dei messaggi PebbleKit prematuramente
+ I messaggi inviati alle applicazioni di terze parti verranno immediatamente confermate
Tentativi di riconessione
+ Unità
+ Formato dell\'orario
+ Durata dell\'accensione dello schermo
+ Misura il battito cardiaco continuativamente
+ Impostazioni HPlus/Makibes
non connesso
in collegamento
connesso
@@ -143,6 +165,10 @@
Utilizza la funzione del sistema operativo per accoppiare il dispositivo.
Accoppia la Mi Band
Accoppiamento con %s…
+ Creazione bonding con %1$s (%2$s)
+ Impossibile completare il pairing con %1$s (%2$s)
+ Bonding in corso: %1$s (%2$s)
+ Bonding già effettuato con %1$s (%2$s), connessione in corso...
Indirizzo MAC mancante, impossibile completare l\'accoppiamento.
Impostazioni specifiche dispositivo
Impostazioni Mi Band
@@ -154,6 +180,7 @@
Dati dell\'utente non inseriti, vengono usati dati d\'esempio.
Quando la Mi Band vibra e lampeggia, dalle qualche leggero colpetto.
Installa
+ Imposta il tuo dispositivo perchè sia rilevabile. I dispositivi attualmente connessi non saranno probabilmente rilevati. Abilita i servizi di geolocalizzazione su android 6+. Disabilita Privacy Guard per Gadgetbridge, potrebbe causare crash e riavvii. Se non vedi il tuo dispositivo entro un paio di minuti, riprova dopo avere riavviato il dispositivo Android.
Nota:
Immagine dispositivo
Nome / Soprannome
@@ -213,6 +240,8 @@
Ultima ricarica: %s \n
Numero di ricariche: %s
Il tuo sonno
+ Sonno della settimana
+ Sonno di oggi, obiettivo: %1$s
Passi della settimana
Attività e sonno
Aggiornamento del Firmware...
@@ -257,6 +286,8 @@
Sfasamento dell\'orario per il device (per consentire il rilevamento del sonno per chi lavora a turni)
Mi2: formato della data
Ora
+ Attiva il display quando sollevato
+ Vengono trasferiti dati a partire dal %1$s
in attesa di riconnessione
Informazioni sull\'utilizzatore
Anno di nascita
@@ -282,6 +313,7 @@
Gestione del database
Gestione del database
Le operazioni sul database utilizzano il percorso qui sotto. \nQuesto percorso è accessibile ad altre applicazioni ed al tuo computer. \nDopo l\'esportazione il database si troverà qui (oppure copia qui il database che desideri importare):
+ Elimina database nel vecchio formato
Impossibile accedere al path esterno. Per cortesia contatta gli sviluppatori del progetto.
Esportato su: %1$s
Errore esportando il DB: %1$s
@@ -303,4 +335,14 @@
Vibrazione
+ Pairing del Pebble
+ Un avviso di pairing dovrebbe comparire sul tuo dispositivo Android. Se non succede verifica l\'area delle notifiche ed accetta questa richiesta di pairing. Dopo fai lo stesso sul tuo Pebble
+ Assicurati che questa skin sia abilitata nell\'applicazione \"Notifiche Meteo\" per ricevere informazioni meteo sul tuo Pebble.\n\nNon è necessaria nessuna ulteriore configurazione.\n\nPuoi abilitare l\'applicazione Meteo di sistema sul tuo Pebble dalla gestione applicazioni.\n\nLe watchfaces che lo supportano mostreranno il meteo automaticamente.
+ Abilita il pairing bluetooth
+ Disattiva se hai problemi di connession
+ Metrico
+ Imperiale
+ Sveglia
+ Trovato!
+ Mi2: Formato dell\'orario
diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml
new file mode 100644
index 000000000..faae1f18b
--- /dev/null
+++ b/app/src/main/res/values-v21/styles.xml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index ac484db26..4c3a59cb6 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -10,6 +10,8 @@
#000000
#ffffff
#ff808080
+ #ffd0d0d0
+ #ff606060
#1f000000
#ffab40
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index fb6e23509..8cc2ce917 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -8,4 +8,8 @@ Refer to App Widget Documentation for margin information
http://developer.android.com/guide/topics/appwidgets/index.html#CreatingLayout
-->
8dp
+
+ 16dp
+ 160dp
+ 16dp
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8846cc0bf..ee631139a 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -14,6 +14,13 @@
Delete Device
Delete %1$s
This will delete the device and all associated data!
+ Open navigation drawer
+ Close navigation drawer
+ Long press the card to disconnect
+ Disconnecting
+ Connecting
+ Taking a screenshot of the device
+
Debug
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 26eaea46a..3c1ab6bd2 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -1,9 +1,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/xml/changelog_master.xml b/app/src/main/res/xml/changelog_master.xml
index 30d16c40a..d8314326c 100644
--- a/app/src/main/res/xml/changelog_master.xml
+++ b/app/src/main/res/xml/changelog_master.xml
@@ -1,6 +1,7 @@
+ All new GUI for the control center
Add Portuguese pt_PT and pt_BR translations
Add Czech translation
Add Hebrew translation and transliteration