Java tutorial
/** * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 3 of the License, or (at your option) any later * version. * You should have received a copy of the GNU General Public License along with * this program; if not, see <http://www.gnu.org/licenses/>. * Use this application at your own risk. * * Copyright (c) 2009 by Harald Mueller and Sofia Lemons. */ package og.android.tether; import android.R.drawable; import android.annotation.TargetApi; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.app.ProgressDialog; import android.content.*; import android.content.pm.PackageManager; import android.graphics.Color; import android.graphics.PixelFormat; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.Html; import android.text.Spanned; import android.util.Log; import android.view.*; import android.view.View.OnClickListener; import android.view.animation.Animation; import android.view.animation.BounceInterpolator; import android.view.animation.ScaleAnimation; import android.widget.*; import android.widget.AdapterView.OnItemClickListener; import android.widget.CompoundButton.OnCheckedChangeListener; import com.google.analytics.tracking.android.EasyTracker; import com.google.analytics.tracking.android.TrackedActivity; import com.google.android.c2dm.C2DMessaging; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.miscwidgets.widget.Panel; import org.miscwidgets.widget.Panel.OnPanelListener; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; public class MainActivity extends TrackedActivity { private TetherApplication application = null; private ProgressDialog progressDialog; private ImageView startBtn = null; private OnClickListener startBtnListener = null; private ImageView stopBtn = null; private OnClickListener stopBtnListener = null; private CompoundButton lockBtn = null; private OnCheckedChangeListener lockBtnListener = null; private TextView radioModeLabel = null; private ImageView radioModeImage = null; private TextView progressTitle = null; private TextView progressText = null; private ProgressBar progressBar = null; private RelativeLayout downloadUpdateLayout = null; private RelativeLayout batteryTemperatureLayout = null; private CheckBox lockButtonCheckbox = null; private RelativeLayout trafficRow = null; private TextView downloadText = null; private TextView uploadText = null; private TextView downloadRateText = null; private TextView uploadRateText = null; private TextView batteryTemperature = null; private TableRow startTblRow = null; private TableRow stopTblRow = null; private ScaleAnimation animation = null; private RSSReader rssReader = null; private ListView rssView = null; private ArrayAdapter<Spanned> rssAdapter = null; private JSONArray jsonRssArray = null; private Panel rssPanel = null; private TextView communityText = null; private LinearLayout bottomButtonLayout = null; private static int ID_DIALOG_STARTING = 0; private static int ID_DIALOG_STOPPING = 1; public static final int MESSAGE_CHECK_LOG = 1; public static final int MESSAGE_CANT_START_TETHER = 2; public static final int MESSAGE_DOWNLOAD_STARTING = 3; public static final int MESSAGE_DOWNLOAD_PROGRESS = 4; public static final int MESSAGE_DOWNLOAD_COMPLETE = 5; public static final int MESSAGE_DOWNLOAD_BLUETOOTH_COMPLETE = 6; public static final int MESSAGE_DOWNLOAD_BLUETOOTH_FAILED = 7; public static final int MESSAGE_TRAFFIC_START = 8; public static final int MESSAGE_TRAFFIC_COUNT = 9; public static final int MESSAGE_TRAFFIC_RATE = 10; public static final int MESSAGE_TRAFFIC_END = 11; public static final String MSG_TAG = "TETHER -> MainActivity"; public static MainActivity currentInstance = null; private static void setCurrent(MainActivity current) { MainActivity.currentInstance = current; } String tagURL(String url, String medium, String content, String campaign) { String p = url.contains("?") ? "&" : "?"; String source = "og.android.tether_" + application.getVersionNumber(); try { source = URLEncoder.encode(source, "UTF-8"); medium = URLEncoder.encode(medium, "UTF-8"); content = URLEncoder.encode(content, "UTF-8"); campaign = URLEncoder.encode(campaign, "UTF-8"); } catch (UnsupportedEncodingException e) { } return url + p + "utm_source=" + source + "&utm_medium=" + medium + "&utm_content=" + content + "&utm_campaign=" + campaign; } /** Called when the activity is first created. */ @TargetApi(4) @Override public void onCreate(Bundle savedInstanceState) { Log.d(MSG_TAG, "Calling onCreate()"); super.onCreate(savedInstanceState); setContentView(R.layout.main); // Init Application this.application = (TetherApplication) this.getApplication(); MainActivity.setCurrent(this); // Init Table-Rows this.startTblRow = (TableRow) findViewById(R.id.startRow); this.stopTblRow = (TableRow) findViewById(R.id.stopRow); this.radioModeImage = (ImageView) findViewById(R.id.radioModeImage); this.progressBar = (ProgressBar) findViewById(R.id.progressBar); this.progressText = (TextView) findViewById(R.id.progressText); this.progressTitle = (TextView) findViewById(R.id.progressTitle); this.downloadUpdateLayout = (RelativeLayout) findViewById(R.id.layoutDownloadUpdate); this.batteryTemperatureLayout = (RelativeLayout) findViewById(R.id.layoutBatteryTemp); this.lockButtonCheckbox = (CheckBox) findViewById(R.id.lockButton); this.trafficRow = (RelativeLayout) findViewById(R.id.trafficRow); this.downloadText = (TextView) findViewById(R.id.trafficDown); this.uploadText = (TextView) findViewById(R.id.trafficUp); this.downloadRateText = (TextView) findViewById(R.id.trafficDownRate); this.uploadRateText = (TextView) findViewById(R.id.trafficUpRate); this.batteryTemperature = (TextView) findViewById(R.id.batteryTempText); // Define animation animation = new ScaleAnimation(0.9f, 1, 0.9f, 1, // From x, to x, from y, to y ScaleAnimation.RELATIVE_TO_SELF, 0.5f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f); animation.setDuration(600); animation.setFillAfter(true); animation.setStartOffset(0); animation.setRepeatCount(1); animation.setRepeatMode(Animation.REVERSE); if (this.application.startupCheckPerformed == false) { if (this.application.settings.getLong("install_timestamp", -1) == -1) { long t = System.currentTimeMillis() / 1000; this.application.preferenceEditor.putLong("install_timestamp", t); } } this.application.reportStats(-1, false); // open ad bar openAdBar(); // Startup-Check if (this.application.startupCheckPerformed == false) { this.application.startupCheckPerformed = true; String regId = C2DMessaging.getRegistrationId(this); boolean registered = this.application.settings.getBoolean("c2dm_registered", false); if (!registered || regId == null || "".equals(regId)) { Log.d(MSG_TAG, "C2DM Registering"); C2DMessaging.register(this, DeviceRegistrar.SENDER_ID); } else { Log.d(MSG_TAG, "C2DM already registered"); } // Check if required kernel-features are enabled if (!this.application.coretask.isNetfilterSupported()) { this.openNoNetfilterDialog(); this.application.accessControlSupported = false; this.application.whitelist.remove(); } else { // Check if access-control-feature is supported by kernel if (!this.application.coretask.isAccessControlSupported()) { if (this.application.settings.getBoolean("warning_noaccesscontrol_displayed", false) == false) { this.openNoAccessControlDialog(); this.application.preferenceEditor.putBoolean("warning_noaccesscontrol_displayed", true); this.application.preferenceEditor.commit(); } this.application.accessControlSupported = false; this.application.whitelist.remove(); } } // Check if binaries need to be updated if (this.application.binariesExists() == false || this.application.coretask.filesetOutdated()) { if (this.application.coretask.hasRootPermission()) { this.application.installFiles(); } } // Open donate-dialog this.openDonateDialog(); // Check for updates this.application.checkForUpdate(); } // Check root-permission, files if (!this.application.coretask.hasRootPermission()) openLaunchedDialog(true); this.rssReader = new RSSReader(getApplicationContext(), TetherApplication.FORUM_RSS_URL); this.rssView = (ListView) findViewById(R.id.RSSView); this.rssAdapter = new ArrayAdapter<Spanned>(this, R.layout.rss_item); this.rssView.setAdapter(this.rssAdapter); this.rssView.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Log.d(MSG_TAG, parent + ":" + view + ":" + position + ":" + id); MainActivity.this.application.statRSSClicks(); String url = null; try { url = MainActivity.this.jsonRssArray.getJSONObject(position).getString("link"); } catch (JSONException e) { url = TetherApplication.FORUM_URL; } url = tagURL(url, "android", "rss", "community"); Intent viewRssLink = new Intent(Intent.ACTION_VIEW).setData(Uri.parse(url)); try { startActivity(viewRssLink); } catch (ActivityNotFoundException e) { url = tagURL(TetherApplication.FORUM_URL, "android", "rss", "community"); viewRssLink = new Intent(Intent.ACTION_VIEW).setData(Uri.parse(url)); try { startActivity(viewRssLink); } catch (ActivityNotFoundException e2) { e2.printStackTrace(); } } } }); this.rssPanel = (Panel) findViewById(R.id.RSSPanel); this.rssPanel.setInterpolator(new BounceInterpolator()); this.rssPanel.setOnPanelListener(new OnPanelListener() { public void onPanelClosed(Panel panel) { hideCommunityText(true); MainActivity.this.application.preferenceEditor.putBoolean("rss_closed", true).commit(); } public void onPanelOpened(Panel panel) { hideCommunityText(false); MainActivity.this.application.preferenceEditor.putBoolean("rss_closed", false).commit(); } }); this.communityText = (TextView) findViewById(R.id.communityHeader); this.communityText.setOnClickListener(new OnClickListener() { public void onClick(View v) { MainActivity.this.rssPanel.setOpen(!MainActivity.this.rssPanel.isOpen(), true); } }); hideCommunityText(!this.rssPanel.isOpen()); this.bottomButtonLayout = (LinearLayout) findViewById(R.id.bottomButtonLayout); ((Button) findViewById(R.id.anchorLinkButton)).setOnClickListener(new OnClickListener() { public void onClick(View v) { startGooglePlayMeshclient("nonroot_tether"); } }); ((Button) findViewById(R.id.configButton)).setOnClickListener(new OnClickListener() { public void onClick(View v) { startActivityForResult(new Intent(MainActivity.this, SetupActivity.class).setAction("FOO"), 33); } }); // Start Button this.startBtn = (ImageView) findViewById(R.id.startTetherBtn); this.startBtnListener = new OnClickListener() { public void onClick(View v) { Log.d(MSG_TAG, "StartBtn pressed ..."); new Thread(new Runnable() { public void run() { Intent intent = new Intent(TetherService.INTENT_MANAGE); intent.putExtra("state", TetherService.MANAGE_START); Log.d(MSG_TAG, "SENDING MANAGE: " + intent); MainActivity.this.sendBroadcast(intent); } }).start(); } }; this.startBtn.setOnClickListener(this.startBtnListener); // Stop Button this.stopBtn = (ImageView) findViewById(R.id.stopTetherBtn); this.stopBtnListener = new OnClickListener() { public void onClick(View v) { Log.d(MSG_TAG, "StopBtn pressed ..."); if (MainActivity.this.lockBtn.isChecked()) { Log.d(MSG_TAG, "Tether was locked ..."); MainActivity.this.application.displayToastMessage(getString(R.string.main_activity_locked)); return; } new Thread(new Runnable() { public void run() { Intent intent = new Intent(TetherService.INTENT_MANAGE); intent.setAction(TetherService.INTENT_MANAGE); intent.putExtra("state", TetherService.MANAGE_STOP); Log.d(MSG_TAG, "Sending Intent: " + intent); MainActivity.this.sendBroadcast(intent); } }).start(); } }; this.stopBtn.setOnClickListener(this.stopBtnListener); this.lockBtn = (CompoundButton) findViewById(R.id.lockButton); this.lockBtnListener = new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { Log.d(MSG_TAG, "LockBtn pressed ..."); } }; this.lockBtn.setOnCheckedChangeListener(this.lockBtnListener); // Toggles between start and stop screen this.toggleStartStop(); } private void openAdBar() { LayoutInflater li = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); final View ad_view = li.inflate(R.layout.ad_view, null); ad_view.setBackgroundColor(Color.TRANSPARENT); final WindowManager wm = getWindowManager(); WindowManager.LayoutParams wmParams = new WindowManager.LayoutParams(); wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT; wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT; wmParams.gravity = Gravity.BOTTOM; wmParams.y = 100; wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; wmParams.format = PixelFormat.TRANSLUCENT; wm.addView(ad_view, wmParams); View ad_open = ad_view.findViewById(R.id.ad_open); View ad_close = ad_view.findViewById(R.id.ad_close); OnClickListener adListener = new OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.ad_open: Log.i(MSG_TAG, "ad_open"); Intent i = new Intent(); i.setAction(Intent.ACTION_VIEW); i.addCategory(Intent.CATEGORY_BROWSABLE); i.setData(Uri.parse( "market://details?id=com.opengarden.radiofreenet&referrer=utm_source%3Dog.android.tether%26utm_medium%3Dandroid%26utm_campaign%3Dbanner%26utm_content%3Dinstall")); try { startActivity(i); } catch (android.content.ActivityNotFoundException e) { Log.e(MSG_TAG, "", e); MainActivity.this.application.displayToastMessage(e.toString()); } break; case R.id.ad_close: Log.i(MSG_TAG, "ad_close"); wm.removeView(ad_view); break; default: Log.i(MSG_TAG, "default"); break; } } }; ad_open.setOnClickListener(adListener); ad_close.setOnClickListener(adListener); } @Override public boolean onTrackballEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { Log.d(MSG_TAG, "Trackball pressed ..."); String tetherStatus = this.application.coretask.getProp("tether.status"); if (!tetherStatus.equals("running")) { new AlertDialog.Builder(this).setMessage(getString(R.string.main_activity_trackball_pressed_start)) .setPositiveButton(getString(R.string.main_activity_confirm), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { Log.d(MSG_TAG, "Trackball press confirmed ..."); MainActivity.currentInstance.startBtnListener .onClick(MainActivity.currentInstance.startBtn); } }) .setNegativeButton(getString(R.string.main_activity_cancel), null).show(); } else { if (MainActivity.this.lockBtn.isChecked()) { Log.d(MSG_TAG, "Tether was locked ..."); MainActivity.this.application.displayToastMessage(getString(R.string.main_activity_locked)); return false; } new AlertDialog.Builder(this).setMessage(getString(R.string.main_activity_trackball_pressed_stop)) .setPositiveButton(getString(R.string.main_activity_confirm), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { Log.d(MSG_TAG, "Trackball press confirmed ..."); MainActivity.currentInstance.stopBtnListener .onClick(MainActivity.currentInstance.startBtn); } }) .setNegativeButton(getString(R.string.main_activity_cancel), null).show(); } } return true; } public void onStop() { Log.d(MSG_TAG, "Calling onStop()"); super.onStop(); } public void onDestroy() { Log.d(MSG_TAG, "Calling onDestroy()"); super.onDestroy(); } public void onPause() { Log.d(MSG_TAG, "Calling onPause()"); try { unregisterReceiver(this.intentReceiver); } catch (Exception ex) { ; } super.onPause(); } protected void onNewIntent(Intent intent) { Log.d(MSG_TAG, "onNewIntent(): " + intent); setIntent(intent); } public void onResume() { Log.d(MSG_TAG, "Calling onResume()"); Log.d(MSG_TAG, "ADVCONFIG " + this.application.settings.getBoolean("configadv", false)); try { if (getIntent().getData().getPath().equals("/LAUNCH_CHECK")) { setIntent(null); openLaunchedDialog(false); } } catch (Exception e) { } this.showRadioMode(); super.onResume(); this.intentFilter = new IntentFilter(); // Check, if the battery-temperature should be displayed if (this.application.settings.getString("batterytemppref", "celsius").equals("disabled") == false) { // create the IntentFilter that will be used to listen // to battery status broadcasts this.intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); this.batteryTemperatureLayout.setVisibility(View.VISIBLE); } else { this.batteryTemperatureLayout.setVisibility(View.INVISIBLE); } this.intentFilter.addAction(TetherService.INTENT_TRAFFIC); this.intentFilter.addAction(TetherService.INTENT_STATE); this.intentFilter.addAction(RSSReader.MESSAGE_JSON_RSS); this.intentFilter.addAction(TetherApplication.MESSAGE_POST_STATS); registerReceiver(this.intentReceiver, this.intentFilter); this.toggleStartStop(); // Check, if the lockbutton should be displayed if (this.stopTblRow.getVisibility() == View.VISIBLE && this.application.settings.getBoolean("lockscreenpref", true) == false) { this.lockButtonCheckbox.setVisibility(View.VISIBLE); } else { this.lockButtonCheckbox.setVisibility(View.GONE); } this.rssPanel.setOpen(!this.application.settings.getBoolean("rss_closed", false), true); hideCommunityText(!this.rssPanel.isOpen()); this.rssReader.readRSS(); } private static final int MENU_SETUP = 0; private static final int MENU_LOG = 1; private static final int MENU_ABOUT = 2; private static final int MENU_ACCESS = 3; private static final int MENU_CONNECT = 4; private static final int MENU_COMMUNITY = 5; private static final int MENU_TWITTER = 6; private static final int MENU_FACEBOOK = 7; @Override public boolean onCreateOptionsMenu(Menu menu) { boolean supRetVal = super.onCreateOptionsMenu(menu); SubMenu setup = menu.addSubMenu(0, MENU_SETUP, 0, getString(R.string.main_activity_settings)); setup.setIcon(drawable.ic_menu_preferences); if (this.application.accessControlSupported) { SubMenu accessctr = menu.addSubMenu(0, MENU_ACCESS, 0, getString(R.string.main_activity_accesscontrol)); accessctr.setIcon(drawable.ic_menu_manage); } SubMenu connect = menu.addSubMenu(0, MENU_CONNECT, 0, getString(R.string.main_activity_connect)); connect.setIcon(drawable.ic_menu_add); SubMenu log = menu.addSubMenu(0, MENU_LOG, 0, getString(R.string.main_activity_showlog)); log.setIcon(drawable.ic_menu_agenda); SubMenu community = menu.addSubMenu(0, MENU_COMMUNITY, 0, getString(R.string.main_activity_community)); community.setIcon(drawable.ic_menu_myplaces); SubMenu about = menu.addSubMenu(0, MENU_ABOUT, 0, getString(R.string.main_activity_about)); about.setIcon(drawable.ic_menu_info_details); SubMenu twitter = menu.addSubMenu(0, MENU_TWITTER, 0, getString(R.string.main_activity_twitter)); SubMenu facebook = menu.addSubMenu(0, MENU_FACEBOOK, 0, getString(R.string.main_activity_facebook)); return supRetVal; } @Override public boolean onOptionsItemSelected(MenuItem menuItem) { boolean supRetVal = super.onOptionsItemSelected(menuItem); Log.d(MSG_TAG, "Menuitem:getId - " + menuItem.getItemId()); switch (menuItem.getItemId()) { case MENU_SETUP: startActivityForResult(new Intent(MainActivity.this, SetupActivity.class), 0); break; case MENU_LOG: startActivityForResult(new Intent(MainActivity.this, LogActivity.class), 0); break; case MENU_ABOUT: this.openAboutDialog(); break; case MENU_ACCESS: startActivityForResult(new Intent(MainActivity.this, AccessControlActivity.class), 0); break; case MENU_CONNECT: startActivity(new Intent(MainActivity.this, ConnectActivity.class)); break; case MENU_COMMUNITY: this.application.statCommunityClicks(); startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.communityUrl)))); break; case MENU_TWITTER: try { getPackageManager().getPackageInfo("com.twitter.android", PackageManager.GET_ACTIVITIES); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setClassName("com.twitter.android", "com.twitter.android.ProfileActivity"); intent.putExtra("user_id", 221897815L); startActivity(intent); } catch (PackageManager.NameNotFoundException e) { startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://twitter.com/OpenGarden"))); } break; case MENU_FACEBOOK: try { getPackageManager().getPackageInfo("com.facebook.katana", PackageManager.GET_ACTIVITIES); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("fb://profile/199666333378900")); startActivity(intent); } catch (PackageManager.NameNotFoundException e) { startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://facebook.com/OpenGarden"))); } break; } return supRetVal; } @Override protected Dialog onCreateDialog(int id) { if (id == ID_DIALOG_STARTING) { progressDialog = new ProgressDialog(this); progressDialog.setTitle(getString(R.string.main_activity_start)); progressDialog.setMessage(getString(R.string.main_activity_start_summary)); progressDialog.setIndeterminate(false); progressDialog.setCancelable(true); return progressDialog; } else if (id == ID_DIALOG_STOPPING) { progressDialog = new ProgressDialog(this); progressDialog.setTitle(getString(R.string.main_activity_stop)); progressDialog.setMessage(getString(R.string.main_activity_stop_summary)); progressDialog.setIndeterminate(false); progressDialog.setCancelable(true); return progressDialog; } return null; } /** *Listens for intent broadcasts; Needed for the temperature-display, traffic count, and service state */ private IntentFilter intentFilter; private BroadcastReceiver intentReceiver; public Handler viewUpdateHandler; public MainActivity() { intentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.d(MSG_TAG, "onReceive() " + intent); String action = intent.getAction(); if (action.equals(Intent.ACTION_BATTERY_CHANGED)) { int temp = (intent.getIntExtra("temperature", 0)); MainActivity.this.application.lastTemperature = temp; int celsius = (int) ((temp + 5) / 10); int fahrenheit = (int) (((temp / 10) / 0.555) + 32 + 0.5); Log.d(MSG_TAG, "Temp ==> " + temp + " -- Celsius ==> " + celsius + " -- Fahrenheit ==> " + fahrenheit); if (MainActivity.this.application.settings.getString("batterytemppref", "celsius") .equals("celsius")) { batteryTemperature .setText("" + celsius + getString(R.string.main_activity_temperatureunit_celsius)); } else { batteryTemperature.setText( "" + fahrenheit + getString(R.string.main_activity_temperatureunit_fahrenheit)); } } else { //Log.d(MSG_TAG, "INTENT RECEIVED: "+intent.getAction()); if (action.equals(TetherService.INTENT_TRAFFIC)) updateTrafficDisplay(intent.getLongArrayExtra("traffic_count")); if (action.equals(TetherService.INTENT_STATE)) { Log.d(MSG_TAG, "STATE RECEIVED: " + intent.getIntExtra("state", 999)); try { switch (intent.getIntExtra("state", TetherService.STATE_IDLE)) { case TetherService.STATE_RESTARTING: try { MainActivity.this.dismissDialog(MainActivity.ID_DIALOG_STOPPING); } catch (Exception e) { } break; case TetherService.STATE_STARTING: MainActivity.this.showDialog(MainActivity.ID_DIALOG_STARTING); break; case TetherService.STATE_RUNNING: try { MainActivity.this.dismissDialog(MainActivity.ID_DIALOG_STARTING); } catch (Exception e) { } MainActivity.this.toggleStartStop(); break; case TetherService.STATE_STOPPING: MainActivity.this.showDialog(MainActivity.ID_DIALOG_STOPPING); break; case TetherService.STATE_IDLE: try { MainActivity.this.dismissDialog(MainActivity.ID_DIALOG_STOPPING); } catch (Exception e) { } MainActivity.this.toggleStartStop(); break; case TetherService.STATE_FAIL_LOG: try { MainActivity.this.dismissDialog(MainActivity.ID_DIALOG_STARTING); } catch (Exception e) { } MainActivity.this.application .displayToastMessage(getString(R.string.main_activity_start_errors)); MainActivity.this.toggleStartStop(); break; case TetherService.STATE_FAIL_EXEC_START: try { MainActivity.this.dismissDialog(MainActivity.ID_DIALOG_STARTING); } catch (Exception e) { } MainActivity.this.application .displayToastMessage(getString(R.string.main_activity_start_unable)); MainActivity.this.toggleStartStop(); break; case TetherService.STATE_FAIL_EXEC_STOP: try { MainActivity.this.dismissDialog(MainActivity.ID_DIALOG_STOPPING); } catch (Exception e) { } MainActivity.this.toggleStartStop(); break; } } catch (Exception e) { } finally { // MainActivity.this.toggleStartStop(); } } else if (action.equals(RSSReader.MESSAGE_JSON_RSS)) { updateRSSView(intent.getStringExtra(RSSReader.EXTRA_JSON_RSS)); } } } }; // ??? deprecated? viewUpdateHandler = new Handler() { public void handleMessage(Message msg) { Log.d(MSG_TAG, "MESSAGE: " + msg); switch (msg.what) { case MESSAGE_CHECK_LOG: Log.d(MSG_TAG, "Error detected. Check log."); MainActivity.this.application .displayToastMessage(getString(R.string.main_activity_start_errors)); MainActivity.this.toggleStartStop(); break; case MESSAGE_CANT_START_TETHER: Log.d(MSG_TAG, "Unable to start tethering!"); MainActivity.this.application .displayToastMessage(getString(R.string.main_activity_start_unable)); MainActivity.this.toggleStartStop(); break; case MESSAGE_TRAFFIC_START: MainActivity.this.trafficRow.setVisibility(View.VISIBLE); break; case MESSAGE_TRAFFIC_COUNT: MainActivity.this.trafficRow.setVisibility(View.VISIBLE); //??? long uploadTraffic = ((TetherService.DataCount) msg.obj).totalUpload; long downloadTraffic = ((TetherService.DataCount) msg.obj).totalDownload; long uploadRate = ((TetherService.DataCount) msg.obj).uploadRate; long downloadRate = ((TetherService.DataCount) msg.obj).downloadRate; // Set rates to 0 if values are negative if (uploadRate < 0) uploadRate = 0; if (downloadRate < 0) downloadRate = 0; MainActivity.this.uploadText.setText(MainActivity.this.formatCount(uploadTraffic, false)); MainActivity.this.downloadText.setText(MainActivity.this.formatCount(downloadTraffic, false)); MainActivity.this.downloadText.invalidate(); MainActivity.this.uploadText.invalidate(); MainActivity.this.uploadRateText.setText(MainActivity.this.formatCount(uploadRate, true)); MainActivity.this.downloadRateText.setText(MainActivity.this.formatCount(downloadRate, true)); MainActivity.this.downloadRateText.invalidate(); MainActivity.this.uploadRateText.invalidate(); break; case MESSAGE_TRAFFIC_END: MainActivity.this.trafficRow.setVisibility(View.INVISIBLE); break; case MESSAGE_DOWNLOAD_STARTING: Log.d(MSG_TAG, "Start progress bar"); MainActivity.this.progressBar.setIndeterminate(true); MainActivity.this.progressTitle.setText((String) msg.obj); MainActivity.this.progressText.setText("Starting..."); MainActivity.this.downloadUpdateLayout.setVisibility(View.VISIBLE); break; case MESSAGE_DOWNLOAD_PROGRESS: MainActivity.this.progressBar.setIndeterminate(false); MainActivity.this.progressText.setText(msg.arg1 + "k /" + msg.arg2 + "k"); MainActivity.this.progressBar.setProgress(msg.arg1 * 100 / msg.arg2); break; case MESSAGE_DOWNLOAD_COMPLETE: Log.d(MSG_TAG, "Finished download."); MainActivity.this.progressText.setText(""); MainActivity.this.progressTitle.setText(""); MainActivity.this.downloadUpdateLayout.setVisibility(View.GONE); break; case MESSAGE_DOWNLOAD_BLUETOOTH_COMPLETE: Log.d(MSG_TAG, "Finished bluetooth download."); MainActivity.this.startBtn.setClickable(true); MainActivity.this.radioModeLabel.setText("Bluetooth"); break; case MESSAGE_DOWNLOAD_BLUETOOTH_FAILED: Log.d(MSG_TAG, "FAILED bluetooth download."); MainActivity.this.startBtn.setClickable(true); MainActivity.this.application.preferenceEditor.putBoolean("bluetoothon", false); MainActivity.this.application.preferenceEditor.commit(); // TODO: More detailed popup info. MainActivity.this.application.displayToastMessage( "No bluetooth module for your kernel! Please report your kernel version."); default: MainActivity.this.toggleStartStop(); } super.handleMessage(msg); } }; } // constructor private synchronized void updateRSSView(String JSONrss) { Log.d(MSG_TAG, "Intent JSONRSS: " + JSONrss); try { this.rssAdapter.clear(); this.rssAdapter.notifyDataSetChanged(); this.jsonRssArray = new JSONArray(JSONrss); for (int i = 0; i < jsonRssArray.length(); i++) { JSONObject jsonRssItem = jsonRssArray.getJSONObject(i); this.rssAdapter.add(Html.fromHtml( jsonRssItem.getString("title") + " - <i>" + jsonRssItem.getString("creator") + "</i>")); } if (jsonRssArray.length() > 0 && !this.application.settings.getBoolean("rss_closed", false)) this.rssPanel.setOpen(true, true); } catch (JSONException e) { e.printStackTrace(); } } private void updateTrafficDisplay(long[] trafficData) { MainActivity.this.trafficRow.setVisibility(View.VISIBLE); long uploadTraffic = trafficData[0]; long downloadTraffic = trafficData[1]; long uploadRate = trafficData[2]; long downloadRate = trafficData[3]; // Set rates to 0 if values are negative if (uploadRate < 0) uploadRate = 0; if (downloadRate < 0) downloadRate = 0; MainActivity.this.uploadText.setText(MainActivity.this.formatCount(uploadTraffic, false)); MainActivity.this.downloadText.setText(MainActivity.this.formatCount(downloadTraffic, false)); MainActivity.this.downloadText.invalidate(); MainActivity.this.uploadText.invalidate(); MainActivity.this.uploadRateText.setText(MainActivity.this.formatCount(uploadRate, true)); MainActivity.this.downloadRateText.setText(MainActivity.this.formatCount(downloadRate, true)); MainActivity.this.downloadRateText.invalidate(); MainActivity.this.uploadRateText.invalidate(); } private void toggleStartStop() { if ((TetherService.singleton != null) && ((TetherService.singleton.getState() == TetherService.STATE_RUNNING) || (TetherService.singleton.getState() == TetherService.STATE_FAIL_LOG) || (TetherService.singleton.getState() == TetherService.STATE_STOPPING))) { Log.d(MSG_TAG, "TOGGLE: RUNNING"); this.startTblRow.setVisibility(View.GONE); this.stopTblRow.setVisibility(View.VISIBLE); this.bottomButtonLayout.setVisibility(View.INVISIBLE); // Animation if (this.animation != null) this.stopBtn.startAnimation(this.animation); this.application.showStartNotification(getString(R.string.global_application_tethering_running)); // Check, if the lockbutton should be displayed if (MainActivity.this.application.settings.getBoolean("lockscreenpref", true) == false) { MainActivity.this.lockButtonCheckbox.setVisibility(View.VISIBLE); } } else if ((TetherService.singleton == null) || (TetherService.singleton.getState() == TetherService.STATE_IDLE) || (TetherService.singleton.getState() == TetherService.STATE_STARTING) || (TetherService.singleton.getState() == TetherService.STATE_RESTARTING) || (TetherService.singleton.getState() == TetherService.STATE_FAIL_EXEC_START) || (TetherService.singleton.getState() == TetherService.STATE_FAIL_EXEC_STOP)) { Log.d(MSG_TAG, "TOGGLE: STOPPED"); this.startTblRow.setVisibility(View.VISIBLE); this.stopTblRow.setVisibility(View.GONE); this.trafficRow.setVisibility(View.INVISIBLE); this.bottomButtonLayout.setVisibility(View.VISIBLE); //??? this.application.trafficCounterEnable(false); // Animation if (this.animation != null) this.startBtn.startAnimation(this.animation); // Notification this.application.notificationManager.cancelAll(); // Check, if the lockbutton should be displayed MainActivity.this.lockButtonCheckbox.setVisibility(View.GONE); } else { Log.d(MSG_TAG, "TOGGLE: UNKNOWN"); this.startTblRow.setVisibility(View.VISIBLE); this.stopTblRow.setVisibility(View.VISIBLE); MainActivity.this.application.displayToastMessage(getString(R.string.main_activity_start_unknownstate)); } this.showRadioMode(); System.gc(); } static String formatCount(long count, boolean rate) { // Converts the supplied argument into a string. // 'rate' indicates whether is a total bytes, or bits per sec. // Under 2Mb, returns "xxx.xKb" // Over 2Mb, returns "xxx.xxMb" if (count < 1e6 * 2) return ((float) ((int) (count * 10 / 1024)) / 10 + (rate ? "kbps" : "kB")); return ((float) ((int) (count * 100 / 1024 / 1024)) / 100 + (rate ? "mbps" : "MB")); } static String formatCountForPost(long count) { if (count < 1e6 * 2) return ((float) ((int) (count * 10 / 1024)) / 10 + (" kilobytes")); return ((float) ((int) (count * 100 / 1024 / 1024)) / 100 + (" megabytes")); } private void openNoNetfilterDialog() { LayoutInflater li = LayoutInflater.from(this); View view = li.inflate(R.layout.nonetfilterview, null); new AlertDialog.Builder(MainActivity.this).setTitle(getString(R.string.main_activity_nonetfilter)) .setView(view) .setNegativeButton(getString(R.string.main_activity_exit), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { Log.d(MSG_TAG, "Close pressed"); MainActivity.this.finish(); } }) .setNeutralButton(getString(R.string.main_activity_ignore), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { Log.d(MSG_TAG, "Override pressed"); MainActivity.this.application.displayToastMessage( "Ignoring, note that this application will NOT work correctly."); } }).show(); } private void openNoAccessControlDialog() { LayoutInflater li = LayoutInflater.from(this); View view = li.inflate(R.layout.noaccesscontrolview, null); new AlertDialog.Builder(MainActivity.this).setTitle(getString(R.string.main_activity_noaccesscontrol)) .setView(view) .setNeutralButton(getString(R.string.main_activity_ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { Log.d(MSG_TAG, "OK pressed"); MainActivity.this.application .displayToastMessage(getString(R.string.main_activity_accesscontrol_disabled)); } }).show(); } private void openAboutDialog() { LayoutInflater li = LayoutInflater.from(this); View view = li.inflate(R.layout.aboutview, null); TextView versionName = (TextView) view.findViewById(R.id.versionName); versionName.setText(this.application.getVersionName()); new AlertDialog.Builder(MainActivity.this).setTitle(getString(R.string.main_activity_about)).setView(view) .setNeutralButton(getString(R.string.main_activity_donate), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { Log.d(MSG_TAG, "Donate pressed"); // Disable donate-dialog for later startups MainActivity.this.application.preferenceEditor.putBoolean("donatepref", false); MainActivity.this.application.preferenceEditor.commit(); Uri uri = Uri.parse(getString(R.string.paypalUrl)); startActivity(new Intent(Intent.ACTION_VIEW, uri)); } }) .setNegativeButton(getString(R.string.main_activity_close), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { Log.d(MSG_TAG, "Close pressed"); } }).show(); } private void openDonateDialog() { if (this.application.showDonationDialog()) { // Creating Layout LayoutInflater li = LayoutInflater.from(this); View view = li.inflate(R.layout.donateview, null); new AlertDialog.Builder(MainActivity.this).setTitle(getString(R.string.main_activity_donate)) .setView(view).setNeutralButton(getString(R.string.main_activity_close), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { Log.d(MSG_TAG, "Close pressed"); } }) .setNegativeButton(getString(R.string.main_activity_donate), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { Log.d(MSG_TAG, "Donate pressed"); // Disable donate-dialog for later startups MainActivity.this.application.preferenceEditor.putBoolean("donatepref", false); MainActivity.this.application.preferenceEditor.commit(); Uri uri = Uri.parse(getString(R.string.paypalUrl)); startActivity(new Intent(Intent.ACTION_VIEW, uri)); } }) .show(); } } private void showRadioMode() { boolean usingBluetooth = this.application.settings.getBoolean("bluetoothon", false); if (usingBluetooth) { this.radioModeImage.setImageResource(R.drawable.bluetooth); } else { this.radioModeImage.setImageResource(R.drawable.wifi); } } public void openUpdateDialog(final String downloadFileUrl, final String fileName, final String message, final String updateTitle) { LayoutInflater li = LayoutInflater.from(this); Builder dialog; View view; view = li.inflate(R.layout.updateview, null); TextView messageView = (TextView) view.findViewById(R.id.updateMessage); TextView updateNowText = (TextView) view.findViewById(R.id.updateNowText); if (fileName.length() == 0) // No filename, hide 'download now?' string updateNowText.setVisibility(View.GONE); messageView.setText(message); dialog = new AlertDialog.Builder(MainActivity.this).setTitle(updateTitle).setView(view); if (fileName.length() > 0) { // Display Yes/No for if a filename is available. dialog.setNeutralButton(getString(R.string.main_activity_no), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { Log.d(MSG_TAG, "No pressed"); } }); dialog.setNegativeButton(getString(R.string.main_activity_yes), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { Log.d(MSG_TAG, "Yes pressed"); MainActivity.this.application.downloadUpdate(downloadFileUrl, fileName); } }); } else dialog.setNeutralButton(getString(R.string.main_activity_ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { Log.d(MSG_TAG, "Ok pressed"); } }); dialog.show(); } public Dialog openLaunchedDialog(final boolean noroot) { final long value = noroot ? 1 : 0; EasyTracker.getTracker().trackEvent("ui_action", "create_dialog", "meshclient", value); Dialog dialog = new AlertDialog.Builder(this) .setMessage(noroot ? R.string.dialog_noroot_text : R.string.dialog_launched_text) .setTitle(getString(R.string.dialog_launched_title)).setIcon(R.drawable.og_app_icon) .setCancelable(false).setOnKeyListener(new DialogInterface.OnKeyListener() { public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) MainActivity.this.finish(); if (keyCode < KeyEvent.KEYCODE_DPAD_UP || keyCode > KeyEvent.KEYCODE_DPAD_CENTER) return true; else return false; } }).setPositiveButton(getString(R.string.main_activity_ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { EasyTracker.getTracker().trackEvent("ui_action", "button_press", "meshclient_positive", value); startGooglePlayMeshclient(noroot ? "fail_noroot" : "fail"); } }) .setNegativeButton(getString(R.string.main_activity_cancel), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { EasyTracker.getTracker().trackEvent("ui_action", "button_press", "meshclient_negative", value); } }).create(); dialog.show(); return dialog; } void startGooglePlayMeshclient(String content) { Log.d(MSG_TAG, "startGooglePlayMeshclient()"); Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(TetherApplication.MESHCLIENT_GOOGLE_PLAY_URL + content)); try { startActivity(i); } catch (android.content.ActivityNotFoundException e) { Log.e(MSG_TAG, "", e); MainActivity.this.application.displayToastMessage(e.toString()); } } private void hideCommunityText(boolean hide) { if (hide) { MainActivity.this.communityText .setText(String.format("%" + this.communityText.getText().length() + "s", " ")); } else MainActivity.this.communityText.setText(R.string.community_header); } }