build: change of package name

This commit is contained in:
antonio 2023-06-17 15:30:23 +02:00
parent 49afdbe4eb
commit b76a38cb30
274 changed files with 1981 additions and 2161 deletions

View file

@ -0,0 +1,342 @@
package com.cappielloantonio.tempo.ui.activity;
import android.content.Context;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.core.splashscreen.SplashScreen;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModelProvider;
import androidx.media3.common.Player;
import androidx.media3.common.util.UnstableApi;
import androidx.navigation.NavController;
import androidx.navigation.fragment.NavHostFragment;
import androidx.navigation.ui.NavigationUI;
import com.cappielloantonio.tempo.R;
import com.cappielloantonio.tempo.broadcast.receiver.ConnectivityStatusBroadcastReceiver;
import com.cappielloantonio.tempo.databinding.ActivityMainBinding;
import com.cappielloantonio.tempo.service.MediaManager;
import com.cappielloantonio.tempo.ui.activity.base.BaseActivity;
import com.cappielloantonio.tempo.ui.dialog.ConnectionAlertDialog;
import com.cappielloantonio.tempo.ui.dialog.ServerUnreachableDialog;
import com.cappielloantonio.tempo.ui.fragment.PlayerBottomSheetFragment;
import com.cappielloantonio.tempo.util.Constants;
import com.cappielloantonio.tempo.util.Preferences;
import com.cappielloantonio.tempo.viewmodel.MainViewModel;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
@UnstableApi
public class MainActivity extends BaseActivity {
private static final String TAG = "MainActivity";
public ActivityMainBinding bind;
private MainViewModel mainViewModel;
private FragmentManager fragmentManager;
private NavHostFragment navHostFragment;
private BottomNavigationView bottomNavigationView;
public NavController navController;
private BottomSheetBehavior bottomSheetBehavior;
ConnectivityStatusBroadcastReceiver connectivityStatusBroadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
SplashScreen.installSplashScreen(this);
super.onCreate(savedInstanceState);
bind = ActivityMainBinding.inflate(getLayoutInflater());
View view = bind.getRoot();
setContentView(view);
mainViewModel = new ViewModelProvider(this).get(MainViewModel.class);
connectivityStatusBroadcastReceiver = new ConnectivityStatusBroadcastReceiver(this);
connectivityStatusReceiverManager(true);
init();
checkConnectionType();
}
@Override
protected void onStart() {
super.onStart();
initService();
}
@Override
protected void onResume() {
super.onResume();
pingServer();
}
@Override
protected void onDestroy() {
super.onDestroy();
connectivityStatusReceiverManager(false);
bind = null;
}
@Override
public void onBackPressed() {
if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED)
collapseBottomSheet();
else
super.onBackPressed();
}
public void init() {
fragmentManager = getSupportFragmentManager();
initBottomSheet();
initNavigation();
if (Preferences.getPassword() != null || (Preferences.getToken() != null && Preferences.getSalt() != null)) {
goFromLogin();
} else {
goToLogin();
}
}
// BOTTOM SHEET/NAVIGATION
private void initBottomSheet() {
bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.player_bottom_sheet));
bottomSheetBehavior.addBottomSheetCallback(bottomSheetCallback);
fragmentManager.beginTransaction().replace(R.id.player_bottom_sheet, new PlayerBottomSheetFragment(), "PlayerBottomSheet").commit();
setBottomSheetInPeek(mainViewModel.isQueueLoaded());
}
public void setBottomSheetInPeek(Boolean isVisible) {
if (isVisible) {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
} else {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
}
}
public void setBottomSheetVisibility(boolean visibility) {
if (visibility) {
findViewById(R.id.player_bottom_sheet).setVisibility(View.VISIBLE);
} else {
findViewById(R.id.player_bottom_sheet).setVisibility(View.GONE);
}
}
public void collapseBottomSheet() {
final Handler handler = new Handler();
final Runnable runnable = () -> bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
handler.postDelayed(runnable, 100);
}
public void setBottomSheetDraggableState(Boolean isDraggable) {
bottomSheetBehavior.setDraggable(isDraggable);
}
private final BottomSheetBehavior.BottomSheetCallback bottomSheetCallback =
new BottomSheetBehavior.BottomSheetCallback() {
int navigationHeight;
@Override
public void onStateChanged(@NonNull View view, int state) {
PlayerBottomSheetFragment playerBottomSheetFragment = (PlayerBottomSheetFragment) getSupportFragmentManager().findFragmentByTag("PlayerBottomSheet");
switch (state) {
case BottomSheetBehavior.STATE_HIDDEN:
hideMusicSession();
break;
case BottomSheetBehavior.STATE_COLLAPSED:
if (playerBottomSheetFragment != null)
playerBottomSheetFragment.goBackToFirstPage();
break;
case BottomSheetBehavior.STATE_SETTLING:
case BottomSheetBehavior.STATE_EXPANDED:
case BottomSheetBehavior.STATE_DRAGGING:
case BottomSheetBehavior.STATE_HALF_EXPANDED:
break;
}
}
@Override
public void onSlide(@NonNull View view, float slideOffset) {
animateBottomSheet(slideOffset);
animateBottomNavigation(slideOffset, navigationHeight);
}
};
private void animateBottomSheet(float slideOffset) {
PlayerBottomSheetFragment playerBottomSheetFragment = (PlayerBottomSheetFragment) getSupportFragmentManager().findFragmentByTag("PlayerBottomSheet");
if (playerBottomSheetFragment != null) {
float condensedSlideOffset = Math.max(0.0f, Math.min(0.2f, slideOffset - 0.2f)) / 0.2f;
playerBottomSheetFragment.getPlayerHeader().setAlpha(1 - condensedSlideOffset);
playerBottomSheetFragment.getPlayerHeader().setVisibility(condensedSlideOffset > 0.99 ? View.GONE : View.VISIBLE);
}
}
private void animateBottomNavigation(float slideOffset, int navigationHeight) {
if (slideOffset < 0) return;
if (navigationHeight == 0) {
navigationHeight = bind.bottomNavigation.getHeight();
}
float slideY = navigationHeight - navigationHeight * (1 - slideOffset);
bind.bottomNavigation.setTranslationY(slideY);
}
private void initNavigation() {
bottomNavigationView = findViewById(R.id.bottom_navigation);
navHostFragment = (NavHostFragment) fragmentManager.findFragmentById(R.id.nav_host_fragment);
navController = Objects.requireNonNull(navHostFragment).getNavController();
/*
* In questo modo intercetto il cambio schermata tramite navbar e se il bottom sheet è aperto,
* lo chiudo
*/
navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED && (
destination.getId() == R.id.homeFragment ||
destination.getId() == R.id.libraryFragment ||
destination.getId() == R.id.downloadFragment)
) {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
});
NavigationUI.setupWithNavController(bottomNavigationView, navController);
}
public void setBottomNavigationBarVisibility(boolean visibility) {
if (visibility) {
bottomNavigationView.setVisibility(View.VISIBLE);
} else {
bottomNavigationView.setVisibility(View.GONE);
}
}
private void initService() {
MediaManager.check(getMediaBrowserListenableFuture());
getMediaBrowserListenableFuture().addListener(() -> {
try {
getMediaBrowserListenableFuture().get().addListener(new Player.Listener() {
@Override
public void onIsPlayingChanged(boolean isPlaying) {
if (isPlaying && bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_HIDDEN) {
setBottomSheetInPeek(true);
}
}
});
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}, MoreExecutors.directExecutor());
}
private void goToLogin() {
setBottomNavigationBarVisibility(false);
setBottomSheetVisibility(false);
if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.landingFragment) {
navController.navigate(R.id.action_landingFragment_to_loginFragment);
} else if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.settingsFragment) {
navController.navigate(R.id.action_settingsFragment_to_loginFragment);
} else if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.homeFragment) {
navController.navigate(R.id.action_homeFragment_to_loginFragment);
}
}
private void goToHome() {
bottomNavigationView.setVisibility(View.VISIBLE);
if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.landingFragment) {
navController.navigate(R.id.action_landingFragment_to_homeFragment);
} else if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.loginFragment) {
navController.navigate(R.id.action_loginFragment_to_homeFragment);
}
}
public void goFromLogin() {
setBottomSheetInPeek(mainViewModel.isQueueLoaded());
goToHome();
}
public void quit() {
resetUserSession();
resetMusicSession();
resetViewModel();
goToLogin();
}
private void resetUserSession() {
Preferences.setServerId(null);
Preferences.setSalt(null);
Preferences.setToken(null);
Preferences.setPassword(null);
Preferences.setServer(null);
Preferences.setUser(null);
// TODO Enter all settings to be reset
Preferences.setServerId(null);
Preferences.setPlaybackSpeed(Constants.MEDIA_PLAYBACK_SPEED_100);
Preferences.setSkipSilenceMode(false);
Preferences.setDataSavingMode(false);
Preferences.setStarredSyncEnabled(false);
}
private void resetMusicSession() {
MediaManager.reset(getMediaBrowserListenableFuture());
}
private void hideMusicSession() {
MediaManager.hide(getMediaBrowserListenableFuture());
}
private void resetViewModel() {
this.getViewModelStore().clear();
}
// CONNECTION
private void connectivityStatusReceiverManager(boolean isActive) {
if (isActive) {
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(connectivityStatusBroadcastReceiver, filter);
} else {
unregisterReceiver(connectivityStatusBroadcastReceiver);
}
}
private void pingServer() {
if (Preferences.getToken() != null) {
mainViewModel.ping().observe(this, isPingSuccessfull -> {
if (!isPingSuccessfull && Preferences.showServerUnreachableDialog()) {
ServerUnreachableDialog dialog = new ServerUnreachableDialog();
dialog.show(getSupportFragmentManager(), null);
}
});
}
}
private void checkConnectionType() {
if (Preferences.isWifiOnly()) {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager.getActiveNetworkInfo().getType() != ConnectivityManager.TYPE_WIFI) {
ConnectionAlertDialog dialog = new ConnectionAlertDialog();
dialog.show(getSupportFragmentManager(), null);
}
}
}
}

