diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 792b2c8..39f66fe 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -39,4 +39,7 @@ <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> + </manifest> diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java index d02e088..c70f172 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/DatabaseFragment.java @@ -24,11 +24,12 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector; * * Fragment for showing list of Available Databases for user */ -public class DatabaseFragment extends Fragment implements AdapterView.OnItemClickListener, AsyncDatabaseConnector.ListReturnListener { +public class DatabaseFragment extends Fragment implements AdapterView.OnItemClickListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.OnPostExecuteListener { private ListView databasesListView; private ListAdapter listAdapter; private RelativeLayout rootView; private ProgressBar progressBar; + private List<String> databases; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ @@ -39,6 +40,7 @@ public class DatabaseFragment extends Fragment implements AdapterView.OnItemClic progressBar = (ProgressBar) rootView.findViewById(R.id.loginProgressBar); Static.asyncDatabaseConnector.setListReturnListener(this); + Static.asyncDatabaseConnector.setOnPostExecuteListener(this); Static.asyncDatabaseConnector.getDatabases(); return rootView; } @@ -60,6 +62,11 @@ public class DatabaseFragment extends Fragment implements AdapterView.OnItemClic @Override public void onListReturn(List<String> databases) { + this.databases = databases; + } + + @Override + public void onPostExecute() { if(databases!= null) { listAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, databases); databasesListView.setAdapter(listAdapter); diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java index 670324e..f46b353 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/EntriesFragment.java @@ -31,7 +31,7 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector; * * Fragment for showing elements */ -public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.MatrixReturnListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.IntegerReturnListener, View.OnClickListener { +public class EntriesFragment extends Fragment implements AsyncDatabaseConnector.MatrixReturnListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.IntegerReturnListener, View.OnClickListener, AsyncDatabaseConnector.OnPostExecuteListener { private static final int HEADER_PADDING_TOP = 15; private static final int HEADER_PADDING_BOTTOM = 15; private static final int HEADER_PADDING_LEFT = 15; @@ -57,7 +57,10 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector. private CustomScrollView fakeScrollView; private View dummyView; + private int onPostExecuteListenerExecuted; + private Menu menu; + private TableRow headerRow; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -70,6 +73,8 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector. Static.asyncDatabaseConnector.setIntegerReturnListener(this); Static.asyncDatabaseConnector.setListReturnListener(this); Static.asyncDatabaseConnector.setMatrixReturnListener(this); + Static.asyncDatabaseConnector.setOnPostExecuteListener(this); + onPostExecuteListenerExecuted = 0; Static.asyncDatabaseConnector.getFields(tableName); Static.asyncDatabaseConnector.getEntriesCount(tableName); @@ -203,9 +208,6 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector. newRow.setClickable(true); newRow.setOnClickListener(this); entriesTable.addView(newRow); - - syncWidths(); - fakeScroll(); } } else { TextView errorMessage = new TextView(getActivity()); @@ -223,7 +225,6 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector. @Override public void onListReturn(List<String> fieldList) { // First we need header - TableRow headerRow; headerRow = new TableRow(getActivity()); headerRow.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)); rowCount = fieldList.size(); @@ -236,7 +237,6 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector. textView.setPadding(HEADER_PADDING_LEFT, HEADER_PADDING_TOP, HEADER_PADDING_RIGHT, HEADER_PADDING_BOTTOM); headerRow.addView(textView); } - headerFrame.addView(headerRow); Static.asyncDatabaseConnector.getRows(tableName, entriesLimit, page); } @@ -246,12 +246,15 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector. pageCount = result/entriesLimit; if( result%entriesLimit > 0) pageCount++; - - setHasOptionsMenu(true); + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + setHasOptionsMenu(true); + } + }); } private void syncWidths(){ // TODO: Merge with adding columns maybe? Loops -= 3 should be quicker - TableRow headerRow = (TableRow) headerFrame.getChildAt(0); int maxWidth[]= new int[headerRow.getChildCount()]; for(int i=0;i<headerRow.getChildCount();i++){ TextView textView = (TextView) headerRow.getChildAt(i); @@ -280,8 +283,8 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector. tmpHeader.setWidth(maxWidth[i]); } - headerFrame.setVisibility(View.VISIBLE); - entriesTable.setVisibility(View.VISIBLE); +// headerFrame.setVisibility(View.VISIBLE); +// entriesTable.setVisibility(View.VISIBLE); } private void fakeScroll(){ @@ -311,4 +314,13 @@ public class EntriesFragment extends Fragment implements AsyncDatabaseConnector. intent.putStringArrayListExtra(ElementFragment.EDIT_LIST, values); startActivity(intent); } + + @Override + public void onPostExecute() { + if(++onPostExecuteListenerExecuted==3){ + headerFrame.addView(headerRow); + syncWidths(); + fakeScroll(); + } + } } diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java index 73e145d..726d080 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/LoginFragment.java @@ -19,7 +19,7 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector; * * Fragment for login */ -public class LoginFragment extends Fragment implements View.OnClickListener, AsyncDatabaseConnector.BooleanReturnListener { +public class LoginFragment extends Fragment implements View.OnClickListener, AsyncDatabaseConnector.BooleanReturnListener, AsyncDatabaseConnector.OnPostExecuteListener { private EditText urlTextbox; private EditText loginTextbox; private EditText passwordTextbox; @@ -86,6 +86,7 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy if(Static.isNetworkConnected(getActivity())) { asyncDatabaseConnector = new AsyncDatabaseConnector(login, password, url); asyncDatabaseConnector.setBooleanReturnListener(this); + asyncDatabaseConnector.setOnPostExecuteListener(this); asyncDatabaseConnector.checkLogin(); } else { Static.showErrorAlert(getResources().getString(R.string.no_connection), getActivity()); @@ -105,9 +106,12 @@ public class LoginFragment extends Fragment implements View.OnClickListener, Asy else { Static.showErrorAlert(AsyncDatabaseConnector.errorMsg, getActivity()); } - loginButton.setEnabled(true); // Now we can click button again - progressBar.setVisibility(View.INVISIBLE); } + @Override + public void onPostExecute() { + loginButton.setEnabled(true); // Now we can click button again + progressBar.setVisibility(View.INVISIBLE); + } } diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java b/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java index 8a63cd4..1007f2c 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/TableFragment.java @@ -22,12 +22,13 @@ import info.nerull7.mysqlbrowser.db.AsyncDatabaseConnector; /** * Created by nerull7 on 14.07.14. */ -public class TableFragment extends Fragment implements AdapterView.OnItemClickListener, AsyncDatabaseConnector.ListReturnListener{ +public class TableFragment extends Fragment implements AdapterView.OnItemClickListener, AsyncDatabaseConnector.ListReturnListener, AsyncDatabaseConnector.OnPostExecuteListener { private String databaseName; private ListView tablesList; private ListAdapter listAdapter; private RelativeLayout rootView; private ProgressBar progressBar; + private List<String> tables; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -38,6 +39,7 @@ public class TableFragment extends Fragment implements AdapterView.OnItemClickLi this.rootView = (RelativeLayout) rootView; progressBar = (ProgressBar) rootView.findViewById(R.id.loginProgressBar); Static.asyncDatabaseConnector.setListReturnListener(this); + Static.asyncDatabaseConnector.setOnPostExecuteListener(this); Static.asyncDatabaseConnector.getTables(); return rootView; } @@ -59,6 +61,11 @@ public class TableFragment extends Fragment implements AdapterView.OnItemClickLi @Override public void onListReturn(List<String> tables) { + this.tables = tables; + } + + @Override + public void onPostExecute() { if(tables != null) { listAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1, tables); tablesList.setAdapter(listAdapter); diff --git a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java index 8aeef5c..0f01403 100644 --- a/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java +++ b/app/src/main/java/info/nerull7/mysqlbrowser/db/AsyncDatabaseConnector.java @@ -45,6 +45,7 @@ public class AsyncDatabaseConnector { private MatrixReturnListener matrixReturnListener; public static String errorMsg; + private OnPostExecuteListener onPostExecuteListener; public AsyncDatabaseConnector(String login, String password, String url){ this.login = login; @@ -99,10 +100,18 @@ public class AsyncDatabaseConnector { try { list = parseListFromJSON(data); } catch (JSONException e) { e.printStackTrace(); } - if(listReturnListener!=null) - listReturnListener.onListReturn(list); + if(listReturnListener!=null) { + final List<String> finalList = list; +// new Thread(new Runnable() { +// @Override +// public void run() { + listReturnListener.onListReturn(finalList); +// +// } +// }).run(); + } } - }); + }, onPostExecuteListener); downloader.execute(urlQuery); } @@ -117,7 +126,7 @@ public class AsyncDatabaseConnector { if(matrixReturnListener!=null) matrixReturnListener.onMatrixReturn(list); } - }); + }, onPostExecuteListener); downloader.execute(urlQuery); } @@ -161,7 +170,7 @@ public class AsyncDatabaseConnector { booleanReturnListener.onBooleanReturn(listenerData); } - }); + }, onPostExecuteListener); downloader.execute(actionUrlBuilder(ACTION_LOGIN)); return false; } @@ -224,7 +233,7 @@ public class AsyncDatabaseConnector { if(integerReturnListener!=null) integerReturnListener.onIntegerReturn(Integer.parseInt(data)); } - }); + }, onPostExecuteListener); downloader.execute(urlQuery); } @@ -278,7 +287,7 @@ public class AsyncDatabaseConnector { stringReturnListener.onStringReturn(data); } } - }); + }, onPostExecuteListener); downloader.execute(request); } @@ -302,6 +311,10 @@ public class AsyncDatabaseConnector { this.matrixReturnListener = matrixReturnListener; } + public void setOnPostExecuteListener(OnPostExecuteListener onPostExecuteListener){ + this.onPostExecuteListener = onPostExecuteListener; + } + public static interface BooleanReturnListener{ public void onBooleanReturn(boolean result); } @@ -322,16 +335,22 @@ public class AsyncDatabaseConnector { public void onMatrixReturn(List<List<String>> data); } + public static interface OnPostExecuteListener { + void onPostExecute(); + } + private static class Downloader extends AsyncTask<String, Void, String> { private OnFinishedListener onFinishedListener; + private OnPostExecuteListener onPostExecuteListener; private String errorString; public static final String CONNECTION_REQUEST_METHOD = "GET"; public static final int CONNECTION_TIMEOUT = 15000; public static final int READ_TIMEOUT = 10000; - Downloader(OnFinishedListener onFinishedListener){ + Downloader(OnFinishedListener onFinishedListener, OnPostExecuteListener onPostExecuteListener){ this.onFinishedListener = onFinishedListener; + this.onPostExecuteListener = onPostExecuteListener; errorString = null; } @@ -385,7 +404,8 @@ public class AsyncDatabaseConnector { @Override protected String doInBackground(String... strings) { try { - return httpRequest(strings[0]); + String data = httpRequest(strings[0]); + onFinishedListener.onFinished(data, errorMsg); // Can't be null cos we demand listener in constructor } catch (IOException e) { e.printStackTrace(); } @@ -394,11 +414,17 @@ public class AsyncDatabaseConnector { @Override protected void onPostExecute(String data) { - onFinishedListener.onFinished(data, errorString); // Can't be null cos we demand listener in constructor + if (onPostExecuteListener!=null) + onPostExecuteListener.onPostExecute(); + } + + public void setOnPostExecuteListener(OnPostExecuteListener onPostExecuteListener) { + this.onPostExecuteListener = onPostExecuteListener; } private static interface OnFinishedListener { void onFinished(String data, String error); } + } }