Skip to content

Commit

Permalink
- Added shortcut to vibrate the current time
Browse files Browse the repository at this point in the history
- Increased vibration intensity for Android versions >= 8
- Fixed drifting alarms
- Updated to ViewPager2 and other small ui fixes
  • Loading branch information
scheibler committed May 11, 2024
1 parent 84609b4 commit 8385d72
Show file tree
Hide file tree
Showing 18 changed files with 455 additions and 167 deletions.
9 changes: 9 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@



## v2.3.0: Released at 2024-05-11

- Added shortcut to vibrate the current time
- Increased vibration intensity for Android versions >= 8
- Fixed drifting alarms
- Updated to ViewPager2 and other small ui fixes



## v2.2.0: Released at 2024-03-25

- Support for Android 14 (SDK 34)
Expand Down
6 changes: 3 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ android {
minSdkVersion 16
targetSdkVersion 34
multiDexEnabled true
versionCode 10
versionName '2.2.0'
versionCode 11
versionName '2.3.0'
// project website
buildConfigField 'String', 'CONTACT_EMAIL_ADDRESS', '"[email protected]"'
buildConfigField 'String', 'PROJECT_WEBSITE', '"https://github.com/scheibler/TactileClock"'
Expand Down Expand Up @@ -72,7 +72,7 @@ dependencies {
implementation 'androidx.drawerlayout:drawerlayout:1.2.0'
implementation 'androidx.fragment:fragment:1.6.2'
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'
implementation 'androidx.viewpager:viewpager:1.0.0'
implementation 'androidx.viewpager2:viewpager2:1.0.0'
// material design
implementation 'com.google.android.material:material:1.11.0'
// guava
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,23 @@

<activity
android:name=".ui.activity.MainActivity"
android:launchMode="singleTop"
android:exported="true" >

<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity>

<activity
android:name=".ui.activity.ShortcutActivity"
android:taskAffinity="" />

<activity
android:name=".ui.activity.SettingsActivity"
android:label="@string/settingsActivityTitle"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package de.eric_scheibler.tactileclock.ui.activity;

import androidx.core.content.ContextCompat;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.tabs.TabLayout;
import com.google.common.primitives.Ints;

import android.content.Intent;

Expand All @@ -19,38 +19,41 @@

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentPagerAdapter;

import androidx.viewpager.widget.ViewPager;

import de.eric_scheibler.tactileclock.R;
import de.eric_scheibler.tactileclock.ui.activity.AbstractActivity;
import de.eric_scheibler.tactileclock.ui.dialog.HelpDialog;
import de.eric_scheibler.tactileclock.ui.fragment.PowerButtonFragment;
import de.eric_scheibler.tactileclock.ui.fragment.WatchFragment;
import de.eric_scheibler.tactileclock.utils.TactileClockService;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import timber.log.Timber;
import de.eric_scheibler.tactileclock.utils.ApplicationInstance;


public class MainActivity extends AbstractActivity {
public static String EXTRA_NEW_TAB = "newTab";

// fragments
public static final int TAB_POWER_BUTTON = 0;
public static final int TAB_WATCH = 1;
public final static int[] FragmentValueArray = {
TAB_POWER_BUTTON, TAB_WATCH
};

private DrawerLayout drawerLayout;
private NavigationView navigationView;

private ViewPager viewPager;
private TabAdapter tabAdapter;
private ViewPager2 viewPager;
private TabLayout tabLayout;
private int selectedTabIndex;
private Tab selectedTab;

@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Timber.d("onCreate");

// start service
Intent startServiceIntent = new Intent(this, TactileClockService.class);
startServiceIntent.setAction(TactileClockService.ACTION_UPDATE_NOTIFICATION);
ContextCompat.startForegroundService(
ApplicationInstance.getContext(), startServiceIntent);

// navigation drawer
drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
Expand Down Expand Up @@ -83,48 +86,71 @@ public class MainActivity extends AbstractActivity {
drawerLayout.addDrawerListener(drawerToggle);
drawerToggle.syncState();

tabAdapter = new TabAdapter(this);
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(tabAdapter);
viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
// ViewPager2 and TabLayout

viewPager = (ViewPager2) findViewById(R.id.pager);
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override public void onPageSelected(int position) {
if (selectedTabIndex != position) {
// set toolbar title
setToolbarTitle(position);
// save active fragment
selectedTabIndex = position;
}
Timber.d("onPageSelected: %1$d", position);
tabLayout.selectTab(tabLayout.getTabAt(position));
setToolbarTitle(position);
selectedTab = Tab.getTabAtPosition(position);
}
});

tabLayout = (TabLayout) findViewById(R.id.tabLayout);
//tabLayout.setTabMode(TabLayout.MODE_FIXED);
//setTabGravity(TabLayout.GRAVITY_FILL);
//tabLayout.setSelectedTabIndicatorColor(Color.parseColor("#FFFFFF"));
tabLayout.setupWithViewPager(viewPager);

// open selected tab
int tabIndexFromBundle = -1;
if (savedInstanceState != null) {
tabIndexFromBundle = savedInstanceState.getInt("selectedTabIndex");
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override public void onTabSelected(TabLayout.Tab tab) {
loadFragment(tab.getPosition());
}
@Override public void onTabUnselected(TabLayout.Tab tab) {
}
@Override public void onTabReselected(TabLayout.Tab tab) {
}
});

// prepare tab adapter and load tab

TabAdapter tabAdapter = new TabAdapter(MainActivity.this);
for (int pos=0; pos<tabAdapter.getItemCount(); pos++) {
TabLayout.Tab tab = tabLayout.newTab();
tab.setText(tabAdapter.getFragmentName(pos));
tabLayout.addTab(tab);
}
if (Ints.contains(FragmentValueArray, tabIndexFromBundle)) {
selectedTabIndex = tabIndexFromBundle;
viewPager.setAdapter(tabAdapter);

Tab tabToOpen = getTabFromIntent(getIntent());
if (tabToOpen != null) {
loadFragment(tabToOpen.position);
} else {
selectedTabIndex = TAB_WATCH;
if (savedInstanceState != null) {
tabToOpen = (Tab) savedInstanceState.getSerializable("selectedTab");
}
if (tabToOpen == null) {
tabToOpen = Tab.CLOCK;
}
loadFragment(tabToOpen.position);
}
setToolbarTitle(selectedTabIndex);
viewPager.setCurrentItem(selectedTabIndex);
}

// start service
Intent intent = new Intent(this, TactileClockService.class);
intent.setAction(TactileClockService.ACTION_UPDATE_NOTIFICATION);
startService(intent);
@Override protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Tab tabToOpen = getTabFromIntent(intent);
if (tabToOpen != null) {
loadFragment(tabToOpen.position);
}
}

