/* Copyright (C) 2016-2017 Andreas Shimokawa, Carsten Pfeiffer, Daniele Gobbetti 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.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.annotation.NonNull; 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 java.util.Locale; 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.AndroidUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import static de.cketti.library.changelog.ChangeLog.DEFAULT_CSS; //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_LANGUAGE_CHANGE: setLanguage(GBApplication.getLanguage()); break; 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_LANGUAGE_CHANGE); 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, (GBApplication.isDarkThemeEnabled() ? "body { color: #ffffff; background-color: #282828; }\n" : "") + DEFAULT_CSS); 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 protected void onDestroy() { unregisterForContextMenu(deviceListView); LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver); super.onDestroy(); } @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(@NonNull 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, (GBApplication.isDarkThemeEnabled() ? "body { color: #ffffff; background-color: #282828; }\n" : "") + DEFAULT_CSS); cl.getFullLogDialog().show(); return true; } return true; } private void launchDiscoveryActivity() { startActivity(new Intent(this, DiscoveryActivity.class)); } private void refreshPairedDevices() { List deviceList = deviceManager.getDevices(); 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 (!wantedPermissions.isEmpty()) ActivityCompat.requestPermissions(this, wantedPermissions.toArray(new String[wantedPermissions.size()]), 0); } private void setLanguage(Locale language) { AndroidUtils.setLanguage(this, language); } }