package ve.gob.cenditel.tibisaymovil; import java.io.File; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import ve.gob.cenditel.tibisaymovil.R; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.content.DialogInterface.OnCancelListener; import android.content.DialogInterface.OnDismissListener; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.View.OnClickListener; import android.view.Window; import android.webkit.MimeTypeMap; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener; import android.widget.Toast; public class FilesToPDFSignActivity extends KeyChainClientActivity implements OnItemClickListener, OnClickListener { private File cwd; private List selected; private FileBrowserView viewHolder; private FileListAdapter listAdapter; private int requestCode; private int resultCode; private Intent data; private String privateKeyAlias; private String filterMImeType = "application/pdf"; @Override protected void onCreate(Bundle savedInstanceState) { //Estilando la barra de titulo final boolean customTitleSupported = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE); super.onCreate(savedInstanceState); this.viewHolder = new FileBrowserView(); if (savedInstanceState != null) { this.selected = TypeUtils.convertToFileList(savedInstanceState.getStringArrayList("selected")); if (this.selected.size() > 0) { FilesToPDFSignActivity.this.updateButton (FilesToPDFSignActivity.this.viewHolder.accept,true); } this.cwd = new File(savedInstanceState.getString("cwd")); this.viewHolder.fileList.setAdapter(this.listAdapter = new FileListAdapter(this.cwd.getAbsolutePath(), filterMImeType)); } else { this.selected = new ArrayList(); this.viewHolder.fileList.setAdapter(this.listAdapter = new FileListAdapter()); } boolean enabled = false; if (!this.selected.isEmpty()) enabled = this.viewHolder.accept.isEnabled(); FilesToPDFSignActivity.this.updateButton(FilesToPDFSignActivity.this.viewHolder.accept,enabled); FilesToPDFSignActivity.this.updateButton (FilesToPDFSignActivity.this.viewHolder.accept,enabled); //Estilando Barra de titulo if(customTitleSupported) getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_bar); //Obtiene o crea un instancia de en keyChain y le asigna la actividad que lo genera KeyChainStrategy.getInstance().setClientActivity(this); } /** * Provides the data to be shown in the file browser ListView. * * @author José M. Prieto (jmprieto@emergya.com) */ private class FileListAdapter extends BaseAdapter { private final ArrayList directories; private final ArrayList files; private FileListAdapter() { this("/",filterMImeType); } private FileListAdapter(String location) { this(location, ""); } private FileListAdapter(String location, String filterMimeType) { directories = new ArrayList(); files = new ArrayList(); //Obtiene etiqueta que se colocará antes del path que visualizará el usuario String toPathText = FilesToPDFSignActivity.this.getString(R.string.pathstring)+": "; //Coloca el texto de la etiqueta en la vista FilesToPDFSignActivity.this.viewHolder.pathString.setText(toPathText); //Coloca el texto con el path actual FilesToPDFSignActivity.this.viewHolder.path.setText(location); //Crea un objeto file cwd con la ubicacion dada en location FilesToPDFSignActivity.this.cwd = new File(location); //Obtiene el directorio padre del objeto file cwd File parent = FilesToPDFSignActivity.this.cwd.getParentFile(); //Si tiene un padre, lo agrega en la posición cero de la lista de directorios if (parent != null) { directories.add(0, parent); } //Crea un arreglo con las lista de archivos contenidos en el directorio cwd File[] ls = FilesToPDFSignActivity.this.cwd.listFiles(); if (ls != null) { for (File f : ls) { //recorre todos los archivos contenidos en el directorio if (FsUtils.isHiddenOrNotReadable(f)) { // Si son ocultos no hace nada continue; } // Si son directorios los agrega a la lista de directorios a partir de la posición 1 // En la posición 0 se encuentra el directorio padre if (f.isDirectory()) { directories.add(f); } else // De lo contrario lo agrega a la lista de archivos { //Valida tipo de archivo a mostrar Uri selectedUri = Uri.fromFile(f); String fileExtension = MimeTypeMap.getFileExtensionFromUrl(selectedUri.toString()); String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension); // Toast.makeText(FileToSignHandwrittenSignatureActivity.this, // "FileExtension: " + fileExtension + "\n" + // "MimeType: " + mimeType, // Toast.LENGTH_LONG).show(); //Filtra por mimeType if(filterMimeType.isEmpty() || filterMimeType == mimeType) files.add(f); } } } Collections.sort(directories); // Ordena los directorios alfabeticamente Collections.sort(files); // Ordena los archivos alfabeticamente } /** * Retorna cantidad total de elementos que se listarán en el directorio. */ @Override public int getCount() { return directories.size() + files.size(); } /** * Dada una posición en el listado del directorio, retorna un archivo o directorio * según corresponda. */ @Override public File getItem(int position) { if (position < directories.size()) { return directories.get(position); } else { return files.get(position - directories.size()); } } /** * Retorna un código hash para el archivo, permite comparar si dos archivos son los mismos */ @Override public long getItemId(int position) { return getItem(position).hashCode(); } /** * Crea la visualización de cada item del fileBrowser */ @Override public View getView(int position, View convertView, ViewGroup parent) { //Crea la vista de cada fila del filebrowser a partir del layout if (convertView == null) { LayoutInflater inflater = LayoutInflater.from(FilesToPDFSignActivity.this); convertView = inflater.inflate(R.layout.files_to_pdf_sign_item, parent, false); } // Se enlaza a cada componente del layout ImageView image = (ImageView) convertView.findViewById(R.id.type_image); TextView fileName = (TextView) convertView.findViewById(R.id.filename_text); TextView modified = (TextView) convertView.findViewById(R.id.filename_modified); // Se obtiene el archivo ubicado en position File file = getItem(position); //RadioButton CheckBox check = (CheckBox) convertView.findViewById(R.id.file_check); check.setFocusable(false); // Se asignan los iconos según el tipo de archivo y se oculta el radio en los directorios if (file.isDirectory()) { image.setImageResource(R.drawable.ic_carpeta); check.setVisibility(View.INVISIBLE); check.setChecked(false); } else { image.setImageResource(R.drawable.ic_archivo); check.setVisibility(View.VISIBLE); if (!FilesToPDFSignActivity.this.selected.contains(file)){ check.setChecked(false); } else{ check.setChecked(true); } } // Si es el directorio que hace referencia al padre le coloca como nombre ".." if (file.isDirectory() && position == 0 && ! "/".equals(FilesToPDFSignActivity.this.cwd.getAbsolutePath())) { fileName.setText(".."); } else { fileName.setText(file.getName()); } //Datos de modificación del archivo SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); Date date = new Date(file.lastModified()); String dateString = FilesToPDFSignActivity.this.getString(R.string.modified)+": "; if (file.lastModified()>0) modified.setText(dateString+sdf.format(date)); else modified.setText(dateString+"-"); return convertView; } /** * Controla la selección de cada item del fileBrowser */ public void select(ListView parent, int position) { File item = getItem(position); //Si es un directorio el seleccionado se hace un llamado del fileBrowser del directorio if (item.isDirectory()) { parent.setAdapter(FilesToPDFSignActivity.this.listAdapter = new FileListAdapter(item.getAbsolutePath())); } else { // Si es un archivo //Se agrega el archivo a la lista de seleccionados si no se encuentra en la misma if (!FilesToPDFSignActivity.this.selected.contains(item)){ FilesToPDFSignActivity.this.selected.add(item); FilesToPDFSignActivity.this.updateButton(FilesToPDFSignActivity.this.viewHolder.accept,true); } else{ // De lo contrario se elimina de la lista de seleccionados FilesToPDFSignActivity.this.selected.remove(item); if (FilesToPDFSignActivity.this.selected.isEmpty()){ FilesToPDFSignActivity.this.updateButton(FilesToPDFSignActivity.this.viewHolder.accept,false); }else { FilesToPDFSignActivity.this.updateButton(FilesToPDFSignActivity.this.viewHolder.accept,true); } } notifyDataSetChanged(); } } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelable("intent", this.getIntent()); outState.putString("cwd", this.cwd.getAbsolutePath()); outState.putStringArrayList("selected", TypeUtils.convertToStringArrayList(this.selected)); outState.putParcelable("intent", this.data); outState.putInt("requestCode", this.requestCode); outState.putInt("resultCode", this.resultCode); } private void updateButton(View v, boolean bool) { try{ v.setEnabled(bool); if (v instanceof TextView){ Drawable icon = ((TextView)v).getCompoundDrawables()[1]; if (icon!=null) if (bool) icon.setAlpha(255); else icon.setAlpha(127); } if (v instanceof ImageView){ ImageView result = (ImageView) v; if (bool) result.setAlpha(255); else result.setAlpha(127); } }catch(NullPointerException e){} } private void updateButton(LinearLayout layout, boolean bool) { try{ layout.setEnabled(bool); for (int i=0; i parent, View view, int position, long id) { if (parent.getId() == R.id.file_list) { // user selects a file this.listAdapter.select((ListView) parent, position); } else { // user de-selects a file //this.listAdapter.addIfSameDirectory(selectedAdapter.doUnselect((ListView) parent, position)); } //this.viewHolder.numSelected.setText(Integer.toString(this.selected.size())); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.button_clear_zone: this.selected.clear(); this.listAdapter.notifyDataSetChanged(); //this.viewHolder.numSelected.setText(""+this.selected.size()); this.updateButton(this.viewHolder.accept, false); break; case R.id.button_accept_zone: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH || this.getFileStreamPath(DirectKeyChain.keyStoreFilename).exists()){ Intent intent = new Intent(this, FilesToPDFSignConfirmationActivity.class); intent.putStringArrayListExtra(IntentExtraField.FILES, TypeUtils.convertToStringArrayList(this.selected)); startActivityForResult(intent, ActivityResult.FILES_CONFIRMATED); }else{ this.createNoKeyStoreDialog(); } break; } } private void createNoKeyStoreDialog() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setCancelable(false); builder.setMessage(R.string.error_keystore_file); builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.dismiss(); } }); AlertDialog dialog = builder.create(); dialog.show(); } @Override protected void onActivityResult(int requestCode, int resultCode, final Intent data) { Toast.makeText(this, "result", Toast.LENGTH_LONG).show(); this.requestCode = requestCode; this.resultCode = resultCode; this.data=data; Toast.makeText(this, "request_code="+this.requestCode+" result="+this.resultCode, Toast.LENGTH_LONG).show(); if (resultCode == RESULT_CANCELED && requestCode!=ActivityResult.FILES_CONFIRMATED && requestCode!=ActivityResult.IMPORT_CERTIFICATE) { //Removed to fix task error #73085 /*setResult(RESULT_CANCELED); finish(); return; */ if (this.selected.size()>0){ Intent intent = new Intent(this, FilesToPKCS7SignConfirmationActivity.class); intent.putStringArrayListExtra(IntentExtraField.FILES, TypeUtils.convertToStringArrayList(this.selected)); startActivityForResult(intent, ActivityResult.FILES_CONFIRMATED); } } switch (requestCode) { case ActivityResult.CHECK_CERTIFICATE_VALIDITY: if (resultCode == RESULT_OK) { Toast.makeText(FilesToPDFSignActivity.this, "aqui", Toast.LENGTH_LONG).show(); boolean embedSignature = data.getBooleanExtra(IntentExtraField.EMBED_SIGNATURE_IN_PDF, false); Intent intent = new Intent(this, SignActivity.class); intent.putExtra(IntentExtraField.EMBED_SIGNATURE_IN_PDF, embedSignature); intent.putExtra(IntentExtraField.ALIAS, this.privateKeyAlias); intent.putParcelableArrayListExtra(IntentExtraField.FILES, TypeUtils.convertToUriArrayList(this.selected)); startActivity(intent); //Finish only in this branch to fix error #73085 finish(); } break; case ActivityResult.FILES_CONFIRMATED: if (resultCode == RESULT_OK){ this.selected.clear(); List paths = data.getStringArrayListExtra(IntentExtraField.FILES); for (String s: paths) this.selected.add(new File(s)); this.listAdapter.notifyDataSetChanged(); KeyChainStrategy.getInstance().choosePrivateKeyAlias(); } break; } // if (requestCode == ActivityResult.IMPORT_CERTIFICATE && resultCode == Activity.RESULT_OK) { // //this.launchPasswordDialog(data); // } } private void launchPasswordDialog(final Intent data) { //TODO: Setting boolean to false instead of true. Disables "New KeyStore" option. final PasswordDialog dialog = new PasswordDialog(this, R.string.certificate_password, false); dialog.setAcceptListener(new OnClickListener() { @Override public void onClick(View v) { try { DirectKeyChain direct = DirectKeyChain.getInstance(); int imported = direct.importCertificate(data.getData(), dialog.getPassword()); String text = FilesToPDFSignActivity.this.getResources().getQuantityString(R.plurals.number_imported_certificates, imported, imported); Toast.makeText(FilesToPDFSignActivity.this, text, Toast.LENGTH_LONG).show(); direct.saveKeystore(); direct.refreshAdapter(); } catch (IncorrectPasswordException e) { Toast toast = Toast.makeText(FilesToPDFSignActivity.this, R.string.incorrect_password, Toast.LENGTH_LONG); toast.show(); } catch (Exception e) { Toast toast = Toast.makeText(FilesToPDFSignActivity.this, R.string.error_reading_p12, Toast.LENGTH_LONG); toast.show(); } dialog.dismiss(); FilesToPDFSignActivity.this.requestCode=Integer.MIN_VALUE; FilesToPDFSignActivity.this.resultCode=Integer.MIN_VALUE; FilesToPDFSignActivity.this.data=null; } }); //TODO: dialog.setOnDismissListener(new OnDismissListener(){ @Override public void onDismiss(DialogInterface arg0) { FilesToPDFSignActivity.this.data=null; FilesToPDFSignActivity.this.requestCode=Integer.MIN_VALUE; FilesToPDFSignActivity.this.resultCode=Integer.MIN_VALUE; }}); dialog.setOnCancelListener(new OnCancelListener(){ @Override public void onCancel(DialogInterface dialog) { FilesToPDFSignActivity.this.data=null; FilesToPDFSignActivity.this.requestCode=Integer.MIN_VALUE; FilesToPDFSignActivity.this.resultCode=Integer.MIN_VALUE; }}); dialog.show(); } @Override public void setAlias(String alias) { if (alias == null) { Toast.makeText(CustomKeyChain.activity, "alias null", Toast.LENGTH_LONG).show(); finish(); return; } // Toast.makeText(this, "setAlias="+alias, Toast.LENGTH_LONG).show(); this.privateKeyAlias = alias; Intent intent = new Intent(this, CertValidatorActivity.class); intent.putExtra(IntentExtraField.ALIAS, alias); intent.putExtra(IntentExtraField.EMBED_SIGNATURE_IN_PDF, true); intent.putParcelableArrayListExtra(IntentExtraField.FILES, TypeUtils.convertToUriArrayList(this.selected)); startActivityForResult(intent, ActivityResult.CHECK_CERTIFICATE_VALIDITY); } }