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 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 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 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 @@ + + + + + + + +