private Tab getTabFromIntent(Intent intent) {
if (intent != null && intent.getExtras() != null) {
return (Tab) intent.getExtras().getSerializable(EXTRA_NEW_TAB);
}
return null;
}

@Override public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("selectedTabIndex", selectedTabIndex);
savedInstanceState.putSerializable("selectedTab", selectedTab);
}

@Override public void onBackPressed() {
Expand All @@ -137,44 +163,75 @@ public class MainActivity extends AbstractActivity {

private void setToolbarTitle(int tabIndex) {
getSupportActionBar().setTitle(
tabAdapter.getPageTitle(tabIndex).toString());
tabLayout.getTabAt(tabIndex).getText().toString());
}


/**
* tab adapter
* tabs
*/

public class TabAdapter extends FragmentPagerAdapter {

public TabAdapter(FragmentActivity activity) {
super(activity.getSupportFragmentManager());
}
public enum Tab {
CLOCK(0),
SHORTCUT(1);

@Override public Fragment getItem(int position) {
switch (position) {
case TAB_POWER_BUTTON:
return PowerButtonFragment.newInstance();
case TAB_WATCH:
return WatchFragment.newInstance();
default:
return null;
public static Tab getTabAtPosition(int position) {
for (Tab tab : Tab.values()) {
if (tab.position == position) {
return tab;
}
}
return null;
}

public int position;

private Tab(int position) {
this.position = position;
}
}


private void loadFragment(int newTabIndex) {
Timber.d("loadFragment: newTabIndex=%1$d", newTabIndex);
viewPager.setCurrentItem(newTabIndex);
}

@Override public CharSequence getPageTitle(int position) {
switch (position) {
case TAB_POWER_BUTTON:
return getResources().getString(R.string.fragmentPowerButton);
case TAB_WATCH:
return getResources().getString(R.string.fragmentWatch);
default:
return "";

private class TabAdapter extends FragmentStateAdapter {

public TabAdapter(FragmentActivity activity) {
super(activity);
}

@Override public Fragment createFragment(int position) {
Tab tab = Tab.getTabAtPosition(position);
if (tab != null) {
switch (tab) {
case CLOCK:
return WatchFragment.newInstance();
case SHORTCUT:
return PowerButtonFragment.newInstance();
}
}
return null;
}

@Override public int getCount() {
return FragmentValueArray.length;
@Override public int getItemCount() {
return Tab.values().length;
}

public String getFragmentName(int position) {
Tab tab = Tab.getTabAtPosition(position);
if (tab != null) {
switch (tab) {
case CLOCK:
return getResources().getString(R.string.fragmentWatch);
case SHORTCUT:
return getResources().getString(R.string.fragmentPowerButton);
}
}
return "";
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@
import de.eric_scheibler.tactileclock.data.HourFormat;
import de.eric_scheibler.tactileclock.data.TimeComponentOrder;
import de.eric_scheibler.tactileclock.ui.activity.AbstractActivity;
import androidx.appcompat.widget.SwitchCompat;
import android.widget.CompoundButton;


public class SettingsActivity extends AbstractActivity {

private SwitchCompat switchMaxStrengthVibrations;
private RadioGroup radioHourFormat, radioTimeComponentOrder;

@Override public void onCreate(Bundle savedInstanceState) {
Expand All @@ -28,6 +31,15 @@ public class SettingsActivity extends AbstractActivity {
getSupportActionBar().setTitle(
getResources().getString(R.string.settingsActivityTitle));

switchMaxStrengthVibrations = (SwitchCompat) findViewById(R.id.switchMaxStrengthVibrations);
switchMaxStrengthVibrations.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton view, boolean isChecked) {
if (isChecked != settingsManagerInstance.getMaxStrengthVibrationsEnabled()) {
settingsManagerInstance.setMaxStrengthVibrationsEnabled(isChecked);
}
}
});

// hour format
radioHourFormat = (RadioGroup) findViewById(R.id.radioHourFormat);
radioHourFormat.setOnCheckedChangeListener(new OnCheckedChangeListener() {
Expand Down Expand Up @@ -59,6 +71,7 @@ public void onCheckedChanged(RadioGroup group, int checkedId) {
}

private void updateUI() {
switchMaxStrengthVibrations.setChecked(settingsManagerInstance.getMaxStrengthVibrationsEnabled());
if (settingsManagerInstance.getHourFormat() == HourFormat.TWELVE_HOURS) {
radioHourFormat.check(R.id.button12Hours);
} else {
Expand Down
Loading

0 comments on commit 8385d72

Please sign in to comment.