Java tutorial
/** * Copyright 2013 Ryan Shaw (ryanfx1@gmail.com) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package com.github.opengarageapp.activity; import java.io.IOException; import java.util.List; import org.apache.http.HttpStatus; import com.github.OpenGarageApp; import com.github.opengarageapp.GarageService; import com.github.opengarageapp.GarageStateService; import com.github.opengarageapp.GarageToggleService; import com.github.testapp.R; import android.os.Bundle; import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.AccountManagerCallback; import android.accounts.AccountManagerFuture; import android.accounts.AuthenticatorException; import android.accounts.OperationCanceledException; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager.RunningServiceInfo; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private OpenGarageApp application; private Button toggleButton1; private Button closeButton1; private TextView status1; private Button toggleButton2; private Button closeButton2; private TextView status2; private final static int AUTHENTICATION_INTENT = 0; @Override protected void onPause() { super.onPause(); unregisterReceiver(receiver); } @Override protected void onResume() { super.onResume(); IntentFilter filter = new IntentFilter(); filter.addAction(GarageToggleService.INTENT_CLOSE1); filter.addAction(GarageToggleService.INTENT_TOGGLE1); filter.addAction(GarageToggleService.INTENT_ERROR); filter.addAction(GarageToggleService.INTENT_STATE1); filter.addAction(GarageToggleService.INTENT_CLOSE2); filter.addAction(GarageToggleService.INTENT_TOGGLE2); filter.addAction(GarageToggleService.INTENT_ERROR); filter.addAction(GarageToggleService.INTENT_STATE2); registerReceiver(receiver, filter); // Start up the getState loop. if (application.getSelectedAccount() != null) { startStateLoop(); } // If the actvitiy was closed before the previous service started, the // buttons // will still be in a disabled state. Re-enable them here. if (!isServiceRunning(GarageToggleService.class.getName())) { enableButtons1(true); enableButtons2(true); } } public boolean isServiceRunning(String serviceClassName) { final ActivityManager activityManager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE); final List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE); for (RunningServiceInfo runningServiceInfo : services) { if (runningServiceInfo.service.getClassName().equals(serviceClassName)) { return true; } } return false; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); toggleButton1 = (Button) findViewById(R.id.toggle_garage_button1); closeButton1 = (Button) findViewById(R.id.close_garage_button1); status1 = (TextView) findViewById(R.id.status1); closeButton1.setOnClickListener(buttonListener); toggleButton1.setOnClickListener(buttonListener); toggleButton2 = (Button) findViewById(R.id.toggle_garage_button2); closeButton2 = (Button) findViewById(R.id.close_garage_button2); status2 = (TextView) findViewById(R.id.status2); closeButton2.setOnClickListener(buttonListener); toggleButton2.setOnClickListener(buttonListener); application = (OpenGarageApp) getApplication(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.action_settings) { startActivity(new Intent(this, ConfigurationActivity.class)); return true; } return super.onOptionsItemSelected(item); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); String action = data.getAction(); if (requestCode == AUTHENTICATION_INTENT) { if (resultCode == RESULT_OK) { getAuthAndDo(action); } else { enableButtons1(true); enableButtons2(true); } } } private OnClickListener buttonListener = new OnClickListener() { @Override public void onClick(View v) { if (application.getSelectedAccount() != null) { // Disable all of the buttons enableButtons1(false); enableButtons2(false); // Handle Door1 Presses if (v.getId() == R.id.toggle_garage_button1) { getAuthAndDo(GarageToggleService.INTENT_TOGGLE1); } else if (v.getId() == R.id.close_garage_button1) { getAuthAndDo(GarageToggleService.INTENT_CLOSE1); } // Handle Door2 Presses if (v.getId() == R.id.toggle_garage_button2) { getAuthAndDo(GarageToggleService.INTENT_TOGGLE2); } else if (v.getId() == R.id.close_garage_button2) { getAuthAndDo(GarageToggleService.INTENT_CLOSE2); } } else { Toast.makeText(MainActivity.this, "User Account must be selected first!", Toast.LENGTH_LONG).show(); } } }; private BroadcastReceiver receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { int statusCode = intent.getExtras().getInt(GarageToggleService.EXTRA_HTTP_RESPONSE_CODE); String response = intent.getExtras().getString(GarageToggleService.EXTRA_HTTP_RESPONSE_TEXT); // Door 1 - CLOSED/CLOSING if (intent.getAction().equals(GarageToggleService.INTENT_CLOSE1)) { enableButtons1(true); if (statusCode == HttpStatus.SC_OK) { if (response.equals("closed")) { Toast.makeText(MainActivity.this, "Door is already closed!", Toast.LENGTH_LONG).show(); } else { Toast.makeText(MainActivity.this, "Door1 is closing...", Toast.LENGTH_LONG).show(); } } else { Toast.makeText(MainActivity.this, "Error Occured - Status1: " + statusCode + " " + response, Toast.LENGTH_LONG).show(); } // Door 1 - Toggle } else if (intent.getAction().equals(GarageToggleService.INTENT_TOGGLE1)) { enableButtons1(true); if (statusCode == HttpStatus.SC_OK) { Toast.makeText(MainActivity.this, "Door1 is toggling", Toast.LENGTH_LONG).show(); } else { Toast.makeText(MainActivity.this, "Error Occured - Status: " + statusCode + " " + response, Toast.LENGTH_LONG).show(); } // Door 1 - State } else if (intent.getAction().equals(GarageToggleService.INTENT_STATE1)) { if (statusCode == HttpStatus.SC_OK) { if (response.equalsIgnoreCase("CLOSED")) { status1.setText(response); } else if (response.equalsIgnoreCase("OPEN")) { status1.setText(response); } else if (response.equalsIgnoreCase("UNKNOWN")) { status1.setText(response); } else { status1.setText("Invalid state response " + response); } startGetStateService(1); } else if (statusCode == HttpStatus.SC_UNAUTHORIZED) { // If we were rejected, maybe our auth token is expired. MainActivity.this.invalidateAuthToken(); Log.e(MainActivity.class.getName(), "Unauthorized request!"); status1.setText("Authentication Failure"); startGetStateService(1); } else { status1.setText("..."); startGetStateService(1); } } // Door 2 - CLOSED/CLOSING if (intent.getAction().equals(GarageToggleService.INTENT_CLOSE2)) { enableButtons2(true); if (statusCode == HttpStatus.SC_OK) { if (response.equals("closed")) { Toast.makeText(MainActivity.this, "Door2 is already closed!", Toast.LENGTH_LONG).show(); } else { Toast.makeText(MainActivity.this, "Door2 is closing...", Toast.LENGTH_LONG).show(); } } else { Toast.makeText(MainActivity.this, "Error Occured - Status2: " + statusCode + " " + response, Toast.LENGTH_LONG).show(); } // Door 2 - Toggle } else if (intent.getAction().equals(GarageToggleService.INTENT_TOGGLE2)) { enableButtons2(true); if (statusCode == HttpStatus.SC_OK) { Toast.makeText(MainActivity.this, "Door2 is toggling", Toast.LENGTH_LONG).show(); } else { Toast.makeText(MainActivity.this, "Error Occured - Status: " + statusCode + " " + response, Toast.LENGTH_LONG).show(); } // Door 2 - State } else if (intent.getAction().equals(GarageToggleService.INTENT_STATE2)) { if (statusCode == HttpStatus.SC_OK) { if (response.equalsIgnoreCase("CLOSED")) { status2.setText(response); } else if (response.equalsIgnoreCase("OPEN")) { status2.setText(response); } else if (response.equalsIgnoreCase("UNKNOWN")) { status2.setText(response); } else { status2.setText("Invalid state response " + response); } startGetStateService(2); } else if (statusCode == HttpStatus.SC_UNAUTHORIZED) { // If we were rejected, maybe our auth token is expired. MainActivity.this.invalidateAuthToken(); Log.e(MainActivity.class.getName(), "Unauthorized request!"); status2.setText("Authentication Failure"); startGetStateService(2); } else { status2.setText("..."); startGetStateService(2); } } } }; public void enableButtons1(boolean enabled) { toggleButton1.setEnabled(enabled); closeButton1.setEnabled(enabled); } public void enableButtons2(boolean enabled) { toggleButton2.setEnabled(enabled); closeButton2.setEnabled(enabled); } public void getAuthAndDo(String intent) { Account account = application.getSelectedAccount(); AccountManager manager = AccountManager.get(this); manager.getAuthToken(account, "oauth2:https://www.googleapis.com/auth/userinfo.email", new Bundle(), this, new GarageActionAuthCallback(intent), null); } public void invalidateAuthToken() { AccountManager manager = AccountManager.get(this); manager.invalidateAuthToken("com.google", application.getAuthToken()); } private void startStateLoop() { getAuthAndDo(GarageService.INTENT_STATE1); getAuthAndDo(GarageService.INTENT_STATE2); } private void startGetStateService(int door) { Intent serviceIntent = new Intent(MainActivity.this, GarageStateService.class); switch (door) { case 1: serviceIntent.setAction(GarageService.INTENT_STATE1); startService(serviceIntent); case 2: serviceIntent.setAction(GarageService.INTENT_STATE2); startService(serviceIntent); } } private void startToggleService(int door) { Intent serviceIntent = new Intent(MainActivity.this, GarageToggleService.class); switch (door) { case 1: serviceIntent.setAction(GarageService.INTENT_TOGGLE1); startService(serviceIntent); case 2: serviceIntent.setAction(GarageService.INTENT_TOGGLE2); startService(serviceIntent); } } private void startCloseService(int door) { Intent serviceIntent = new Intent(MainActivity.this, GarageToggleService.class); switch (door) { case 1: serviceIntent.setAction(GarageService.INTENT_CLOSE1); startService(serviceIntent); case 2: serviceIntent.setAction(GarageService.INTENT_CLOSE2); startService(serviceIntent); } } private class GarageActionAuthCallback implements AccountManagerCallback<Bundle> { private String action = null; private GarageActionAuthCallback(String action) { this.action = action; } @Override public void run(AccountManagerFuture<Bundle> result) { Bundle bundle; try { bundle = result.getResult(); Intent intent = (Intent) bundle.get(AccountManager.KEY_INTENT); // If further authorization from the user is required if (intent != null) { intent.setAction(action); startActivityForResult(intent, AUTHENTICATION_INTENT); } // Otherwise, let's do the action we wanted to do else { String token = bundle.getString(AccountManager.KEY_AUTHTOKEN); application.setAuthToken(token); if (action.equals(GarageService.INTENT_STATE1)) { startGetStateService(1); } else if (action.equals(GarageService.INTENT_TOGGLE1)) { startToggleService(1); } else if (action.equals(GarageService.INTENT_CLOSE1)) { startCloseService(1); } else if (action.equals(GarageService.INTENT_TOGGLE2)) { startToggleService(2); } else if (action.equals(GarageService.INTENT_CLOSE2)) { startCloseService(2); } else if (action.equals(GarageService.INTENT_STATE2)) { startGetStateService(2); } } } catch (OperationCanceledException e) { Log.e(this.getClass().getName(), "Authentication Cancelled", e); enableButtons1(true); enableButtons2(true); Toast.makeText(MainActivity.this, "Authentication Cancelled: " + e.getMessage(), Toast.LENGTH_LONG) .show(); } catch (AuthenticatorException e) { Log.e(this.getClass().getName(), "Authentication Failed", e); enableButtons1(true); enableButtons2(true); Toast.makeText(MainActivity.this, "Authentication Failed: " + e.getMessage(), Toast.LENGTH_LONG) .show(); } catch (IOException e) { Log.e(this.getClass().getName(), "Authentication Failed", e); enableButtons1(true); enableButtons2(true); // IOException means the AccountManager had a network error // call, restart the state loop. startStateLoop(); } } } }