Java tutorial
/* * Adamas -- An application to securely and anonymously tunnel IP * networks over other Internet protocols. It consists of Adamas * Client, Adamas Connector and Adamas Server. * * Copyright (C) 2016 <adamasvpn@gmail.com> * * This file is part of Adamas Client or Connector, or both. * * Adamas Client and Adamas Connector are free software: you can * redistribute them and/or modify them 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. * * Adamas Client and Adamas Connector are distributed in the hope * that they 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 Adamas Client and Adamas Connector. If not, see * <http://www.gnu.org/licenses/>. */ package com.adamas.client.android.ui; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.PorterDuff; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.ContextMenu; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.adamas.client.Protocol; import com.adamas.client.R; import com.adamas.client.android.EditConnectorActivity; import com.adamas.client.android.MainActivity; import com.adamas.client.android.util.Store; import com.adamas.client.android.util.ToastType; import com.adamas.client.android.util.Util; import com.adamas.connector.Connector; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; import java.util.Locale; /** * A simple {@link Fragment} subclass. * Activities that contain this fragment must implement the * {@link ConnectorsFragment.OnFragmentInteractionListener} interface * to handle interaction events. * Use the {@link ConnectorsFragment#newInstance} factory method to * create an instance of this fragment. */ public class ConnectorsFragment extends Fragment { private final static String INDEX = "INDEX"; private int _index = -1; /////////////////////////////////// private ListView vpnListview; private VpnAdapter vpnAdapter = null; private static final int ADD_EDIT_CONNECTOR = 1000; // static keeps all the elements in the list even device orientation changes and this instance is reinitialized private static final List<Connector> _vpnList = new LinkedList<Connector>(); /////////////////////////////////// private OnFragmentInteractionListener mListener; public ConnectorsFragment() { // Required empty public constructor } /** * Use this factory method to create a new instance of * this fragment using the provided parameters. * * @return A new instance of fragment HomeFragment. */ // TODO: Rename and change types and number of parameters public static ConnectorsFragment newInstance(int index) { ConnectorsFragment fragment = new ConnectorsFragment(); Bundle bundle = new Bundle(); bundle.putInt(INDEX, index); fragment.setArguments(bundle); fragment.setArguments(bundle); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { _index = getArguments().getInt(INDEX); } } public void changeHomeImage(View rootview) { if (true) { return; } //the layout is not attached to root activity yet, so the following call does not work // ((MainActivity)getActivity()).changeHomeImage(true); FrameLayout frameLayout = (FrameLayout) rootview.findViewById(R.id.layouthelpinghand); if (frameLayout != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (((MainActivity) getActivity()).isConnected()) { // frameLayout.setBackground(getResources().getDrawable(R.drawable.helpinghand, getTheme())); frameLayout.getBackground().setTint(getResources().getColor(R.color.material_yellow_300)); frameLayout.getBackground().setTintMode(PorterDuff.Mode.SCREEN); } else { // frameLayout.setBackground(getResources().getDrawable(R.drawable.helpinghand, getTheme())); frameLayout.getBackground().setTintMode(PorterDuff.Mode.SCREEN); frameLayout.getBackground().setTint(getResources().getColor(R.color.material_grey_300)); } } else { if (((MainActivity) getActivity()).isConnected()) { // frameLayout.setBackgroundDrawable(getResources().getDrawable(R.drawable.helpinghand)); } else { // frameLayout.setBackgroundDrawable(getResources().getDrawable(R.drawable.helpinghand)); } } } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View rootview = inflater.inflate(R.layout.fragment_connectors, container, false); { vpnListview = (ListView) rootview.findViewById(R.id.vpnlist); vpnAdapter = new VpnAdapter(); // Assign adapter to ListView vpnListview.setAdapter(vpnAdapter); vpnListview.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) { Connector currentVpn = vpnAdapter.getBaseVpn(position); if (currentVpn.isSelected()) { currentVpn.setSelected(false); updateConnectorInStore(currentVpn); } else { for (Connector baseVpn : _vpnList) { if (baseVpn.isSelected()) { baseVpn.setSelected(false); updateConnectorInStore(baseVpn); } } currentVpn.setSelected(true); updateConnectorInStore(currentVpn); } vpnAdapter.notifyDataSetChanged(); if (currentVpn.isSelected()) { if (currentVpn instanceof Connector) { ((MainActivity) getActivity()).setSelectedAdamasConnector(currentVpn); } } else { ((MainActivity) getActivity()).setSelectedAdamasConnector(null); } } }); this.registerForContextMenu(vpnListview); if (_vpnList.isEmpty()) { processRefreshKey(); } //TODO // { // connectDisconnectImage = (ImageView) findViewById(R.id.button_connect_disconnect); // connectDisconnectImage.setOnClickListener(new View.OnClickListener() { // @Override // public void onClick(View v) { // processConnectDisconnectKey(); // } // }); // } } changeHomeImage(rootview); return rootview; } // TODO: Rename method, update argument and hook method into UI event public void onButtonPressed(Uri uri) { if (mListener != null) { mListener.onFragmentInteraction(uri); } } @Override public void onAttach(Context context) { super.onAttach(context); if (context instanceof OnFragmentInteractionListener) { mListener = (OnFragmentInteractionListener) context; } else { throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener"); } } @Override public void onDetach() { super.onDetach(); mListener = null; } /** * This interface must be implemented by activities that contain this * fragment to allow an interaction in this fragment to be communicated * to the activity and potentially other fragments contained in that * activity. * <p/> * See the Android Training lesson <a href= * "http://developer.android.com/training/basics/fragments/communicating.html" * >Communicating with Other Fragments</a> for more information. */ public interface OnFragmentInteractionListener { // TODO: Update argument type and name void onFragmentInteraction(Uri uri); } @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if (isVisibleToUser) { ((MainActivity) getActivity()).setCurrentActiveFragment(_index); } } class VpnAdapter extends BaseAdapter { @Override public int getCount() { return _vpnList.size(); } @Override public Object getItem(int arg0) { return _vpnList.get(arg0); } @Override public long getItemId(int arg0) { return arg0; } @Override public View getView(int arg0, View view, ViewGroup arg2) { if (view == null) { LayoutInflater inflater = (LayoutInflater) getActivity() .getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.listview_item_connector_instance, arg2, false); } final Connector baseVpn = _vpnList.get(arg0); Connector adamasConnector = (Connector) baseVpn; TextView ipportprotocol = (TextView) view.findViewById(R.id.ipportprotocol); if (Protocol.tcp.equals(adamasConnector.getProtocol()) || Protocol.udp.equals(adamasConnector.getProtocol())) { String ip = adamasConnector.getProtocol().name().toUpperCase() + " " + adamasConnector.getGeoInfo().getIp() + ":" + adamasConnector.getPort(); ipportprotocol.setText(ip); } TextView country = (TextView) view.findViewById(R.id.country); if (adamasConnector.getGeoInfo() != null && adamasConnector.getGeoInfo().getCountryCode() != null) { Locale loc = new Locale("", adamasConnector.getGeoInfo().getCountryCode()); country.setText(loc.getDisplayCountry()); } else { country.setText(getResources().getString(R.string.unknown_country)); } ImageView countryimg = (ImageView) view.findViewById(R.id.countryimage); ImageView showconnectedimage = (ImageView) view.findViewById(R.id.showconnectedimage); Util.setImage(countryimg, adamasConnector.getGeoInfo().getCountryCode()); if (adamasConnector.isSelected()) { if (((MainActivity) getActivity()).getSelectedAdamasConnector() == null) { ((MainActivity) getActivity()).setSelectedAdamasConnector(adamasConnector); } if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { view.setBackgroundColor(getResources().getColor(R.color.material_green_700)); countryimg.setBackgroundColor(getResources().getColor(R.color.material_green_700)); } else { view.setBackgroundColor( getResources().getColor(R.color.material_green_700, getActivity().getTheme())); countryimg.setBackgroundColor( getResources().getColor(R.color.material_green_700, getActivity().getTheme())); } } else { if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { view.setBackgroundColor(getResources().getColor(R.color.transpatent)); countryimg.setBackgroundColor(getResources().getColor(R.color.transpatent)); } else { view.setBackgroundColor(getResources().getColor(R.color.transpatent, getActivity().getTheme())); countryimg.setBackgroundColor( getResources().getColor(R.color.transpatent, getActivity().getTheme())); } } //TODO if (((MainActivity) getActivity()).isConnected() && ((MainActivity) getActivity()).getConnectedAdamasConnector() != null) { Connector connected = ((MainActivity) getActivity()).getConnectedAdamasConnector(); if (adamasConnector.getIdOnClient() == connected.getIdOnClient()) { showconnectedimage.setVisibility(View.VISIBLE); } else { showconnectedimage.setVisibility(View.INVISIBLE); } } else { showconnectedimage.setVisibility(View.INVISIBLE); } return view; } public Connector getBaseVpn(int position) { return _vpnList.get(position); } } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); MenuInflater inflater = getActivity().getMenuInflater(); inflater.inflate(R.menu.menu_connector, menu); } @Override public boolean onContextItemSelected(MenuItem item) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); switch (item.getItemId()) { case R.id.edit_ac: editAdamasConnector(info.position); return true; case R.id.delete_ac: deleteAdamasConnector(info.position); return true; default: return super.onContextItemSelected(item); } } private void editAdamasConnector(int position) { Connector ac = this._vpnList.get(position); Intent intent = new Intent(getActivity(), EditConnectorActivity.class); Bundle mBundle = new Bundle(); mBundle.putSerializable(EditConnectorActivity.ADAMAS_CONNECTOR, ac); intent.putExtras(mBundle); startActivityForResult(intent, MainActivity.MANUALLY_EDIT_CONNECTOR_REQUEST_CODE); } private void deleteAdamasConnector(int position) { Connector ac = this._vpnList.get(position); deleteConnector(ac); toast(getResources().getString(R.string.toast_delete_connector_succeeded), ToastType.info); } private void toast(String msg, ToastType toastType) { LayoutInflater inflater = getActivity().getLayoutInflater(); // Inflate the Layout View layout = inflater.inflate(R.layout.custom_toast, (ViewGroup) getActivity().findViewById(R.id.custom_toast_layout)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (toastType.equals(ToastType.error)) { layout.setBackground(getActivity().getDrawable(R.drawable.toast_error)); } else if (toastType.equals(ToastType.info)) { layout.setBackground(getActivity().getDrawable(R.drawable.toast_info)); } else if (toastType.equals(ToastType.warning)) { layout.setBackground(getActivity().getDrawable(R.drawable.toast_warning)); } else { layout.setBackground(getActivity().getDrawable(R.drawable.toast_info)); } } TextView text = (TextView) layout.findViewById(R.id.textToShow); // Set the Text to show in TextView text.setText(msg); Toast toast = new Toast(getActivity().getApplicationContext()); toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0); toast.setDuration(Toast.LENGTH_SHORT); toast.setView(layout); toast.show(); } public void processRefreshKey() { RefreshTask refreshTask = new RefreshTask(); try { refreshTask.execute(new URL("http://www.nowhere.com/")); } catch (MalformedURLException e) { e.printStackTrace(); } } private List<Connector> getVpnsFromStore() { SharedPreferences sharedPref = getActivity().getSharedPreferences(Store.STORE_ADAMAS_CONNECTORS, Context.MODE_PRIVATE); return Store.getConnectorsFromStore(sharedPref); } private class RefreshTask extends AsyncTask<URL, Integer, Long> { RefreshTask() { _vpnList.clear(); ((MainActivity) getActivity()).setSelectedAdamasConnector(null); vpnAdapter.notifyDataSetChanged(); //TODO } protected Long doInBackground(URL... urls) { publishProgress(1); _vpnList.addAll(getVpns(urls[0])); _vpnList.addAll(getVpnsFromStore()); if (_vpnList.isEmpty()) { } return 100L; } private List<Connector> getVpns(URL url) { List<Connector> vpns = new ArrayList<Connector>(); return vpns; } protected void onProgressUpdate(Integer... progress) { } protected void onPostExecute(Long result) { sortByIdOnClient(_vpnList); //TODO vpnAdapter.notifyDataSetChanged(); } } private void sortByCountry(List<Connector> vpns) { Collections.sort(vpns, new Comparator<Connector>() { @Override public int compare(Connector adamasConnector, Connector t1) { if (adamasConnector.getGeoInfo().getCountryCode() == null) { return -1; } if (t1.getGeoInfo().getCountryCode() == null) { return 1; } return adamasConnector.getGeoInfo().getCountryCode().compareTo(t1.getGeoInfo().getCountryCode()); } }); vpnAdapter.notifyDataSetChanged(); } private void sortByIdOnClient(List<Connector> vpns) { Collections.sort(vpns, new Comparator<Connector>() { @Override public int compare(Connector adamasConnector, Connector t1) { return adamasConnector.getIdOnClient() - t1.getIdOnClient(); } }); vpnAdapter.notifyDataSetChanged(); } public boolean deleteConnector(Connector ac) { SharedPreferences sharedPref = getActivity().getSharedPreferences(Store.STORE_ADAMAS_CONNECTORS, Context.MODE_PRIVATE); Store.deleteConnector(sharedPref, ac.getIdOnClient()); ((MainActivity) getActivity()).setSelectedAdamasConnector(null); processRefreshKey(); return true; } private void updateConnectorInStore(Connector ac) { SharedPreferences sharedPref = getActivity().getSharedPreferences(Store.STORE_ADAMAS_CONNECTORS, Context.MODE_PRIVATE); Store.updateConnector(sharedPref, ac); } public int getConnectorCount() { return _vpnList.size(); } public void vpnAdaptorNotifyDataSetChanged() { if (vpnAdapter != null) { vpnAdapter.notifyDataSetChanged(); } } }