Commit 49a3e103 authored by Mathias Stanger's avatar Mathias Stanger

Einstellungen in eigenes Fragment ausgelagert. Das wird normalerweise einmal...

Einstellungen in eigenes Fragment ausgelagert. Das wird normalerweise einmal eingestellt und dann nie wieder angefasst.

Der Hostname ist nun konfigurierbar.

Von einer Activity auf mehrere Fragments umgestellt.

Fehlermeldungen werden nun nicht nur ins Log geschrieben sondern auch zurückgegeben.
parent 20bf966b
......@@ -14,7 +14,7 @@
android:supportsRtl="true"
android:name=".BusApplication"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<activity android:name=".FragmentContainerActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
......
package de.matsta.yasc;
import android.app.Fragment;
import android.app.FragmentManager;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AppCompatActivity;
import de.matsta.yasc.fragments.ControlFragment;
public class FragmentContainerActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_container_activity);
// Beim Öffnen wollen bieten wir Interaktionen an.
FragmentManager fragmentManager = getFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(ControlFragment.class.getSimpleName());
if (fragment == null) {
// Wenn unser Fragment noch nicht vorhanden ist, dann erstellen wir es.
fragmentManager.beginTransaction().add(R.id.fragment_container, new ControlFragment(), ControlFragment.class.getSimpleName()).commit();
}
}
@Override
public void onBackPressed() {
// Haben wir einen BackStack-Eintrag (z.B. bei geöffneten Einstellungen), dann navigieren wir zuerst darin zurück.
if (getFragmentManager().getBackStackEntryCount() > 0) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
}
package de.matsta.yasc;
import android.content.Context;
import android.preference.EditTextPreference;
import android.util.AttributeSet;
public class IntegerTextPreference extends EditTextPreference {
public IntegerTextPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public IntegerTextPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public IntegerTextPreference(Context context) {
super(context);
}
@Override
protected String getPersistedString(String defaultReturnValue) {
return String.valueOf(getPersistedInt(-1));
}
@Override
protected boolean persistString(String value) {
return persistInt(Integer.valueOf(value));
}
}
......@@ -30,8 +30,8 @@ public class MainActivity extends ChronosSupportActivity {
EditText mEdtKeyPass;
@Bind(R.id.btnSelectKey)
Button mBtnSelectKey;
@Bind(R.id.btnBuzz)
Button mBtnBuzz;
//@Bind(R.id.btnBuzz)
//Button mBtnBuzz;
@Bind(R.id.btnOpen)
Button mBtnOpen;
@Bind(R.id.btnClose)
......@@ -62,13 +62,13 @@ public class MainActivity extends ChronosSupportActivity {
}
});
mBtnBuzz.setOnClickListener(new View.OnClickListener() {
/*mBtnBuzz.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
save();
executeRemote("buzz");
}
});
});*/
mBtnOpen.setOnClickListener(new View.OnClickListener() {
@Override
......@@ -114,7 +114,7 @@ public class MainActivity extends ChronosSupportActivity {
SharedPrefsTools sharedPrefsTools = new SharedPrefsTools(getApplicationContext());
runOperation(new SshOperation(
// TODO Die Serveradresse sollte konfigurierbar sein.
"sphinx", sharedPrefsTools.getUsername(), sharedPrefsTools.getKey(), sharedPrefsTools.getKeyPwd(), 22, command
sharedPrefsTools.getHost(), sharedPrefsTools.getUsername(), sharedPrefsTools.getKey(), sharedPrefsTools.getKeyPwd(), 22, command
));
}
......@@ -142,7 +142,7 @@ public class MainActivity extends ChronosSupportActivity {
Uri uri = data.getData();
// Wir wollen aber keine Uri sondern den Pfad
try {
String path = getPath(this, uri);
String path = Utils.getPath(this, uri);
if (path == null) {
throw new Exception(getString(R.string.exceptionPathNotParseable));
}
......@@ -156,27 +156,6 @@ public class MainActivity extends ChronosSupportActivity {
super.onActivityResult(requestCode, resultCode, data);
}
public static String getPath(Context context, Uri uri) throws URISyntaxException {
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = {"_data"};
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow("_data");
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
// Eat it
}
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
private void save() {
// Wir speichern die Eingaben in den SharedPreferences
SharedPrefsTools sharedPrefsTools = new SharedPrefsTools(getApplicationContext());
......
......@@ -2,19 +2,21 @@ package de.matsta.yasc;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
public class SharedPrefsTools {
private static final String KEY_KEY = "key";
private static final String KEY_USERNAME = "username";
private static final String KEY_KEYPWD = "keypwd";
public static final String KEY_KEY = "key";
public static final String KEY_USERNAME = "username";
public static final String KEY_KEYPWD = "keypwd";
public static final String KEY_HOST = "host";
public static final String KEY_PORT = "port";
private SharedPreferences.Editor mEditor;
private SharedPreferences mPerf;
public SharedPrefsTools(Context context) {
// Preferences öffnen / anlegen. Durch MODE_PRIVATE können nur Apps mit unserem Benutzer (aktuell nur wir) darauf zugreifen
mPerf = context.getSharedPreferences("SharedPrefs", Context.MODE_PRIVATE);
mPerf = PreferenceManager.getDefaultSharedPreferences(context);
mEditor = mPerf.edit();
}
......@@ -46,4 +48,23 @@ public class SharedPrefsTools {
mEditor.commit();
}
public String getHost() {
return mPerf.getString(KEY_HOST, "");
}
public void setHost(String value) {
mEditor.putString(KEY_HOST, value);
mEditor.commit();
}
public Integer getPort() {
return mPerf.getInt(KEY_PORT, 22);
}
public void setPort(Integer value) {
mEditor.putInt(KEY_PORT, value);
mEditor.commit();
}
}
......@@ -119,6 +119,7 @@ public class SshOperation extends ChronosOperation<String> {
output = executeRemoteCommand();
} catch (Exception e) {
e.printStackTrace();
output = e.getLocalizedMessage();
}
return output;
}
......
package de.matsta.yasc;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import java.net.URISyntaxException;
public class Utils {
public static String getPath(Context context, Uri uri) throws URISyntaxException {
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = {"_data"};
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow("_data");
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
// Eat it
}
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
}
package de.matsta.yasc.fragments;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.redmadrobot.chronos.gui.fragment.ChronosFragment;
import com.redmadrobot.chronos.gui.fragment.ChronosSupportFragment;
import butterknife.Bind;
import butterknife.ButterKnife;
import de.matsta.yasc.R;
import de.matsta.yasc.SharedPrefsTools;
import de.matsta.yasc.SshOperation;
public class ControlFragment extends ChronosFragment {
@Bind(R.id.btnBuzz)
Button mBtnBuzz;
@Bind(R.id.btnUnlock)
Button mBtnUnlock;
@Bind(R.id.btnStatus)
Button mBtnStatus;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.control_fragment, container, false);
ButterKnife.bind(this, view);
setHasOptionsMenu(true);
mBtnBuzz.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
executeRemote("buzz");
}
}
);
mBtnUnlock.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
executeRemote("unlock");
}
});
mBtnStatus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
executeRemote("status");
}
});
return view;
}
private void executeRemote(String command) {
SharedPrefsTools sharedPrefsTools = new SharedPrefsTools(getActivity().getApplicationContext());
runOperation(new SshOperation(
sharedPrefsTools.getHost(), sharedPrefsTools.getUsername(), sharedPrefsTools.getKey(), sharedPrefsTools.getKeyPwd(), sharedPrefsTools.getPort(), command
));
}
@Override
public void onCreateOptionsMenu(
Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.control_fragment_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
public void onOperationFinished(final SshOperation.Result result) {
// Wird das hier eigentlich jemals aufgerufen?
if (result.isSuccessful()) {
Toast.makeText(getActivity(), "onOperationFinished: " + result.getOutput(), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getActivity(), "onOperationFinished: " + result.getErrorMessage(), Toast.LENGTH_LONG).show();
Log.d(this.getClass().getSimpleName(), result.getErrorMessage());
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_config:
// Einstellungen anzeigen
SettingsFragment fragment = new SettingsFragment();
getActivity().getFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment, getString(R.string.config)).addToBackStack(null).commit();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
package de.matsta.yasc.fragments;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.util.Log;
import android.widget.Toast;
import java.net.URISyntaxException;
import de.matsta.yasc.R;
import de.matsta.yasc.SharedPrefsTools;
import de.matsta.yasc.Utils;
public class SettingsFragment extends PreferenceFragment {
private static final int FILE_SELECT_CODE = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
Preference keyPref = (Preference) findPreference(SharedPrefsTools.KEY_KEY);
keyPref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
showFileChooser();
return false;
}
});
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case FILE_SELECT_CODE:
if (resultCode == Activity.RESULT_OK) {
// Wir erhalten eine URI um auf die Datei zuzugreifen
Uri uri = data.getData();
// Wir wollen aber keine Uri sondern den Pfad
try {
String path = Utils.getPath(getActivity(), uri);
if (path == null) {
throw new Exception(getString(R.string.exceptionPathNotParseable));
}
new SharedPrefsTools(getActivity()).setKey(path);
} catch (Exception e) {
Log.e(this.getClass().getSimpleName(), e.getLocalizedMessage());
}
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
private void showFileChooser() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
try {
startActivityForResult(
Intent.createChooser(intent, getString(R.string.selectPrivateKey)),
FILE_SELECT_CODE);
} catch (android.content.ActivityNotFoundException ex) {
Toast.makeText(getActivity(), R.string.installFilebrowser,
Toast.LENGTH_SHORT).show();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Buzz"
android:id="@+id/btnBuzz"
android:layout_gravity="center_horizontal" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Unlock"
android:id="@+id/btnUnlock"
android:layout_gravity="center_horizontal" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Status"
android:id="@+id/btnStatus"
android:layout_gravity="center_horizontal" />
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_config"
android:icon="@drawable/ic_action_config"
android:title="@string/config"
app:showAsAction="ifRoom"/>
</menu>
\ No newline at end of file
<resources>
<string name="app_name">Yet Another Sphinx Client</string>
<string name="app_name">YASC</string>
<string name="app_name_long">Yet Another Sphinx Client</string>
<string name="exceptionPathNotParseable">Dateipfad konnte nicht geparst werden. Vielleicht einen anderen Dateibrowser verwenden.</string>
<string name="selectPrivateKey">Private Key auswählen</string>
<string name="installFilebrowser">Bitte einen Dateibrowser installieren.</string>
<string name="hintUsername">Benutzername</string>
<string name="hintPrivateKeyPassword">Private Key Passwort</string>
<string name="username">Benutzername</string>
<string name="keyfile">Private Key Datei</string>
<string name="keypassword">Private Key Passwort</string>
<string name="port">Port</string>
<string name="host">Host</string>
<string name="authentification">Authentifizierung</string>
<string name="connection">Verbindung</string>
<string name="config">Einstellungen</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/connection">
<EditTextPreference android:key="host" android:title="@string/host"
android:defaultValue="sphinx"/>
<de.matsta.yasc.IntegerTextPreference android:key="port" android:title="@string/port"
android:inputType="number" android:defaultValue="22"/>
</PreferenceCategory>
<PreferenceCategory android:title="@string/authentification">
<EditTextPreference android:key="username" android:title="@string/username"/>
<Preference android:key="key" android:title="@string/keyfile"/>
<EditTextPreference android:key="keypwd" android:title="@string/keypassword"/>
</PreferenceCategory>
</PreferenceScreen>
\ No newline at end of file
......@@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0-rc1'
classpath 'com.android.tools.build:gradle:2.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment