Java tutorial
/** * MainActivity.java * * Copyright (C) 2017, Nariaki Iwatani(Anno Lab Inc.) and Shunichi Yamamoto(Yamamoto Works Ltd.) * * This software is released under the MIT License. * http://opensource.org/licenses/mit-license.php **/ package com.jins_meme.bridge; import android.annotation.TargetApi; import android.app.AlarmManager; import android.app.KeyguardManager; import android.app.PendingIntent; import android.bluetooth.BluetoothAdapter; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Build; import android.os.Handler; import android.preference.PreferenceManager; import android.provider.Settings; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.Toast; import com.crashlytics.android.Crashlytics; import com.jins_jp.meme.MemeConnectListener; import com.jins_jp.meme.MemeFitStatus; import com.jins_jp.meme.MemeLib; import com.jins_jp.meme.MemeRealtimeData; import com.jins_jp.meme.MemeRealtimeListener; import com.jins_jp.meme.MemeScanListener; import com.jins_jp.meme.MemeStatus; import com.spotify.sdk.android.authentication.AuthenticationClient; import com.spotify.sdk.android.authentication.AuthenticationRequest; import com.spotify.sdk.android.authentication.AuthenticationRequest.Builder; import com.spotify.sdk.android.authentication.AuthenticationResponse; import com.spotify.sdk.android.authentication.AuthenticationResponse.Type; import com.spotify.sdk.android.player.Config; import com.spotify.sdk.android.player.ConnectionStateCallback; import com.spotify.sdk.android.player.Connectivity; import com.spotify.sdk.android.player.Error; import com.spotify.sdk.android.player.Player; import com.spotify.sdk.android.player.Player.OperationCallback; import com.spotify.sdk.android.player.PlayerEvent; import com.spotify.sdk.android.player.Spotify; import com.spotify.sdk.android.player.SpotifyPlayer; import io.fabric.sdk.android.Fabric; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import static com.jins_meme.bridge.BridgeUIView.Adapter.NO_ID; public class MainActivity extends AppCompatActivity implements MemeConnectListener, MemeRealtimeListener, RootMenuFragment.OnFragmentInteractionListener, CameraMenuFragment.OnFragmentInteractionListener, SpotifyMenuFragment.OnFragmentInteractionListener, HueMenuFragment.OnFragmentInteractionListener, VDJMenuFragment.OnFragmentInteractionListener, RemoMenuFragment.OnFragmentInteractionListener, DialogListener, SpotifyPlayer.NotificationCallback, ConnectionStateCallback, SimpleTimer.OnResultListener, PauseActionDetector.OnPauseActionListener { private static final int REQUEST_CODE = 1337; private String appID = null; private String appSecret = null; private String lastConnectedMemeID; private int blinkThreshold = 90; private int upDownThreshold = 0; private int leftRightThreshold = 0; private int rollThreshold = 15; private int batteryStatus = 0; private SharedPreferences preferences; private SharedPreferences.Editor editor; private ProgressDialogFragment memeConnectProgressDialog; private Handler handler; private FrameLayout mainLayout; private MemeLib memeLib = null; private List<String> scannedMemeList = new ArrayList<>(); private MemeRealtimeDataFilter mMemeDataFilter = new MemeRealtimeDataFilter(); private static final int TIMER_ID_UI_DISABLE = 0; private static final int TIMER_ID_UI_CANCEL = 1; private static final int TIMER_ID_UI_PAUSE = 2; private SimpleTimer interactionDisableTimer = new SimpleTimer(TIMER_ID_UI_DISABLE); private SimpleTimer cancelTimer = new SimpleTimer(TIMER_ID_UI_CANCEL); private SimpleTimer pauseTimer = new SimpleTimer(TIMER_ID_UI_PAUSE); private boolean memeInteractionFlagPrepareCancel = false; private float pauseWaitTime = 2.5f; private float cancelWaitTime = 2.5f; private float CANCEL_REFRACTORY_TIME = 1.f; private static final int BATTERY_CHECK_INTERVAL = 2000; private int batteryCheckCount = BATTERY_CHECK_INTERVAL; private static final Map<String, Integer> ROOT_CARD_IDS; static { Map<String, Integer> map = new LinkedHashMap<>(); map.put("ENABLE_CAMERA", R.string.camera); map.put("ENABLE_SPOTIFY", R.string.spotify); map.put("ENABLE_REMO", R.string.remo); map.put("ENABLE_HUE", R.string.hue); map.put("ENABLE_EYEVDJ", R.string.vdj); ROOT_CARD_IDS = Collections.unmodifiableMap(map); } private boolean isNetworkEnable = false; private Player mPlayer; private static boolean isAuthenticated = false; private BroadcastReceiver mNetworkStateReceiver; private boolean isCameraMenuFragment = false; void setIsCameraMenuFragment(boolean flag) { isCameraMenuFragment = flag; } boolean isCameraMenuFragment() { return isCameraMenuFragment; } private final Player.OperationCallback mOperationCallback = new OperationCallback() { @Override public void onSuccess() { Log.d("DEBUG", "SPOTIFY:: OperationCallback -> onSuccess"); } @Override public void onError(Error error) { Log.d("DEBUG", "SPOTIFY:: OperationCallback -> onError:" + error); } }; private boolean isForeground = true; private RootMenuFragment rootMenu; private SpotifyMenuFragment spotifyMenu; private HueMenuFragment hueMenu; private RemoMenuFragment remoMenu; private CameraMenuFragment cameraMenu; private VDJMenuFragment vdjMenu; /* * MODIFY YOURSELF * Add your implemented function's configuration * */ // private ***Fragment ***Fragment; private BasicConfigFragment basicConfigFragment; private AboutFragment aboutFragment; private OSCConfigFragment oscConfigFragment; private MIDIConfigFragment midiConfigFragment; private SpotifyConfigFragment spotifyConfigFragment; private HueConfigFragment hueConfigFragment; private RemoConfigFragment remoConfigFragment; /* * MODIFY YOURSELF * Add your implemented function's configuration * */ // private ***ConfigFragment ***ConfigFragment; public InputStream openLocalorAssets(String fileName) { InputStream is = null; Log.d("DEBUG", "external dir. = " + getExternalFilesDir(null).toString()); File file = new File(getExternalFilesDir(null), fileName); if (file.exists()) { try { is = new FileInputStream(file); } catch (FileNotFoundException e) { e.printStackTrace(); } } else { try { is = getResources().getAssets().open(fileName); FileOutputStream fos = new FileOutputStream(new File(getExternalFilesDir(null), fileName)); byte[] buffer = new byte[1024]; int len; while ((len = is.read(buffer)) > 0) { fos.write(buffer, 0, len); } fos.close(); is.close(); is = getResources().getAssets().open(fileName); } catch (IOException e) { e.printStackTrace(); } } return is; } public int getBlinkThreshold() { return blinkThreshold; } public int getUpDownThreshold() { return upDownThreshold; } public int getLeftRightThreshold() { return leftRightThreshold; } public int getRollThreshold() { return rollThreshold; } public void setAuthenticated(boolean authenticated) { isAuthenticated = authenticated; } public boolean isAuthenticated() { return isAuthenticated; } public boolean isNetworkEnabled() { return isNetworkEnable; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Fabric.with(this, new Crashlytics()); setContentView(R.layout.activity_bridge_menu); handler = new Handler(); mainLayout = (FrameLayout) findViewById(R.id.container); preferences = PreferenceManager.getDefaultSharedPreferences(this); editor = preferences.edit(); if (getSupportActionBar() != null) { //updateActionBar(getResources().getString(R.string.actionbar_title)); updateActionBarLogo(isCameraMenuFragment); } // Only use for Eye VDJ /* View decor = this.getWindow().getDecorView(); decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE); */ rootMenu = new RootMenuFragment(); spotifyMenu = new SpotifyMenuFragment(); hueMenu = new HueMenuFragment(); vdjMenu = new VDJMenuFragment(); remoMenu = new RemoMenuFragment(); cameraMenu = new CameraMenuFragment(); interactionDisableTimer.setListener(this); cancelTimer.setListener(this); pauseTimer.setListener(this); ((PauseActionDetector) findViewById(R.id.interceptor)).setListaner(this); basicConfigFragment = new BasicConfigFragment(); oscConfigFragment = new OSCConfigFragment(); midiConfigFragment = new MIDIConfigFragment(); spotifyConfigFragment = new SpotifyConfigFragment(); hueConfigFragment = new HueConfigFragment(); remoConfigFragment = new RemoConfigFragment(); aboutFragment = new AboutFragment(); /* * MODIFY YOURSELF * Add your implemented function's configuration * */ // ***ConfigFragment = new ***ConfigFragment FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); transaction.add(R.id.container, rootMenu); transaction.commit(); if (preferences.getBoolean("SHOW_WELCOME", true)) { showWelcom(); } else { if (Build.VERSION.SDK_INT >= 23) { requestGPSPermission(); } } mNetworkStateReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (mPlayer != null) { Connectivity connectivity = getNetworkConnectivity(context); mPlayer.setConnectivityStatus(mOperationCallback, connectivity); } } }; } @Override public boolean onCreateOptionsMenu(Menu menu) { int index = 0; menu.add(0, index++, 0, R.string.basic_conf); /* * MODIFY YOURSELF * Add your implemented function's configuration * */ menu.add(0, index++, 0, R.string.spotify_conf); menu.add(0, index++, 0, R.string.remo_conf); menu.add(0, index++, 0, R.string.hue_conf); menu.add(0, index++, 0, getString(R.string.osc_conf) + " (for Eye VDJ)"); menu.add(0, index++, 0, getString(R.string.midi_conf) + " (for Eye VDJ)"); menu.add(0, index++, 0, R.string.about); menu.add(0, index, 0, R.string.exit_app); return true; } @Override public boolean onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); //debug Log.d("DEBUG", "onPrepareOptionsMenu"); String barTitle; if (getSupportActionBar() != null && getSupportActionBar().getTitle() != null) { barTitle = getSupportActionBar().getTitle().toString(); Log.d("DEBUG", "Title = " + barTitle); if (barTitle.length() > 1) { for (int i = 0; i < menu.size(); i++) { MenuItem item = menu.getItem(i); String title = item.getTitle().toString(); if (title.contains(" (for Eye VDJ)")) { title = title.substring(0, title.indexOf(" (for Eye VDJ)")); } if (barTitle.contains(title)) { item.setVisible(false); } else { item.setVisible(true); } } } else { for (int i = 0; i < menu.size(); i++) { menu.getItem(i).setVisible(true); } } } return true; } @Override public boolean onOptionsItemSelected(final MenuItem item) { CharSequence cs = item.getTitle(); if (cs == null) { Log.d("DEBUG", "press actionbar back!"); return true; } String itemTitle = item.getTitle().toString(); Log.d("DEBUG", "item id = " + item.getItemId() + " " + itemTitle); if (itemTitle.equals(getString(R.string.basic_conf))) { Log.d("DEBUG", "tap basic setting"); transitToFragment(basicConfigFragment); return true; } else if (itemTitle.equals(getString(R.string.spotify_conf))) { Log.d("DEBUG", "tap spotify setting"); transitToFragment(spotifyConfigFragment); return true; } else if (itemTitle.equals(getString(R.string.hue_conf))) { Log.d("DEBUG", "tap hue setting"); transitToFragment(hueConfigFragment); return true; } else if (itemTitle.equals(getString(R.string.remo_conf))) { Log.d("DEBUG", "tap remo setting"); transitToFragment(remoConfigFragment); return true; } else if (itemTitle.contains(getString(R.string.osc_conf))) { Log.d("DEBUG", "tap osc setting"); transitToFragment(oscConfigFragment); return true; } else if (itemTitle.contains(getString(R.string.midi_conf))) { Log.d("DEBUG", "tap midi setting"); transitToFragment(midiConfigFragment); return true; } /* * MODIFY YOURSELF * Add your implemented function's configuration * */ /* else if (itemTitle.equals(getString(R.string.***_config) { Log.d("DEBUG", "tap *** setting"); transittToConfig(***ConfigFragment); return true; } */ else if (itemTitle.equals(getString(R.string.about))) { Log.d("DEBUG", "tap about"); transitToFragment(aboutFragment); return true; } else if (itemTitle.equals(getString(R.string.exit_app))) { finishAndRemoveTask(); } return super.onOptionsItemSelected(item); } @Override protected void onResume() { super.onResume(); IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(mNetworkStateReceiver, filter); isForeground = true; //if (Build.VERSION.SDK_INT >= 23) { // requestGPSPermission(); //} Log.d("DEBUG", "onResume..." + scannedMemeList.size()); } @Override protected void onPause() { super.onPause(); unregisterReceiver(mNetworkStateReceiver); isForeground = false; Log.d("DEBUG", "MAIN:: onPause..." + scannedMemeList.size()); } @Override protected void onStop() { super.onStop(); Log.d("DEBUG", "MAIN:: onStop... " + isCameraMenuFragment); } @Override protected void onDestroy() { super.onDestroy(); if (memeLib != null && memeLib.isConnected()) { memeLib.disconnect(); memeLib = null; } if (mPlayer != null) { mPlayer.logout(); mPlayer.destroy(); } rootMenu = null; spotifyMenu = null; remoMenu = null; hueMenu = null; vdjMenu = null; basicConfigFragment = null; aboutFragment = null; spotifyConfigFragment = null; remoConfigFragment = null; hueConfigFragment = null; oscConfigFragment = null; midiConfigFragment = null; /* * MODIFY YOURSELF * Add your implemented function's configuration * */ // ***ConfigFragment = null; Log.d("DEBUG", "MAIN:: onDestroy..."); } private void showWelcom() { AlertDialogFragment alertDialogFragment = AlertDialogFragment.newInstance("welcome"); alertDialogFragment.setCancelable(false); alertDialogFragment.setDialogListener(this); alertDialogFragment.show(getSupportFragmentManager(), "dialog"); } private void checkAirplaneMode() { Log.d("DEBUG", "AIRPLANE = " + Settings.System.getInt(getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0)); if (Settings.System.getInt(getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0) == 1) { Log.d("DEBUG", "show airplane warning."); AlertDialogFragment alertDialogFragment = AlertDialogFragment.newInstance("airplane"); alertDialogFragment.setCancelable(false); alertDialogFragment.setDialogListener(this); alertDialogFragment.show(getSupportFragmentManager(), "dialog"); } else { checkNetworkEnable(); } } private void checkNetworkEnable() { ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); if (networkInfo == null || !networkInfo.isConnected()) { isNetworkEnable = false; AlertDialogFragment alertDialogFragment = AlertDialogFragment.newInstance("network"); alertDialogFragment.setCancelable(false); alertDialogFragment.setDialogListener(this); alertDialogFragment.show(getSupportFragmentManager(), "dialog"); } else { isNetworkEnable = true; checkBluetoothEnable(); } } private void checkBluetoothEnable() { if (!isMemeConnected()) { BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (bluetoothAdapter != null && !bluetoothAdapter.isEnabled()) { Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intent, 0); } else if (bluetoothAdapter != null && bluetoothAdapter.isEnabled()) { Log.d("DEBUG", "MAIN:: Initialize MEME LIB"); initMemeLib(); scanAndConnectToLastConnectedMeme(); } } } private void scanAndConnectToLastConnectedMeme() { lastConnectedMemeID = preferences.getString("LAST_CONNECTED_MEME_ID", null); Log.d("DEBUG", "MAIN:: last connected meme ID = " + lastConnectedMemeID); if (lastConnectedMemeID != null) { Log.d("DEBUG", "MAIN:: SCAN Start"); memeConnectProgressDialog = ProgressDialogFragment.newInstance("meme_connect"); memeConnectProgressDialog.setDialogListener(this); memeConnectProgressDialog.setCancelable(false); memeConnectProgressDialog.show(getSupportFragmentManager(), "dialog"); handler.postDelayed(new Runnable() { @Override public void run() { startScan(true); handler.postDelayed(new Runnable() { @Override public void run() { stopScan(); if (getScannedMemeSize() > 0 && scannedMemeList.contains(lastConnectedMemeID)) { connectToMeme(lastConnectedMemeID); final String s2 = lastConnectedMemeID; handler.post(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, getString(R.string.meme_connect, s2), Toast.LENGTH_SHORT).show(); } }); } else { memeConnectProgressDialog.dismiss(); showNotFoundMeme(); } } }, 30000); } }, 1000); } } @Override public void openNextMenu(int card_id) { switch (card_id) { case R.string.vdj: transitToFragment(vdjMenu); break; case R.string.spotify: transitToFragment(spotifyMenu); break; case R.string.hue: transitToFragment(hueMenu); break; case R.string.camera: transitToFragment(cameraMenu); break; case R.string.remo: transitToFragment(remoMenu); break; } } @Override public void backToPreviousMenu() { if (hasBackStackEntryCount()) { super.onBackPressed(); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Log.d("DEBUG", "MAIN:: onActivityResult -> " + requestCode); if (requestCode == 0) { if (resultCode == RESULT_OK) { Log.d("DEBUG", "MAIN:: Bluetooth ON"); } else { finishAndRemoveTask(); } } else if (requestCode == 1337) { processRequestToken(requestCode, resultCode, data); } else { if (resultCode == RESULT_OK) { Log.d("DEBUG", "MAIN:: Auth OK"); basicConfigFragment.unlockAppIDandSecret(); } else { Log.d("DEBUG", "MAIN:: Auth NG"); basicConfigFragment.lockAppIDandSecret(); } } } @TargetApi(23) private void requestGPSPermission() { if (checkSelfPermission( android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[] { android.Manifest.permission.ACCESS_COARSE_LOCATION }, getResources().getInteger(R.integer.PERMISSION_REQUEST_CODE_GPS)); } else { Log.d("DEBUG", "check airplane..."); checkAirplaneMode(); } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == getResources().getInteger(R.integer.PERMISSION_REQUEST_CODE_GPS)) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { Log.d("PERMISSION", "Succeeded"); Toast.makeText(MainActivity.this, getString(R.string.succeeded), Toast.LENGTH_SHORT).show(); checkAirplaneMode(); } else { Log.d("PERMISSION", "Failed"); Toast.makeText(MainActivity.this, getString(R.string.failed), Toast.LENGTH_SHORT).show(); } } else { super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } @Override public void memeConnectCallback(boolean b) { Log.d("DEBUG", "MAIN:: meme connected. " + b + " " + lastConnectedMemeID); if (memeConnectProgressDialog != null) { memeConnectProgressDialog.dismiss(); } if (b) { autoSaveValue("LAST_CONNECTED_MEME_ID", lastConnectedMemeID); } if (handler != null) { handler.post(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, getString(R.string.meme_connected), Toast.LENGTH_SHORT) .show(); } }); } batteryStatus = 5; Log.d("DEBUG", "MAIN:: memeConnectCallback:: " + getSupportActionBar().getTitle().length()); if (getSupportActionBar().getTitle().length() <= 2) { updateActionBarLogo(isCameraMenuFragment); } //invalidateOptionsMenu(); memeLib.setAutoConnect(true); memeLib.startDataReport(this); } @Override public void memeDisconnectCallback() { Log.d("DEBUG", "MAIN:: meme disconnected."); handler.post(new Runnable() { @Override public void run() { //invalidateOptionsMenu(); batteryStatus = 0; updateActionBarLogo(isCameraMenuFragment); if (basicConfigFragment != null) { basicConfigFragment.setSwConnect(false); } Toast.makeText(MainActivity.this, getString(R.string.meme_disconnected), Toast.LENGTH_SHORT).show(); } }); } public void initMemeLib() { appID = preferences.getString("APP_ID", getString(R.string.meme_app_id)); appSecret = preferences.getString("APP_SECRET", getString(R.string.meme_app_secret)); Log.d("DEBUG", "MAIN:: APP_ID: " + appID + " APP_SECRET: " + appSecret); if (appID != null && appID.length() > 0 && appSecret != null && appSecret.length() > 0) { Log.d("DEBUG", "MAIN:: Initialized MemeLib with " + appID + " / and " + appSecret); MemeLib.setAppClientID(this, appID, appSecret); memeLib = MemeLib.getInstance(); memeLib.setAutoConnect(false); } //Log.d("DEBUG", "devs : " + memeBTSPP.getPairedDeviceName()); } public void clearScannedMemeList() { if (scannedMemeList != null) { scannedMemeList.clear(); } } public void startScan(final boolean isConnect) { Log.d("DEBUG", "MAIN:: start scannig... " + lastConnectedMemeID); if (scannedMemeList != null) { scannedMemeList.clear(); } if (memeLib == null) { Log.d("DEBUG", "MAIN:: memeLib is null!"); } if (memeLib != null) { memeLib.setMemeConnectListener(this); MemeStatus status = memeLib.startScan(new MemeScanListener() { @Override public void memeFoundCallback(String s) { Log.d("DEBUG", "MAIN:: " + getString(R.string.meme_found, s)); if (memeConnectProgressDialog != null) { memeConnectProgressDialog.setMessage("Found: " + s); } scannedMemeList.add(s); if (getScannedMemeSize() > 0 && scannedMemeList.contains(lastConnectedMemeID)) { stopScan(); if (handler != null) { handler.removeCallbacksAndMessages(null); } if (isConnect) { Log.d("DEBUG", "MAIN:: connect and stop callbacks"); if (memeConnectProgressDialog != null) { memeConnectProgressDialog.setMessage("Connect to: " + s); } connectToMeme(lastConnectedMemeID); } } } }); Log.d("DEBUG", "MAIN:: MemeStatus = " + status); switch (status) { case MEME_ERROR_SDK_AUTH: case MEME_ERROR_APP_AUTH: showAppIDandSecretWarning(); break; } } } public void stopScan() { Log.d("DEBUG", "MAIN:: stop scannig..."); if (memeLib != null && memeLib.isScanning()) { memeLib.stopScan(); Log.d("DEBUG", "MAIN:: scan stopped."); } } @Override public void memeRealtimeCallback(MemeRealtimeData memeRealtimeData) { if (++batteryCheckCount > BATTERY_CHECK_INTERVAL) { Log.d("DEBUG", "MAIN:: battery status = " + memeRealtimeData.getPowerLeft()); renewBatteryState(memeRealtimeData.getPowerLeft()); batteryCheckCount = 0; } if (isUIDisabled) { return; } int eyeBlinkStrength = memeRealtimeData.getBlinkStrength(); int eyeBlinkSpeed = memeRealtimeData.getBlinkSpeed(); int eyeUp = memeRealtimeData.getEyeMoveUp(); int eyeDown = memeRealtimeData.getEyeMoveDown(); int eyeLeft = memeRealtimeData.getEyeMoveLeft(); int eyeRight = memeRealtimeData.getEyeMoveRight(); //float accelX = memeRealtimeData.getAccX(); //float accelY = memeRealtimeData.getAccY(); //float accelZ = memeRealtimeData.getAccZ(); //float yaw = memeRealtimeData.getYaw(); //float pitch = memeRealtimeData.getPitch(); float roll = memeRealtimeData.getRoll(); if (isForeground && memeRealtimeData.getFitError() == MemeFitStatus.MEME_FIT_OK) { if (Math.abs(roll) > getRollThreshold()) { if (!memeInteractionFlagPrepareCancel) { if (!isUIPaused) { cancelTimer.startTimer(cancelWaitTime, true); } pauseTimer.startTimer(pauseWaitTime, true); } memeInteractionFlagPrepareCancel = true; } else if (Math.abs(roll) <= getRollThreshold()) { final Fragment active = getSupportFragmentManager().findFragmentById(R.id.container); if (!isUIPaused) { pauseTimer.abortTimer(); cancelTimer.abortTimer(); if (!isUIDisabled) { mMemeDataFilter.update(memeRealtimeData, getBlinkThreshold(), getUpDownThreshold(), getLeftRightThreshold()); if (active instanceof MemeRealtimeDataFilter.MemeFilteredDataCallback) { final MemeRealtimeDataFilter.MemeFilteredDataCallback accepter = (MemeRealtimeDataFilter.MemeFilteredDataCallback) active; if (mMemeDataFilter.isBlink()) { Log.d("EYE", "blink = " + eyeBlinkStrength + " " + eyeBlinkSpeed); handler.post(new Runnable() { @Override public void run() { accepter.onMemeBlinked(); } }); } else if (mMemeDataFilter.isUp()) { Log.d("EYE", "up = " + eyeUp); } else if (mMemeDataFilter.isDown()) { Log.d("EYE", "down = " + eyeDown); } else if (mMemeDataFilter.isLeft()) { Log.d("EYE", "left = " + eyeLeft); if (getSavedValue("MENU_SLIDE_DIRECTION", false)) { handler.post(new Runnable() { @Override public void run() { accepter.onMemeMoveLeft(); } }); } else { handler.post(new Runnable() { @Override public void run() { accepter.onMemeMoveRight(); } }); } } else if (mMemeDataFilter.isRight()) { Log.d("EYE", "right = " + eyeRight); if (getSavedValue("MENU_SLIDE_DIRECTION", false)) { handler.post(new Runnable() { @Override public void run() { accepter.onMemeMoveRight(); } }); } else { handler.post(new Runnable() { @Override public void run() { accepter.onMemeMoveLeft(); } }); } } } } } if (!mMemeDataFilter.isDown()) { memeInteractionFlagPrepareCancel = false; } } } } @Override public void onTimerStarted(int id) { switch (id) { case TIMER_ID_UI_DISABLE: isUIDisabled = true; break; case TIMER_ID_UI_CANCEL: break; case TIMER_ID_UI_PAUSE: break; } } @Override public void onTimerFinished(int id, boolean completed) { switch (id) { case TIMER_ID_UI_DISABLE: if (completed) { isUIDisabled = false; } break; case TIMER_ID_UI_CANCEL: if (!completed) { handler.post(new Runnable() { @Override public void run() { if (cancel(false)) { interactionDisableTimer.startTimer(CANCEL_REFRACTORY_TIME, true); } } }); } break; case TIMER_ID_UI_PAUSE: if (completed) { handler.post(new Runnable() { @Override public void run() { setUIPaused(!isUIPaused); } }); } break; } } private boolean isUIPaused = false; private boolean isUIDisabled = false; private void setUIPaused(final boolean pause) { Fragment active = getSupportFragmentManager().findFragmentById(R.id.container); if (active instanceof MenuFragmentBase) { isUIPaused = pause; ((MenuFragmentBase) active).setTouchEnabled(!isUIPaused); handler.post(new Runnable() { @Override public void run() { findViewById(R.id.pauseView).setVisibility(pause ? View.VISIBLE : View.GONE); } }); } } public void pause() { setUIPaused(!isUIPaused); } @Override public void onPauseAction() { setUIPaused(!isUIPaused); } public List<String> getScannedMemeList() { return scannedMemeList; } public int getScannedMemeSize() { return scannedMemeList.size(); } public boolean isMemeConnected() { return memeLib != null && memeLib.isConnected(); } public void connectToMeme(String id) { Log.d("DEBUG", "MAIN:: connectToMeme"); lastConnectedMemeID = id; memeLib.connect(id); } public void disconnectToMeme() { if (memeLib.isConnected()) { memeLib.disconnect(); } } @Override public void onBackPressed() { Log.d("DEBUG", "MAIN:: press back!"); setUIPaused(false); cancel(false); } public boolean cancel(boolean allow_finish) { Fragment active = getSupportFragmentManager().findFragmentById(R.id.container); boolean processed = false; if (active instanceof MenuFragmentBase) { processed = ((MenuFragmentBase) active).menuBack(); } if (!processed) { if (allow_finish || hasBackStackEntryCount()) { super.onBackPressed(); processed = true; } } return processed; } void changeMainBackgroud(final int resId) { handler.post(new Runnable() { @Override public void run() { mainLayout.setBackgroundResource(resId); } }); } void changeSettingButton(final boolean isRev) { final String overflowDesc = getString(R.string.accessibility_overflow); final ViewGroup decor = (ViewGroup) getWindow().getDecorView(); decor.post(new Runnable() { @Override public void run() { final ArrayList<View> outViews = new ArrayList<>(); decor.findViewsWithText(outViews, overflowDesc, View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION); if (outViews.isEmpty()) { return; } ImageView overflow = (ImageView) outViews.get(0); if (isRev) { overflow.setImageResource(R.mipmap.ic_setting_rev); } else { overflow.setImageResource(R.mipmap.ic_setting); } } }); } void updateActionBar(String title, boolean isRev) { Log.d("DEBUG", "updateActionBar 0"); ActionBar target = getSupportActionBar(); if (target != null) { Log.d("DEBUG", "updateActionBar 1"); target.setTitle(String.format(" %s", title)); target.setDisplayHomeAsUpEnabled(false); target.setDisplayShowHomeEnabled(true); target.setDisplayUseLogoEnabled(false); if (isRev) { target.setBackgroundDrawable(getDrawable(R.color.no0)); } else { target.setBackgroundDrawable(getDrawable(R.color.no4)); } /* switch (batteryStatus) { case 1: if (isRev) { } else { target.setLogo(R.drawable.connected_caution); } break; case 2: if (isRev) { } else { target.setLogo(R.drawable.connected_30); } break; case 3: if (isRev) { } else { target.setLogo(R.drawable.connected_50); } break; case 4: if (isRev) { } else { target.setLogo(R.drawable.connected_80); } break; case 5: if (isRev) { } else { target.setLogo(R.drawable.connected_full); } break; default: if (isRev) { } else { target.setLogo(R.drawable.not_connected); } break; } */ } } void updateActionBarLogo(final boolean isRev) { final ActionBar target = getSupportActionBar(); if (target != null) { Log.d("DEBUG", "MAIN:: updateActionBarLogo " + isRev); handler.post(new Runnable() { @Override public void run() { target.setDisplayHomeAsUpEnabled(false); //invalidateOptionsMenu(); target.setDisplayShowHomeEnabled(true); target.setDisplayUseLogoEnabled(true); if (isRev) { target.setBackgroundDrawable(getDrawable(R.color.no0)); } else { target.setBackgroundDrawable(getDrawable(R.color.no4)); } switch (batteryStatus) { case 1: if (isRev) { target.setLogo(R.mipmap.connected_caution_rev); } else { target.setLogo(R.mipmap.connected_caution); } break; case 2: if (isRev) { target.setLogo(R.mipmap.connected_30_rev); } else { target.setLogo(R.mipmap.connected_30); } break; case 3: if (isRev) { target.setLogo(R.mipmap.connected_50_rev); } else { target.setLogo(R.mipmap.connected_50); } break; case 4: if (isRev) { target.setLogo(R.mipmap.connected_80_rev); } else { target.setLogo(R.mipmap.connected_80); } break; case 5: if (isRev) { target.setLogo(R.mipmap.connected_full_rev); } else { target.setLogo(R.mipmap.connected_full); } break; default: if (isRev) { target.setLogo(R.mipmap.not_connected_rev); } else { target.setLogo(R.mipmap.not_connected); } break; } } }); } } void transitToFragment(Fragment next) { setUIPaused(false); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(mainLayout.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); FragmentManager manager = getSupportFragmentManager(); FragmentTransaction transaction = manager.beginTransaction(); transaction.setCustomAnimations(R.anim.config_in, android.R.anim.fade_out, android.R.anim.fade_in, R.anim.config_out2); transaction.replace(R.id.container, next); transaction.addToBackStack(null); transaction.commit(); } private boolean hasBackStackEntryCount() { return getSupportFragmentManager().getBackStackEntryCount() > 0; } String getSavedValue(String key) { return preferences.getString(key, null); } String getSavedValue(String key, String initValue) { return preferences.getString(key, initValue); } boolean getSavedValue(String key, boolean flag) { return preferences.getBoolean(key, flag); } int getSavedValue(String key, int initValue) { return preferences.getInt(key, initValue); } float getSavedValue(String key, float initValue) { return preferences.getFloat(key, initValue); } void autoSaveValue(String key, String text) { Log.d("DEBUG", "SAVE PARAM:: " + key + " -> " + text); editor.putString(key, text); editor.apply(); } void autoSaveValue(String key, boolean flag) { Log.d("DEBUG", "SAVE PARAM:: " + key + " -> " + flag); editor.putBoolean(key, flag); editor.apply(); } void autoSaveValue(String key, int value) { Log.d("DEBUG", "SAVE PARAM:: " + key + " -> " + value); switch (key) { case "BLINK_TH": blinkThreshold = value; break; case "UD_TH": upDownThreshold = value; break; case "LR_TH": leftRightThreshold = value; break; case "ROLL_TH": rollThreshold = value; } editor.putInt(key, value); editor.apply(); } void autoSaveValue(String key, float value) { Log.d("DEBUG", "SAVE PARAM:: " + key + " -> " + value); switch (key) { case "PAUSE_TIME": pauseWaitTime = value; cancelWaitTime = value; break; } editor.putFloat(key, value); editor.apply(); } void showAuthScreen() { KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); if (!keyguardManager.isKeyguardSecure()) { basicConfigFragment.unlockAppIDandSecret(); return; } Intent intent = keyguardManager.createConfirmDeviceCredentialIntent(getString(R.string.unlock_auth_title), getString(R.string.unlock_auth_explain)); if (intent != null) { startActivityForResult(intent, 1); } } void showNotFoundMeme() { AlertDialogFragment alertDialogFragment = AlertDialogFragment.newInstance("meme"); alertDialogFragment.setCancelable(false); alertDialogFragment.setDialogListener(this); alertDialogFragment.show(getSupportFragmentManager(), "dialog"); } void showAppIDandSecretWarning() { AlertDialogFragment alertDialogFragment = AlertDialogFragment.newInstance("app_id_secret"); alertDialogFragment.setCancelable(false); alertDialogFragment.setDialogListener(this); alertDialogFragment.show(getSupportFragmentManager(), "dialog"); } boolean checkAppIDandSecret() { return (appID != null && appID.length() > 0 && appSecret != null && appSecret.length() > 0); } void restart() { PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, getIntent(), PendingIntent.FLAG_CANCEL_CURRENT); AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); alarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + 500, pendingIntent); finishAndRemoveTask(); } void renewBatteryState(int status) { Log.d("DEBUG", "renewBatteryState"); batteryStatus = status; //invalidateOptionsMenu(); if (getSupportActionBar().getTitle().length() <= 2) { updateActionBarLogo(isCameraMenuFragment); } } int getRootCardId(int position) { for (String key : ROOT_CARD_IDS.keySet()) { if (getSavedValue(key, true)) { if (--position < 0) { return ROOT_CARD_IDS.get(key); } } } Log.d("ERROR", "unexpected operation. if new root cards were added, edit ROOT_CARD_IDS as well."); return NO_ID; } int getEnabledCardNum() { int num = 0; for (String key : ROOT_CARD_IDS.keySet()) { if (getSavedValue(key, true)) { ++num; } } return num; } @Override public void doPositiveClick(String type) { switch (type) { case "welcome": if (Build.VERSION.SDK_INT >= 23) { requestGPSPermission(); } editor.putBoolean("SHOW_WELCOME", false); editor.apply(); break; case "network": checkBluetoothEnable(); break; case "meme": transitToFragment(basicConfigFragment); break; } } @Override public void doNegativeClick(String type) { switch (type) { case "meme_connect": Log.d("DEBUG", "meme_connect cancel"); stopScan(); handler.removeCallbacksAndMessages(null); break; default: Log.d("DEBUG", "default"); handler.removeCallbacksAndMessages(null); finishAndRemoveTask(); break; } } IntentFilter getFilter() { return (new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); } boolean authenticate() { //Log.d("DEBUG", "SPOTIFY:: authenticate " + getRedirectUri().toString()); if (isNetworkEnable && !isAuthenticated && getSavedValue("SPOTIFY_USE", false)) { AuthenticationRequest.Builder builder = new Builder(getString(R.string.spotify_client_id), Type.TOKEN, "jins-meme-bridge-login://callback"); builder.setShowDialog(false).setScopes(new String[] { "user-read-private", "playlist-read", "playlist-read-private", "user-follow-read", "user-library-read", "streaming" }); final AuthenticationRequest request = builder.build(); AuthenticationClient.openLoginActivity(this, REQUEST_CODE, request); return false; } else { return true; } } void logout() { mPlayer.logout(); } private void onAuthenticationComplete(AuthenticationResponse authResponse, String clientID) { Log.d("DEBUG", "Got authentication token"); if (mPlayer == null) { Config playerConfig = new Config(this, authResponse.getAccessToken(), clientID); mPlayer = Spotify.getPlayer(playerConfig, this, new SpotifyPlayer.InitializationObserver() { @Override public void onInitialized(SpotifyPlayer player) { Log.d("DEBUG", "-- Player initialized --"); mPlayer.setConnectivityStatus(mOperationCallback, getNetworkConnectivity(MainActivity.this)); mPlayer.addNotificationCallback(MainActivity.this); mPlayer.addConnectionStateCallback(MainActivity.this); } @Override public void onError(Throwable error) { Log.d("DEBUG", "Error in initialization: " + error.getMessage()); } }); } else { mPlayer.login(authResponse.getAccessToken()); } } private Connectivity getNetworkConnectivity(Context context) { ConnectivityManager connectivityManager; connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo(); if (activeNetwork != null && activeNetwork.isConnected()) { return Connectivity.fromNetworkType(activeNetwork.getType()); } else { return Connectivity.OFFLINE; } } void setShuffle(boolean flag) { mPlayer.setShuffle(mOperationCallback, flag); } void setPlayUri(String uri) { mPlayer.playUri(mOperationCallback, uri, 0, 0); } void setPause() { mPlayer.pause(mOperationCallback); } boolean isPlaying() { return mPlayer.getPlaybackState().isPlaying; } String processRequestToken(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE) { final AuthenticationResponse response = AuthenticationClient.getResponse(resultCode, data); SpotifyConfigFragment.setAccessToken(response.getAccessToken()); switch (response.getType()) { case TOKEN: Log.d("DEBUG", "Spotify Token: " + response.getAccessToken()); onAuthenticationComplete(response, getString(R.string.spotify_client_id)); SpotifyConfigFragment.setIsLoggedIn(true); break; case ERROR: Log.d("DEBUG", "Spotify Error: " + response.getError()); break; default: Log.d("DEBUG", "Spotify Other: " + response.getState()); break; } } return SpotifyConfigFragment.getAccessToken(); } @Override public void onConnectionMessage(String s) { Log.d("DEBUG", "SPOTIFY:: Received connection message: " + s); } @Override public void onLoggedIn() { Log.d("DEBUG", "SPOTIFY:: User logged in."); isAuthenticated = true; spotifyConfigFragment.getPlaylist(); } @Override public void onLoggedOut() { Log.d("DEBUG", "SPOTIFY:: User logged out."); isAuthenticated = false; } @Override public void onLoginFailed(Error error) { Log.d("DEBUG", "SPOTIFY:: Loggin failed."); } @Override public void onPlaybackEvent(PlayerEvent playerEvent) { } @Override public void onPlaybackError(Error error) { } @Override public void onTemporaryError() { Log.d("DEBUG", "SPOTIFY:: Temporary error occurred."); } }