View file

@ -0,0 +1,126 @@
package com.cappielloantonio.tempo.ui.activity.base;
import android.Manifest;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.provider.Settings;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.offline.DownloadService;
import androidx.media3.session.MediaBrowser;
import androidx.media3.session.SessionToken;
import com.cappielloantonio.tempo.R;
import com.cappielloantonio.tempo.service.DownloaderService;
import com.cappielloantonio.tempo.service.MediaService;
import com.cappielloantonio.tempo.util.UIUtil;
import com.google.android.gms.cast.framework.CastContext;
import com.google.android.material.elevation.SurfaceColors;
import com.google.common.util.concurrent.ListenableFuture;
@UnstableApi
public class BaseActivity extends AppCompatActivity {
private static final String TAG = "BaseActivity";
private ListenableFuture<MediaBrowser> mediaBrowserListenableFuture;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initializeCastContext();
initializeDownloader();
}
@Override
protected void onStart() {
super.onStart();
setNavigationBarColor();
initializeBrowser();
}
@Override
protected void onResume() {
super.onResume();
checkBatteryOptimization();
checkPermission();
}
@Override
protected void onStop() {
releaseBrowser();
super.onStop();
}
private void checkBatteryOptimization() {
if (detectBatteryOptimization()) {
showBatteryOptimizationDialog();
}
}
private void checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.POST_NOTIFICATIONS}, 101);
}
}
}
private boolean detectBatteryOptimization() {
String packageName = getPackageName();
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
return !powerManager.isIgnoringBatteryOptimizations(packageName);
}
private void showBatteryOptimizationDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.activity_battery_optimizations_summary)
.setTitle(R.string.activity_battery_optimizations_title)
.setNegativeButton(R.string.activity_negative_button, null)
.setPositiveButton(R.string.activity_neutral_button, (dialog, id) -> openPowerSettings())
.show();
}
private void openPowerSettings() {
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
startActivity(intent);
}
private void initializeBrowser() {
mediaBrowserListenableFuture = new MediaBrowser.Builder(this, new SessionToken(this, new ComponentName(this, MediaService.class))).buildAsync();
}
private void releaseBrowser() {
MediaBrowser.releaseFuture(mediaBrowserListenableFuture);
}
public ListenableFuture<MediaBrowser> getMediaBrowserListenableFuture() {
return mediaBrowserListenableFuture;
}
private void initializeDownloader() {
try {
DownloadService.start(this, DownloaderService.class);
} catch (IllegalStateException e) {
DownloadService.startForeground(this, DownloaderService.class);
}
}
private void initializeCastContext() {
if (UIUtil.isCastApiAvailable(this)) CastContext.getSharedInstance(this);
}
private void setNavigationBarColor() {
getWindow().setNavigationBarColor(SurfaceColors.getColorForElevation(this, 10));
}
}