Java tutorial
/** * ManageRepos, part of Aptoide * * from v3.0 Copyright (C) 2012 Duarte Silveira * duarte.silveira@caixamagica.pt * * derivative work of ManageRepo from Aptoide's earlier versions with * Copyright (C) 2009 Roberto Jacinto * roberto.jacinto@caixamagica.pt * * 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 2 * of the License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package pt.aptoide.backupapps; import java.io.IOException; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Vector; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.ProtocolException; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.RedirectHandler; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; import pt.aptoide.backupapps.R; import pt.aptoide.backupapps.data.AptoideServiceData; import pt.aptoide.backupapps.data.display.ViewDisplayListRepos; import pt.aptoide.backupapps.data.display.ViewDisplayRepo; import pt.aptoide.backupapps.data.model.ViewLogin; import pt.aptoide.backupapps.data.model.ViewRepository; import pt.aptoide.backupapps.data.util.Constants; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.ListActivity; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.ServiceConnection; import android.content.res.Configuration; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.RemoteException; import android.util.Log; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.SimpleAdapter.ViewBinder; import android.widget.TextView; import android.widget.Toast; import pt.aptoide.backupapps.AIDLReposInfo; import pt.aptoide.backupapps.data.AIDLAptoideServiceData; /** * ManageRepos, interface class to manage and display the details * of managed repositories * * @author dsilveira * @since 3.0 * */ public class ManageRepos extends ListActivity { ContextThemeWrapper theme = new ContextThemeWrapper(this, R.style.DialogTheme); View loading; View empty; private ViewDisplayListRepos repos = null; private ViewDisplayListRepos freshRepos = null; private HashMap<Integer, ViewDisplayRepo> reposInserting; private SimpleAdapter reposListAdapter; private ReposManager reposManager; private boolean handlingMyappRepos = false; private AIDLAptoideServiceData serviceDataCaller = null; private boolean serviceDataIsBound = false; private ServiceConnection serviceDataConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { // This is called when the connection with the service has been // established, giving us the object we can use to // interact with the service. We are communicating with the // service using AIDL, so here we set the remote service interface. serviceDataCaller = AIDLAptoideServiceData.Stub.asInterface(service); serviceDataIsBound = true; Log.v("Aptoide-AppInfo", "Connected to ServiceData"); try { serviceDataCaller.callRegisterReposObserver(serviceDataCallback); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } handleIncomingIntent(getIntent()); reposManager.getRepos(); } public void onServiceDisconnected(ComponentName className) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. serviceDataCaller = null; serviceDataIsBound = false; Log.v("Aptoide-AppInfo", "Disconnected from ServiceData"); } }; private AIDLReposInfo.Stub serviceDataCallback = new AIDLReposInfo.Stub() { @Override public void updateReposBasicInfo() throws RemoteException { reposManager.getRepos(); } @Override public void insertedRepo(int repoHashid) throws RemoteException { reposInserting.remove(repoHashid); reposManager.getRepos(); } }; private Handler interfaceTasksHandler = new Handler() { @Override public void handleMessage(Message msg) { EnumReposInfoTasks task = EnumReposInfoTasks.reverseOrdinal(msg.what); switch (task) { case NO_MANAGED_REPOS: askAddDefaultRepo(); break; case UPDATE_REPOS_INFO: setReposList(); break; default: break; } } }; private class ReposManager { private ExecutorService reposThreadPool; public ReposManager() { reposThreadPool = Executors.newSingleThreadExecutor(); } public void getRepos() { try { reposThreadPool.execute(new GetRepos()); } catch (Exception e) { } } public void addRepo(ViewRepository repo) { reposThreadPool.execute(new AddRepo(repo)); } public void removeRepo(int repoHashid) { reposThreadPool.execute(new RemoveRepo(repoHashid)); } public void setInUseRepo(int repoHashid) { reposThreadPool.execute(new SetInUseRepo(repoHashid)); } public void unsetInUseRepo(int repoHashid) { reposThreadPool.execute(new UnsetInUseRepo(repoHashid)); } public void removeLogin(int repoHashid) { reposThreadPool.execute(new RemoveLogin(repoHashid)); } public void updateLogin(ViewRepository repo) { reposThreadPool.execute(new UpdateLogin(repo)); } private class GetRepos implements Runnable { @Override public void run() { try { freshRepos = serviceDataCaller.callGetRepos(); Log.d("Aptoide-ManageRepo", "Repos: " + freshRepos); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } interfaceTasksHandler.sendEmptyMessage(EnumReposInfoTasks.UPDATE_REPOS_INFO.ordinal()); } } private class AddRepo implements Runnable { ViewRepository repo; public AddRepo(ViewRepository repo) { this.repo = repo; } @Override public void run() { try { serviceDataCaller.callLoadingRepos(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { serviceDataCaller.callAddRepo(repo); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private class RemoveRepo implements Runnable { int repoHashid; public RemoveRepo(int repoHashid) { this.repoHashid = repoHashid; } @Override public void run() { boolean noUsableRepos = true; for (Map<String, Object> repo : repos.getList()) { if ((Boolean) repo.get(Constants.KEY_REPO_IN_USE)) { noUsableRepos = false; } } if (noUsableRepos) { try { serviceDataCaller.callNoRepos(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { try { serviceDataCaller.callLoadingRepos(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } try { serviceDataCaller.callRemoveRepo(repoHashid); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private class SetInUseRepo implements Runnable { int repoHashid; public SetInUseRepo(int repoHashid) { this.repoHashid = repoHashid; } @Override public void run() { try { serviceDataCaller.callLoadingRepos(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { serviceDataCaller.callSetInUseRepo(repoHashid); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private class UnsetInUseRepo implements Runnable { int repoHashid; public UnsetInUseRepo(int repoHashid) { this.repoHashid = repoHashid; } @Override public void run() { boolean noUsableRepos = true; for (Map<String, Object> repo : repos.getList()) { if ((Boolean) repo.get(Constants.KEY_REPO_IN_USE)) { noUsableRepos = false; } } if (noUsableRepos) { try { serviceDataCaller.callNoRepos(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { try { serviceDataCaller.callLoadingRepos(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } try { serviceDataCaller.callUnsetInUseRepo(repoHashid); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private class RemoveLogin implements Runnable { int repoHashid; public RemoveLogin(int repoHashid) { this.repoHashid = repoHashid; } @Override public void run() { try { serviceDataCaller.callRemoveLogin(repoHashid); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private class UpdateLogin implements Runnable { ViewRepository repo; public UpdateLogin(ViewRepository repo) { this.repo = repo; } @Override public void run() { try { serviceDataCaller.callUpdateLogin(repo); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } private void setReposList() { loading.setVisibility(View.GONE); repos = freshRepos; if ((repos == null || repos.getList().size() == 0) && !handlingMyappRepos) { empty.setVisibility(View.VISIBLE); interfaceTasksHandler.sendEmptyMessage(EnumReposInfoTasks.NO_MANAGED_REPOS.ordinal()); } else { initReposList(); } } private void toggleDisplayRepoInUse(int repoHashid) { boolean repoInUse = true; for (Map<String, Object> repo : repos.getList()) { if (repoHashid == (Integer) repo.get(Constants.KEY_REPO_HASHID)) { repoInUse = !(Boolean) repo.get(Constants.KEY_REPO_IN_USE); repo.put(Constants.KEY_REPO_IN_USE, repoInUse); break; } } if (repos.getHashMap().get(repoHashid).getInUse() != repoInUse) { if (repoInUse) { reposManager.setInUseRepo(repoHashid); } else { reposManager.unsetInUseRepo(repoHashid); } } } private void removeDisplayRepo(int repoHashid) { for (Map<String, Object> repo : repos.getList()) { if (repoHashid == (Integer) repo.get(Constants.KEY_REPO_HASHID)) { repos.getList().remove(repo); break; } } reposManager.removeRepo(repoHashid); } private void addDisplayRepo(ViewRepository repo) { reposManager.addRepo(repo); ViewDisplayRepo newDisplayRepo = new ViewDisplayRepo(repo.getHashid(), repo.getUri(), true, 0); reposInserting.put(newDisplayRepo.getRepoHashid(), newDisplayRepo); repos.getList().add(newDisplayRepo.getDiplayMap()); } private void askAddDefaultRepo() { final String uri = Constants.APPS_REPO; AlertDialog.Builder defaultDialog = new AlertDialog.Builder(theme); defaultDialog.setTitle(getString(R.string.attention)); defaultDialog.setIcon(R.drawable.ic_menu_info_details); defaultDialog.setMessage(getString(R.string.add_default_repo_confirm) + uri); defaultDialog.setPositiveButton(getText(R.string.yes), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { addDisplayRepo(new ViewRepository(uri)); initReposList(); return; } }); defaultDialog.setNegativeButton(getText(R.string.no), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { initReposList(); return; } }); defaultDialog.show(); } private String updt_repo; private AlertDialog alert; private AlertDialog alert2; private AlertDialog alert3; private Context ctx; private AlertDialog alrt = null; private enum returnStatus { OK, LOGIN_REQUIRED, BAD_LOGIN, FAIL, EXCEPTION }; private enum popupOptions { EDIT_REPO, REMOVE_REPO }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.list_repos); View searchView = findViewById(R.id.search_button); searchView.setVisibility(View.GONE); loading = findViewById(R.id.loading); empty = findViewById(android.R.id.empty); empty.setVisibility(View.INVISIBLE); this.ctx = this; this.reposInserting = new HashMap<Integer, ViewDisplayRepo>(); this.reposManager = new ReposManager(); if (!serviceDataIsBound) { bindService(new Intent(this, AptoideServiceData.class), serviceDataConnection, Context.BIND_AUTO_CREATE); } registerForContextMenu(this.getListView()); } @Override protected void onNewIntent(Intent intent) { handleIncomingIntent(intent); super.onNewIntent(intent); } private void handleIncomingIntent(Intent incomingIntent) { if (incomingIntent.getExtras() != null && incomingIntent.getExtras().getBoolean(Constants.MYAPP_NEW_REPOS_WAITING)) { Log.d("Aptoide-ManageRepos", "incoming Myapp Repos"); handlingMyappRepos = true; receiveMyappRepos(); } } private void receiveMyappRepos() { try { final ViewDisplayListRepos myappRepos = serviceDataCaller.callGetWaitingMyappRepos(); //TODO checkServerConnection final CharSequence[] reposArray = new CharSequence[myappRepos.getList().size()]; for (int i = 0; i < myappRepos.getList().size(); i++) { reposArray[i] = (String) myappRepos.getList().get(i).get(Constants.KEY_REPO_URI); } final ArrayList<String> addList = new ArrayList<String>(); AlertDialog.Builder builder = new AlertDialog.Builder(theme); builder.setTitle(getString(R.string.add_repo_choose)); builder.setIcon(R.drawable.ic_menu_add); builder.setMultiChoiceItems(reposArray, null, new DialogInterface.OnMultiChoiceClickListener() { public void onClick(DialogInterface dialog, int whichButton, boolean isChecked) { if (isChecked) { addList.add(reposArray[whichButton].toString()); } else { addList.remove(reposArray[whichButton].toString()); } } }); builder.setPositiveButton(getString(R.string.add), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { for (String repoUri : addList) { addDisplayRepo(new ViewRepository(repoUri)); } alert.dismiss(); handlingMyappRepos = false; refreshReposList(); } }); builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { alert.dismiss(); handlingMyappRepos = false; finish(); } }); alert = builder.create(); alert.show(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private boolean isRepoManaged(String uri) { if (repos.getHashMap().containsKey(uri.hashCode())) { Log.d("Aptoide-ManageRepo", "Repo already exists"); return true; } else { String existingUri; for (ViewDisplayRepo existingRepo : repos.getHashMap().values()) { existingUri = existingRepo.getUri(); if (uri.length() == (existingUri.length() - 1)) { if (uri.equals(existingUri.substring(0, existingUri.length() - 1))) { Log.d("Aptoide-ManageRepo", "Repo equal to existant one but without final forward slash"); return true; } } else if (uri.length() == (existingUri.length() - 8)) { if (uri.equals(existingUri.substring(7, existingUri.length() - 1))) { Log.d("Aptoide-ManageRepo", "Repo equal to existant one but without initial http:// and the final forward slash"); return true; } } else { uri = uri + Constants.DOMAIN_APTOIDE_STORE; if (uri.equals(existingUri.substring(7, existingUri.length()))) { Log.d("Aptoide-ManageRepo", "Repo equal to existant one but without initial http:// and without " + Constants.DOMAIN_APTOIDE_STORE + " extension"); return true; } if (uri.equals(existingUri.substring(7, existingUri.length() - 1))) { Log.d("Aptoide-ManageRepo", "Repo equal to existant one but without initial http:// , without " + Constants.DOMAIN_APTOIDE_STORE + ", and the final forward slash"); return true; } } } } Log.d("Aptoide-ManageRepo", "Repo is new"); return false; } private String uriCheck(String uri_str) { if (uri_str.length() != 0 && uri_str.charAt(uri_str.length() - 1) != '/') { uri_str = uri_str + '/'; Log.d("Aptoide-ManageRepo", "repo uri: " + uri_str); } if (!uri_str.startsWith("http://")) { uri_str = "http://" + uri_str; Log.d("Aptoide-ManageRepo", "repo uri: " + uri_str); } return uri_str; } private returnStatus checkServerConnection(String uri, String user, String pwd) { Log.d("Aptoide-ManageRepo", "checking connection for: " + uri + " with credentials: " + user + " " + pwd); int result; HttpParams httpParameters = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(httpParameters, 10000); HttpConnectionParams.setSoTimeout(httpParameters, 10000); DefaultHttpClient mHttpClient = new DefaultHttpClient(httpParameters); // DefaultHttpClient mHttpClient = Threading.getThreadSafeHttpClient(); mHttpClient.setRedirectHandler(new RedirectHandler() { public boolean isRedirectRequested(HttpResponse response, HttpContext context) { return false; } public URI getLocationURI(HttpResponse response, HttpContext context) throws ProtocolException { return null; } }); HttpGet mHttpGet = new HttpGet(uri + "/info.xml"); // SharedPreferences sPref = this.getSharedPreferences("aptoide_prefs", Context.MODE_PRIVATE); // String myid = sPref.getString("myId", "NoInfo"); // String myscr = sPref.getInt("scW", 0)+"x"+sPref.getInt("scH", 0); // mHttpGet.setHeader("User-Agent", "aptoide-" + this.getString(R.string.ver_str)+";"+ Configs.TERMINAL_INFO+";"+myscr+";id:"+myid+";"+sPref.getString(Configs.LOGIN_USER_NAME, "")); try { if (user != null && pwd != null) { URL mUrl = new URL(uri); mHttpClient.getCredentialsProvider().setCredentials(new AuthScope(mUrl.getHost(), mUrl.getPort()), new UsernamePasswordCredentials(user, pwd)); } HttpResponse mHttpResponse = mHttpClient.execute(mHttpGet); Header[] azz = mHttpResponse.getHeaders("Location"); if (azz.length > 0) { String newurl = azz[0].getValue(); mHttpGet = null; mHttpGet = new HttpGet(newurl); if (user != null && pwd != null) { URL mUrl = new URL(newurl); mHttpClient.getCredentialsProvider().setCredentials( new AuthScope(mUrl.getHost(), mUrl.getPort()), new UsernamePasswordCredentials(user, pwd)); } mHttpResponse = null; mHttpResponse = mHttpClient.execute(mHttpGet); } result = mHttpResponse.getStatusLine().getStatusCode(); if (result == 200) { return returnStatus.OK; } else if (result == 401) { return returnStatus.BAD_LOGIN; } else { return returnStatus.FAIL; } } catch (ClientProtocolException e) { return returnStatus.EXCEPTION; } catch (IOException e) { return returnStatus.EXCEPTION; } catch (IllegalArgumentException e) { return returnStatus.EXCEPTION; } catch (Exception e) { return returnStatus.EXCEPTION; } } private void validateRepo(final String originalUriString, final boolean editMode) { final ViewDisplayRepo originalRepo; LayoutInflater li = LayoutInflater.from(ctx); View view = li.inflate(R.layout.addrepo, null); final TextView sec_msg = (TextView) view.findViewById(R.id.sec_msg); final TextView sec_msg2 = (TextView) view.findViewById(R.id.sec_msg2); final EditText sec_user = (EditText) view.findViewById(R.id.sec_user); final EditText sec_pwd = (EditText) view.findViewById(R.id.sec_pwd); final EditText uri = (EditText) view.findViewById(R.id.edit_uri); final CheckBox sec = (CheckBox) view.findViewById(R.id.secure_chk); sec.setOnCheckedChangeListener(new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { sec_user.setEnabled(true); sec_pwd.setEnabled(true); } else { sec_user.setEnabled(false); sec_pwd.setEnabled(false); } } }); Builder p = new AlertDialog.Builder(theme).setView(view); alrt = p.create(); CharSequence actionButtonString; if (editMode) { originalRepo = repos.getRepo(originalUriString.hashCode()); if (originalRepo.requiresLogin()) { sec.setChecked(true); sec_user.setText(originalRepo.getLogin().getUsername()); sec_pwd.setText(originalRepo.getLogin().getPassword()); } else { sec.setChecked(false); } alrt.setIcon(R.drawable.ic_menu_edit); alrt.setTitle(getText(R.string.edit_repo)); actionButtonString = getText(R.string.edit); } else { originalRepo = null; sec.setChecked(false); alrt.setIcon(R.drawable.ic_menu_add); alrt.setTitle(getText(R.string.add_repo)); actionButtonString = getText(R.string.add); } alrt.setButton(actionButtonString, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { String uriString = uri.getText().toString(); String user = null; String pwd = null; if (sec.isChecked()) { user = sec_user.getText().toString(); pwd = sec_pwd.getText().toString(); } Message msg = new Message(); uriString = uriCheck(uriString); sec_msg.setVisibility(View.GONE); sec_msg2.setVisibility(View.GONE); returnStatus result = checkServerConnection(uriString, user, pwd); switch (result) { case OK: Log.d("Aptoide-ManageRepo", "return ok"); msg.obj = 0; if (isRepoManaged(uriString) && ((originalRepo != null && originalRepo.requiresLogin()) ? (originalRepo.getLogin().getUsername().equals(user) && originalRepo.getLogin().getPassword().equals(pwd)) : true)) { Toast.makeText(ctx, "Repo " + uriString + " already exists.", 5000).show(); // finish(); } else { ViewRepository newRepo = new ViewRepository(uriString); if (isRepoManaged(uriString)) { if (user != null && pwd != null) { reposManager.removeLogin(newRepo.getHashid()); } else { newRepo.setLogin(new ViewLogin(user, pwd)); reposManager.updateLogin(newRepo); } } else { if (user != null && pwd != null) { newRepo.setLogin(new ViewLogin(user, pwd)); } if (originalUriString != null) { removeDisplayRepo(originalUriString.hashCode()); } addDisplayRepo(newRepo); refreshReposList(); } alrt.dismiss(); } break; case LOGIN_REQUIRED: Log.d("Aptoide-ManageRepo", "return login_required"); sec_msg2.setText(getText(R.string.login_required)); sec_msg2.setVisibility(View.VISIBLE); msg.obj = 1; break; case BAD_LOGIN: Log.d("Aptoide-ManageRepo", "return bad_login"); sec_msg2.setText(getText(R.string.check_login)); sec_msg2.setVisibility(View.VISIBLE); msg.obj = 1; break; case FAIL: Log.d("Aptoide-ManageRepo", "return fail"); uriString = uriString.substring(0, uriString.length() - 1) + Constants.DOMAIN_APTOIDE_STORE; Log.d("Aptoide-ManageRepo", "repo uri: " + uriString); msg.obj = 1; break; default: Log.d("Aptoide-ManageRepo", "return exception"); uriString = uriString.substring(0, uriString.length() - 1) + Constants.DOMAIN_APTOIDE_STORE; Log.d("Aptoide-ManageRepo", "repo uri: " + uriString); msg.obj = 1; break; } if (result.equals(returnStatus.FAIL) || result.equals(returnStatus.EXCEPTION)) { returnStatus result2 = checkServerConnection(uriString, user, pwd); switch (result2) { case OK: Log.d("Aptoide-ManageRepo", "return ok"); msg.obj = 0; if (isRepoManaged(uriString) && ((originalRepo != null && originalRepo.requiresLogin()) ? (originalRepo.getLogin().getUsername().equals(user) && originalRepo.getLogin().getPassword().equals(pwd)) : true)) { Toast.makeText(ctx, "Repo " + uriString + " already exists.", 5000).show(); // finish(); } else { ViewRepository newRepo = new ViewRepository(uriString); if (isRepoManaged(uriString)) { if (user != null && pwd != null) { reposManager.removeLogin(newRepo.getHashid()); } else { newRepo.setLogin(new ViewLogin(user, pwd)); reposManager.updateLogin(newRepo); } } else { if (user != null && pwd != null) { newRepo.setLogin(new ViewLogin(user, pwd)); } if (originalUriString != null) { removeDisplayRepo(originalUriString.hashCode()); } addDisplayRepo(newRepo); refreshReposList(); } alrt.dismiss(); } break; case LOGIN_REQUIRED: Log.d("Aptoide-ManageRepo", "return login_required"); sec_msg2.setText(getText(R.string.login_required)); sec_msg2.setVisibility(View.VISIBLE); msg.obj = 1; break; case BAD_LOGIN: Log.d("Aptoide-ManageRepo", "return bad_login"); sec_msg2.setText(getText(R.string.check_login)); sec_msg2.setVisibility(View.VISIBLE); msg.obj = 1; break; case FAIL: Log.d("Aptoide-ManageRepo", "return fail"); sec_msg.setText(getText(R.string.cant_connect)); sec_msg.setVisibility(View.VISIBLE); msg.obj = 1; break; default: Log.d("Aptoide-ManageRepo", "return exception"); msg.obj = 1; break; } } invalidRepo.sendMessage(msg); } }); alrt.setButton2(getText(R.string.cancel), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { alrt.dismiss(); } }); alrt.show(); if (originalUriString != null) { uri.setText(originalUriString); } } private Handler invalidRepo = new Handler() { @Override public void handleMessage(Message msg) { if ((Integer) msg.obj == 1) alrt.show(); } }; @Override protected void onResume() { super.onResume(); // refreshReposList(); } private void initReposList() { reposListAdapter = new SimpleAdapter(this, repos.getList(), R.layout.row_repo, new String[] { Constants.KEY_REPO_HASHID, Constants.KEY_REPO_URI, Constants.KEY_REPO_IN_USE, Constants.KEY_REPO_SIZE }, new int[] { R.id.repo_hashid, R.id.uri, R.id.in_use, R.id.size }); reposListAdapter.setViewBinder(new ReposListBinder()); setListAdapter(reposListAdapter); } private void refreshReposList() { reposListAdapter.notifyDataSetChanged(); } class ReposListBinder implements ViewBinder //TODO may need some improvements { public boolean setViewValue(View view, Object data, String textRepresentation) { if (view.getClass().toString().equalsIgnoreCase("class android.widget.TextView")) { TextView tmpr = (TextView) view; tmpr.setText(textRepresentation); } else if (view.getClass().toString().equalsIgnoreCase("class android.widget.ImageView")) { ImageView tmpr = (ImageView) view; boolean inUse = Boolean.parseBoolean(textRepresentation); if (inUse) { tmpr.setImageResource(R.drawable.btn_check_on); } else { tmpr.setImageResource(R.drawable.btn_check_off); } } else if (view.getClass().toString().equalsIgnoreCase("class android.widget.LinearLayout")) { LinearLayout tmpr = (LinearLayout) view; tmpr.setTag(textRepresentation); } else { return false; } return true; } } @Override protected void onListItemClick(ListView list, View view, int position, long id) { super.onListItemClick(list, view, position, id); final int repoHashid = Integer.parseInt(view.getTag().toString()); Log.d("Aptoide-ManageRepo", "Onclick position: " + position + " repoHashid: " + repoHashid); if (!reposInserting.containsKey(repoHashid)) { toggleDisplayRepoInUse(repoHashid); refreshReposList(); } } public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); menu.add(Menu.NONE, EnumOptionsMenu.ADD_REPO.ordinal(), 1, R.string.add_repo) .setIcon(R.drawable.ic_menu_add); menu.add(Menu.NONE, EnumOptionsMenu.EDIT_REPO.ordinal(), 2, R.string.edit_repo) .setIcon(R.drawable.ic_menu_edit); menu.add(Menu.NONE, EnumOptionsMenu.REMOVE_REPO.ordinal(), 3, R.string.remove_repo) .setIcon(R.drawable.ic_menu_close_clear_cancel); return true; } @Override public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) { Log.d("Aptoide-ManageRepos", "oncreateContext view: " + view.toString()); final int repoHashid = Integer.parseInt(view.findViewById(R.id.repo_hashid).getTag().toString()); if (!reposInserting.containsKey(repoHashid)) { super.onCreateContextMenu(menu, view, menuInfo); menu.setHeaderTitle(getString(R.string.options)); menu.add(0, popupOptions.EDIT_REPO.ordinal(), 0, getString(R.string.edit)); menu.add(0, popupOptions.REMOVE_REPO.ordinal(), 0, getString(R.string.remove)); } } @Override public boolean onContextItemSelected(MenuItem item) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); TextView selectedView = (TextView) ((View) (info.targetView)).findViewById(R.id.uri); final String repo_selected = selectedView.getText().toString(); popupOptions popupOption = popupOptions.values()[item.getItemId()]; switch (popupOption) { case EDIT_REPO: validateRepo(repo_selected, true); refreshReposList(); break; case REMOVE_REPO: AlertDialog.Builder builder = new AlertDialog.Builder(theme); builder.setTitle(getString(R.string.remove_repo)); builder.setIcon(R.drawable.ic_menu_close_clear_cancel); builder.setMessage(getString(R.string.remove_repo_confirm) + " " + repo_selected + " ?"); builder.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { removeDisplayRepo(repo_selected.hashCode()); alert3.dismiss(); refreshReposList(); } }); builder.setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { alert3.dismiss(); return; } }); alert3 = builder.create(); alert3.show(); break; default: break; } return super.onContextItemSelected(item); } @Override public boolean onMenuItemSelected(int featureId, MenuItem item) { EnumOptionsMenu option = EnumOptionsMenu.reverseOrdinal(item.getItemId()); CharSequence[] reposArray = new CharSequence[repos.getList().size() - reposInserting.size()]; int j = 0; for (int i = 0; i < repos.getList().size(); i++) { if (!reposInserting.containsKey(repos.getList().get(i).get(Constants.KEY_REPO_HASHID))) { reposArray[j] = (String) repos.getList().get(i).get(Constants.KEY_REPO_URI); j++; } } switch (option) { case ADD_REPO: validateRepo(null, false); break; case REMOVE_REPO: if (reposArray.length == 0) { return true; } final Vector<Integer> remList = new Vector<Integer>(); AlertDialog.Builder builder = new AlertDialog.Builder(theme); builder.setTitle(getString(R.string.remove_repo_choose)); builder.setIcon(R.drawable.ic_menu_close_clear_cancel); builder.setMultiChoiceItems(reposArray, null, new DialogInterface.OnMultiChoiceClickListener() { public void onClick(DialogInterface dialog, int whichButton, boolean isChecked) { if (isChecked) { remList.addElement( (Integer) (repos.getList().get(whichButton).get(Constants.KEY_REPO_HASHID))); } else { remList.removeElement( (Integer) (repos.getList().get(whichButton).get(Constants.KEY_REPO_HASHID))); } } }); builder.setPositiveButton(getString(R.string.remove), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { for (Integer repoHashid : remList) { removeDisplayRepo(repoHashid); } alert.dismiss(); refreshReposList(); } }); builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { alert.dismiss(); return; } }); alert = builder.create(); alert.show(); break; case EDIT_REPO: if (reposArray.length == 0) { return true; } AlertDialog.Builder builder2 = new AlertDialog.Builder(theme); builder2.setTitle(getString(R.string.edit_repo_choose)); builder2.setIcon(R.drawable.ic_menu_edit); builder2.setSingleChoiceItems(reposArray, -1, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { updt_repo = (String) (repos.getList().get(whichButton).get(Constants.KEY_REPO_URI)); } }); builder2.setPositiveButton(getString(R.string.edit), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { alert2.dismiss(); validateRepo(updt_repo, true); return; } }); builder2.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { alert2.dismiss(); return; } }); alert2 = builder2.create(); alert2.show(); break; } return super.onMenuItemSelected(featureId, item); } @Override public void finish() { if (serviceDataIsBound) { unbindService(serviceDataConnection); } super.finish(); } @Override protected void onDestroy() { reposManager.reposThreadPool.shutdownNow(); super.onDestroy(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); } }