/* * Copyright (C) 2015 - Holy Lobster * * Nuntius 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 2 of the License, or * (at your option) any later version. * * Nuntius is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nuntius. If not, see <http://www.gnu.org/licenses/>. */ package org.holylobster.nuntius.activity; import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; import android.bluetooth.BluetoothAdapter; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Bundle; import android.preference.Preference; import android.preference.PreferenceFragment; import android.preference.PreferenceGroup; import android.preference.PreferenceScreen; import android.support.v7.app.ActionBarActivity; import android.util.Log; import android.widget.Toast; import org.apache.http.conn.util.InetAddressUtils; import com.google.zxing.integration.android.IntentIntegrator; import com.google.zxing.integration.android.IntentResult; import org.holylobster.nuntius.R; import org.holylobster.nuntius.connection.Server; import org.holylobster.nuntius.notifications.IntentRequestCodes; import org.holylobster.nuntius.notifications.NotificationListenerService; import org.holylobster.nuntius.utils.PairingData; import org.holylobster.nuntius.utils.SslUtils; import java.net.InetAddress; import java.net.NetworkInterface; import java.util.Enumeration; public class SettingsActivity extends ActionBarActivity { private static final String TAG = SettingsActivity.class.getSimpleName(); private static Context context; private static PairingData currentPairingData; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_settings); try { SslUtils.generateSelfSignedCertificate(); } catch (Exception e) { Log.e(TAG, "Unable to secure network connection. Certificate creation failed", e) ; Toast.makeText(context, "Unable to secure network connection. Certificate creation failed", Toast.LENGTH_SHORT).show(); throw new RuntimeException(); } android.support.v7.widget.Toolbar toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.settingstoolbar); setSupportActionBar(toolbar); // Display the fragment as the main content. getFragmentManager() .beginTransaction() .replace(R.id.content_frame, new SettingsFragment()) .commit(); } public void onActivityResult(int requestCode, int resultCode, Intent intent) { IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent); if (scanResult != null) { String contents = scanResult.getContents(); if (contents != null) { Log.i(TAG, "" + contents); currentPairingData = new PairingData(contents); } } } public static PairingData getCurrentPairingData() { PairingData p = currentPairingData; currentPairingData = null; return p; } public static class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { private BroadcastReceiver br; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.pref_general); Preference ip = findPreference("ip"); PreferenceScreen screen = getPreferenceScreen(); if (Server.BLUETOOTH_ENABLED) { screen.removePreference(ip); } else { ip.setSummary(getLocalIpAddress()); } Preference myPref = (Preference) findPreference("qrcode"); myPref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { public boolean onPreferenceClick(Preference preference) { IntentIntegrator integrator = new IntentIntegrator(getActivity()); integrator.initiateScan(); return true; } }); } @Override public void onResume() { super.onResume(); getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); IntentFilter filter = new IntentFilter(); filter.addAction(IntentRequestCodes.INTENT_SERVER_STATUS_CHANGE); br = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String status = intent.getStringExtra("status"); Log.d(TAG, "Received server status change: " + status); updatePreference(findPreference("main_enable_switch")); } }; getActivity().registerReceiver(br, filter); for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); ++i) { Preference preference = getPreferenceScreen().getPreference(i); if (preference instanceof PreferenceGroup) { PreferenceGroup preferenceGroup = (PreferenceGroup) preference; for (int j = 0; j < preferenceGroup.getPreferenceCount(); ++j) { updatePreference(preferenceGroup.getPreference(j)); } } else { updatePreference(preference); } } } public String getLocalIpAddress() { try { for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface intf = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress() && InetAddressUtils.isIPv4Address(inetAddress.getHostAddress())) { return inetAddress.getHostAddress(); } } } } catch (Exception ex) { Log.e("IP Address", ex.toString()); } return null; } private void updatePreference(Preference preference) { if (preference.getKey().equals("main_enable_switch")) { if (preference.getSharedPreferences().getBoolean("main_enable_switch", true)) { updateSummary(preference); } } else if (preference.getKey().equals("version")) { PackageInfo packageInfo = getPackageInfo(); preference.setSummary(String.format("v%s (%d)", packageInfo.versionName, packageInfo.versionCode)); } } public PackageInfo getPackageInfo() { try { return getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0); } catch (PackageManager.NameNotFoundException e) { // "My first four books, from 'Fight Club' to 'Choke,' dealt with personal identity issues. // The crises the narrators found themselves in were generated by themselves." // Chuck Palahniuk throw new RuntimeException(e); } } private void updateSummary(Preference preference) { String summary; if (NotificationListenerService.server != null) { String message = NotificationListenerService.server.getStatusMessage(); switch (message){ case "connection": int connections = NotificationListenerService.server.getNumberOfConnections(); summary = getResources().getQuantityString(R.plurals.running_with_x_connections, connections, connections); break; case "notification": summary = getString(R.string.notification_not_enabled); break; case "bluetooth": summary = getString(R.string.bluetooth_not_enabled); break; case "pair": summary = getString(R.string.not_paired); break; case "relaunch": summary = getString(R.string.relaunch_server); break; default: summary = "..."; break; } } else if (!NotificationListenerService.isNotificationAccessEnabled()) { summary = getString(R.string.notification_not_enabled); } else { summary = "Something went wrong..."; } preference.setSummary(summary); } @Override public void onPause() { super.onPause(); getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); getActivity().unregisterReceiver(br); } public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { Preference preference = findPreference(key); updatePreference(preference); if (preference.getKey().equals("main_enable_switch")) { if (preference.getSharedPreferences().getBoolean("main_enable_switch", true)) { if (Server.BLUETOOTH_ENABLED) { if (!Server.bluetoothAvailable()) { Toast.makeText(getActivity(), getString(R.string.bluetooth_not_available), Toast.LENGTH_LONG).show(); } else if (!Server.bluetoothEnabled()) { if (!requestEnableBluetooth()) { Toast.makeText(getActivity(), getString(R.string.bluetooth_not_enabled), Toast.LENGTH_LONG).show(); return; } } } if (!NotificationListenerService.isNotificationAccessEnabled()) { new AskNotificationAccessDialogFragment().show(getFragmentManager(), "NoticeDialogFragment"); } updatePreference(preference); } } } public boolean requestEnableBluetooth() { Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableIntent, IntentRequestCodes.BT_REQUEST_ENABLE); return true; } } protected boolean isValidFragment(String fragmentName) { return SettingsFragment.class.getName().equals(fragmentName); } public static class AskNotificationAccessDialogFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setMessage(R.string.dialog_ask_notification_access) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { Toast.makeText(getActivity(), getString(R.string.enable_notification_toast_hint), Toast.LENGTH_LONG).show(); getActivity().startActivity((new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"))); } }) .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // User cancelled the dialog } }); // Create the AlertDialog object and return it return builder.create(); } } }