source: dispositivos_moviles/TibisayMovil/src/ve/gob/cenditel/tibisaymovil/FilesToPDFSignActivity.java

Last change on this file was 58c7f6a, checked in by Antonio Araujo Brett <aaraujo@…>, 10 years ago

Modificaciones en archivos fuentes para la versión 1.1 que mejora el aspecto gráfico de la aplicación.

  • Property mode set to 100644
File size: 22.4 KB
Line 
1/*
2Tibisay Movil
3
4Copyright (C) 2013 Antonio Araujo (aaraujo@cenditel.gob.ve), Jose Ruiz
5(jruiz@cenditel.gob.ve), Fundacion Centro Nacional de Desarrollo e
6Investigacion en Tecnologias Libres - CENDITEL.
7
8La Fundación CENDITEL concede permiso para usar, copiar, distribuir y/o
9modificar este programa, reconociendo el derecho que la humanidad posee al
10libre acceso al conocimiento, bajo los términos de la licencia de software
11GPL versión 2.0 de la Free Software Foundation.
12
13Este programa se distribuye con la esperanza de que sea util, pero SIN
14NINGUNA GARANTIA; tampoco las implicitas garantias de MERCANTILIDAD o
15ADECUACION A UN PROPOSITO PARTICULAR.
16
17Para mayor información sobre los términos de la licencia ver el archivo
18llamado "gpl-2.0.txt" en ingles.
19*/
20
21package ve.gob.cenditel.tibisaymovil;
22
23import java.io.File;
24import java.text.SimpleDateFormat;
25import java.util.ArrayList;
26import java.util.Collections;
27import java.util.Date;
28import java.util.List;
29
30
31import ve.gob.cenditel.tibisaymovil.R;
32import android.app.Activity;
33import android.app.AlertDialog;
34import android.content.DialogInterface;
35import android.content.Intent;
36import android.content.DialogInterface.OnCancelListener;
37import android.content.DialogInterface.OnDismissListener;
38import android.graphics.drawable.Drawable;
39import android.net.Uri;
40import android.os.Build;
41import android.os.Bundle;
42import android.view.LayoutInflater;
43import android.view.View;
44import android.view.ViewGroup;
45import android.view.View.OnClickListener;
46import android.view.Window;
47import android.webkit.MimeTypeMap;
48import android.widget.AdapterView;
49import android.widget.BaseAdapter;
50import android.widget.CheckBox;
51import android.widget.ImageView;
52import android.widget.LinearLayout;
53import android.widget.ListView;
54import android.widget.TextView;
55import android.widget.AdapterView.OnItemClickListener;
56import android.widget.Toast;
57
58public class FilesToPDFSignActivity extends KeyChainClientActivity implements OnItemClickListener, OnClickListener {
59
60        private File cwd;
61    private List<File> selected;
62    private FileBrowserView viewHolder;
63    private FileListAdapter listAdapter;
64        private int requestCode;
65        private int resultCode;
66        private Intent data;
67        private String privateKeyAlias;
68    private String filterMImeType = "application/pdf";
69
70        @Override
71        protected void onCreate(Bundle savedInstanceState) {
72                //Estilando la barra de titulo
73                final boolean customTitleSupported = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
74
75                super.onCreate(savedInstanceState);
76               
77                this.viewHolder = new FileBrowserView();       
78
79        if (savedInstanceState != null) {
80               
81                this.selected = TypeUtils.convertToFileList(savedInstanceState.getStringArrayList("selected"));
82            if (this.selected.size() > 0) {             
83                FilesToPDFSignActivity.this.updateButton
84                (FilesToPDFSignActivity.this.viewHolder.accept,true);
85            }
86           
87            this.cwd = new File(savedInstanceState.getString("cwd"));
88            this.viewHolder.fileList.setAdapter(this.listAdapter = new FileListAdapter(this.cwd.getAbsolutePath(), filterMImeType));
89           
90        } else {
91            this.selected = new ArrayList<File>();
92            this.viewHolder.fileList.setAdapter(this.listAdapter = new FileListAdapter());
93        }
94       
95       
96        boolean enabled = false;
97        if (!this.selected.isEmpty())
98                enabled = this.viewHolder.accept.isEnabled();
99       
100                FilesToPDFSignActivity.this.updateButton(FilesToPDFSignActivity.this.viewHolder.accept,enabled);
101       
102        FilesToPDFSignActivity.this.updateButton
103        (FilesToPDFSignActivity.this.viewHolder.accept,enabled);
104       
105        //Estilando Barra de titulo
106                if(customTitleSupported)
107                        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_bar);
108                //Obtiene o crea un instancia de en keyChain y le asigna la actividad que lo genera
109               
110        KeyChainStrategy.getInstance().setClientActivity(this);
111        }
112
113       
114    /**
115     * Provides the data to be shown in the file browser ListView.
116     *
117     * @author José M. Prieto (jmprieto@emergya.com)
118     */
119    private class FileListAdapter extends BaseAdapter {
120
121        private final ArrayList<File> directories;
122        private final ArrayList<File> files;
123
124        private FileListAdapter() {
125            this("/",filterMImeType);
126        }
127
128        private FileListAdapter(String location) {
129            this(location, "");
130        }
131       
132        private FileListAdapter(String location, String filterMimeType) {
133               
134            directories = new ArrayList<File>();
135            files = new ArrayList<File>();
136           
137            //Obtiene etiqueta que se colocará antes del path que visualizará el usuario
138                String toPathText = FilesToPDFSignActivity.this.getString(R.string.pathstring)+":   ";
139                //Coloca el texto de la etiqueta en la vista
140                FilesToPDFSignActivity.this.viewHolder.pathString.setText(toPathText);
141                //Coloca el texto con el path actual
142                FilesToPDFSignActivity.this.viewHolder.path.setText(location);
143                //Crea un objeto file cwd con la ubicacion dada en location
144            FilesToPDFSignActivity.this.cwd = new File(location);
145            //Obtiene el directorio padre del objeto file cwd
146            File parent = FilesToPDFSignActivity.this.cwd.getParentFile();
147            //Si tiene un padre, lo agrega en la posición cero de la lista de directorios 
148           
149            if (parent != null) {
150                directories.add(0, parent);
151            }
152           
153            //Crea un arreglo con las lista de archivos contenidos en el directorio cwd
154            File[] ls = FilesToPDFSignActivity.this.cwd.listFiles();
155            if (ls != null) {
156                for (File f : ls) { //recorre todos los archivos contenidos en el directorio
157                       
158                    if (FsUtils.isHiddenOrNotReadable(f)) { // Si son ocultos no hace nada
159                        continue;
160                    }
161                  // Si son directorios los agrega a la lista de directorios a partir de la posición 1
162                  // En la posición 0 se encuentra el directorio padre 
163                    if (f.isDirectory()) {
164                        directories.add(f);
165                    } else // De lo contrario lo agrega a la lista de archivos
166                        {
167                        //Valida tipo de archivo a mostrar
168                        Uri selectedUri = Uri.fromFile(f);
169                        String fileExtension = MimeTypeMap.getFileExtensionFromUrl(selectedUri.toString());
170                        String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
171                         
172//                        Toast.makeText(FileToSignHandwrittenSignatureActivity.this,
173//                          "FileExtension: " + fileExtension + "\n" +
174//                          "MimeType: " + mimeType,
175//                          Toast.LENGTH_LONG).show();
176                       
177                        //Filtra por mimeType
178                        if(filterMimeType.isEmpty() || filterMimeType == mimeType)
179                            files.add(f);
180                               
181                    }
182                }
183            }
184
185            Collections.sort(directories); // Ordena los directorios alfabeticamente
186            Collections.sort(files); // Ordena los archivos alfabeticamente
187        }
188       
189        /**
190         * Retorna cantidad total de elementos que se listarán en el directorio.
191         */
192        @Override 
193        public int getCount() {
194               
195            return directories.size() + files.size();
196           
197        }
198
199        /**
200         * Dada una posición en el listado del directorio, retorna un archivo o directorio
201         * según corresponda.
202         */
203        @Override
204        public File getItem(int position) {
205
206            if (position < directories.size()) {
207                return directories.get(position);
208            } else {
209                return files.get(position - directories.size());
210            }
211        }
212
213        /**
214         * Retorna un código hash para el archivo, permite comparar si dos archivos son los mismos
215         */
216        @Override
217        public long getItemId(int position) {
218
219            return getItem(position).hashCode();
220        }
221       
222        /**
223         * Crea la visualización de cada item del fileBrowser
224         */
225        @Override
226        public View getView(int position, View convertView, ViewGroup parent) {
227
228                //Crea la vista de cada fila del filebrowser a partir del layout
229            if (convertView == null) {
230                LayoutInflater inflater = LayoutInflater.from(FilesToPDFSignActivity.this);
231                convertView = inflater.inflate(R.layout.files_to_pdf_sign_item, parent, false); 
232            }
233           
234            // Se enlaza a cada componente del layout
235            ImageView image = (ImageView) convertView.findViewById(R.id.type_image);
236            TextView fileName = (TextView) convertView.findViewById(R.id.filename_text);
237            TextView modified = (TextView) convertView.findViewById(R.id.filename_modified);
238           
239            // Se obtiene el archivo ubicado en position
240                File file = getItem(position);
241               
242                //RadioButton
243            CheckBox check = (CheckBox) convertView.findViewById(R.id.file_check);
244            check.setFocusable(false);
245           
246            // Se asignan los iconos según el tipo de archivo y se oculta el radio en los directorios
247            if (file.isDirectory()) {
248                image.setImageResource(R.drawable.ic_carpeta_verde);
249                check.setVisibility(View.INVISIBLE);
250                check.setChecked(false);
251            } else {
252                image.setImageResource(R.drawable.ic_archivo_verde);
253                check.setVisibility(View.VISIBLE);
254                if (!FilesToPDFSignActivity.this.selected.contains(file)){
255                        check.setChecked(false);
256                } else{
257                        check.setChecked(true);
258                }
259         
260            }
261
262            // Si es el directorio que hace referencia al padre le coloca como nombre ".."
263            if (file.isDirectory() && position == 0 && ! "/".equals(FilesToPDFSignActivity.this.cwd.getAbsolutePath())) {
264                fileName.setText("..");
265            } else {
266                fileName.setText(file.getName());
267            }
268 
269           
270            //Datos de modificación del archivo
271            SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
272            Date date = new Date(file.lastModified());
273           
274            String dateString = FilesToPDFSignActivity.this.getString(R.string.modified)+": ";
275            if (file.lastModified()>0)
276                modified.setText(dateString+sdf.format(date));
277            else
278                modified.setText(dateString+"-");
279           
280            return convertView;
281        }
282       
283        /**
284         * Controla la selección de cada item del fileBrowser
285         */
286        public void select(ListView parent, int position) {
287
288            File item = getItem(position);
289            //Si es un directorio el seleccionado se hace un llamado del fileBrowser del directorio
290            if (item.isDirectory()) {
291                parent.setAdapter(FilesToPDFSignActivity.this.listAdapter = new FileListAdapter(item.getAbsolutePath(), filterMImeType));
292            } else { // Si es un archivo
293               
294                        //Se agrega el archivo a la lista de seleccionados si no se encuentra en la misma               
295                if (!FilesToPDFSignActivity.this.selected.contains(item)){
296                       
297                        FilesToPDFSignActivity.this.selected.add(item);                         
298                        FilesToPDFSignActivity.this.updateButton(FilesToPDFSignActivity.this.viewHolder.accept,true);           
299                                               
300                }
301                else{ // De lo contrario se elimina de la lista de seleccionados
302                       
303                        FilesToPDFSignActivity.this.selected.remove(item);
304                       
305                        if (FilesToPDFSignActivity.this.selected.isEmpty()){
306                               
307                                FilesToPDFSignActivity.this.updateButton(FilesToPDFSignActivity.this.viewHolder.accept,false);
308
309                               
310                        }else {
311                                FilesToPDFSignActivity.this.updateButton(FilesToPDFSignActivity.this.viewHolder.accept,true);
312
313                        }
314                                       
315                }
316                notifyDataSetChanged();
317           }
318        }       
319    }   
320
321
322   
323   
324    @Override
325    protected void onSaveInstanceState(Bundle outState) {
326        super.onSaveInstanceState(outState);
327
328        outState.putParcelable("intent", this.getIntent());
329        outState.putString("cwd", this.cwd.getAbsolutePath());
330        outState.putStringArrayList("selected", TypeUtils.convertToStringArrayList(this.selected));
331       
332        outState.putParcelable("intent", this.data);
333        outState.putInt("requestCode", this.requestCode);
334        outState.putInt("resultCode", this.resultCode);
335       
336        }
337   
338    private void updateButton(View v, boolean bool) {
339        try{
340
341                v.setEnabled(bool);
342                if (v instanceof TextView){
343                        Drawable icon = ((TextView)v).getCompoundDrawables()[1];
344                        if (icon!=null)
345                        if (bool)
346                                icon.setAlpha(255);
347                        else
348                                icon.setAlpha(127);     
349                }
350                if (v instanceof ImageView){
351                        ImageView result = (ImageView) v;
352                        if (bool)
353                                result.setAlpha(255);
354                        else
355                                result.setAlpha(127);   
356                }
357       
358        }catch(NullPointerException e){}
359                       
360        }
361   
362    private void updateButton(LinearLayout layout, boolean bool) {
363        try{
364        layout.setEnabled(bool);
365        for (int i=0; i<layout.getChildCount();i++){
366                this.updateButton(layout.getChildAt(i), bool);
367        }
368        }catch(NullPointerException e){}
369                       
370        }
371
372       
373       
374        /**
375     * Holds references to view objects.
376     *
377     * @author José M. Prieto (jmprieto@emergya.com)
378     */
379    private class FileBrowserView {
380
381        public ListView fileList;
382        public TextView path;
383        public LinearLayout accept;
384                public LinearLayout clear;
385        public TextView pathString;
386
387        public FileBrowserView() {
388
389            setContentView(R.layout.activity_file_to_sign_handwritten_signature);
390            this.path = (TextView) findViewById(R.id.path);
391            this.pathString = (TextView) findViewById(R.id.pathstring);
392
393            this.fileList = (ListView) findViewById(R.id.file_list);
394            this.fileList.setOnItemClickListener(FilesToPDFSignActivity.this);
395            this.fileList.setItemsCanFocus(true);
396         
397           
398            this.clear = (LinearLayout) findViewById(R.id.button_clear_zone);
399            this.clear.setOnClickListener(FilesToPDFSignActivity.this);
400           
401            this.accept = (LinearLayout) findViewById(R.id.button_accept_zone);
402            this.accept.setOnClickListener(FilesToPDFSignActivity.this);
403
404        }
405    }
406   
407        @Override
408    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
409       
410       
411        if (parent.getId() == R.id.file_list) { // user selects a file
412            this.listAdapter.select((ListView) parent, position);
413           
414        } else { // user de-selects a file
415            //this.listAdapter.addIfSameDirectory(selectedAdapter.doUnselect((ListView) parent, position));
416               
417        }
418        //this.viewHolder.numSelected.setText(Integer.toString(this.selected.size()));
419    }
420
421    @Override
422    public void onClick(View v) {
423
424        switch (v.getId()) {
425
426       
427        case R.id.button_clear_zone:
428
429                this.selected.clear();
430                this.listAdapter.notifyDataSetChanged();
431
432                //this.viewHolder.numSelected.setText(""+this.selected.size());
433            this.updateButton(this.viewHolder.accept, false);
434                break;         
435       
436
437       
438            case R.id.button_accept_zone: 
439
440                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH || this.getFileStreamPath(DirectKeyChain.keyStoreFilename).exists()){
441                       
442           
443                Intent intent = new Intent(this, FilesToPDFSignConfirmationActivity.class);
444                intent.putStringArrayListExtra(IntentExtraField.FILES, TypeUtils.convertToStringArrayList(this.selected));
445                startActivityForResult(intent, ActivityResult.FILES_CONFIRMATED);
446         
447               
448                        }else{
449                                this.createNoKeyStoreDialog();
450                        }
451           
452                break;         
453       
454        }
455    }
456   
457   
458        private void createNoKeyStoreDialog() {
459                AlertDialog.Builder builder = new AlertDialog.Builder(this);
460
461                builder.setCancelable(false);
462                builder.setMessage(R.string.error_keystore_file);
463                builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
464                public void onClick(DialogInterface dialog, int id) {
465                    dialog.dismiss();
466                }
467            });
468                AlertDialog dialog = builder.create(); 
469                dialog.show();
470               
471        }
472   
473        @Override
474    protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
475        //Toast.makeText(this, "result", Toast.LENGTH_LONG).show();
476
477        this.requestCode = requestCode;
478        this.resultCode = resultCode;
479        this.data=data;
480        //Toast.makeText(this, "request_code="+this.requestCode+" result="+this.resultCode, Toast.LENGTH_LONG).show();
481       
482       
483
484        if (resultCode == RESULT_CANCELED && requestCode!=ActivityResult.FILES_CONFIRMATED
485                &&      requestCode!=ActivityResult.IMPORT_CERTIFICATE) {
486                //Removed to fix task error #73085
487            /*setResult(RESULT_CANCELED);
488            finish();
489            return;
490            */
491               
492               
493                if (this.selected.size()>0){
494                 Intent intent = new Intent(this, FilesToPKCS7SignConfirmationActivity.class);
495             intent.putStringArrayListExtra(IntentExtraField.FILES, TypeUtils.convertToStringArrayList(this.selected));
496             startActivityForResult(intent, ActivityResult.FILES_CONFIRMATED);
497                }
498               
499               
500        }
501
502       
503        switch (requestCode) {
504        case ActivityResult.CHECK_CERTIFICATE_VALIDITY:
505
506            if (resultCode == RESULT_OK) {
507                //Toast.makeText(FilesToPDFSignActivity.this, "aqui", Toast.LENGTH_LONG).show();
508
509                boolean embedSignature = data.getBooleanExtra(IntentExtraField.EMBED_SIGNATURE_IN_PDF, false);
510                Intent intent = new Intent(this, SignActivity.class);
511                intent.putExtra(IntentExtraField.EMBED_SIGNATURE_IN_PDF, embedSignature);
512                intent.putExtra(IntentExtraField.ALIAS, this.privateKeyAlias);
513                intent.putParcelableArrayListExtra(IntentExtraField.FILES, TypeUtils.convertToUriArrayList(this.selected));
514                startActivity(intent);
515               
516                //Finish only in this branch to fix error #73085
517                finish();
518            }
519            break;
520       
521        case ActivityResult.FILES_CONFIRMATED:
522                if (resultCode == RESULT_OK){
523                                               
524                        this.selected.clear();
525                        List<String> paths = data.getStringArrayListExtra(IntentExtraField.FILES);
526                        for (String s: paths)
527                                this.selected.add(new File(s));
528                       
529                        this.listAdapter.notifyDataSetChanged();
530                        KeyChainStrategy.getInstance().choosePrivateKeyAlias();
531
532                }
533                break;
534        }
535               
536               
537//        if (requestCode == ActivityResult.IMPORT_CERTIFICATE && resultCode == Activity.RESULT_OK) {
538//            //this.launchPasswordDialog(data);
539//        }
540    }
541       
542
543
544    private void launchPasswordDialog(final Intent data) {
545                //TODO: Setting boolean to false instead of true. Disables "New KeyStore" option.
546
547        final PasswordDialog dialog = new PasswordDialog(this, R.string.certificate_password, false);
548        dialog.setAcceptListener(new OnClickListener() {
549
550            @Override
551            public void onClick(View v) {
552
553                try {
554                        DirectKeyChain direct = DirectKeyChain.getInstance();
555                    int imported = direct.importCertificate(data.getData(), dialog.getPassword());
556                    String text = FilesToPDFSignActivity.this.getResources().getQuantityString(R.plurals.number_imported_certificates, imported, imported);
557                    Toast.makeText(FilesToPDFSignActivity.this, text, Toast.LENGTH_LONG).show();
558                    direct.saveKeystore();
559                    direct.refreshAdapter();
560                   
561                } catch (IncorrectPasswordException e) {
562                    Toast toast = Toast.makeText(FilesToPDFSignActivity.this, R.string.incorrect_password, Toast.LENGTH_LONG);
563                    toast.show();
564                } catch (Exception e) {
565                    Toast toast = Toast.makeText(FilesToPDFSignActivity.this, R.string.error_reading_p12, Toast.LENGTH_LONG);
566                    toast.show();
567                }
568               
569             
570               
571                dialog.dismiss();
572                FilesToPDFSignActivity.this.requestCode=Integer.MIN_VALUE;
573                FilesToPDFSignActivity.this.resultCode=Integer.MIN_VALUE;
574                FilesToPDFSignActivity.this.data=null;
575            }
576        });
577       
578       
579       
580        //TODO:
581       
582       dialog.setOnDismissListener(new OnDismissListener(){
583
584                @Override
585                public void onDismiss(DialogInterface arg0) {
586                        FilesToPDFSignActivity.this.data=null;
587                        FilesToPDFSignActivity.this.requestCode=Integer.MIN_VALUE;
588                        FilesToPDFSignActivity.this.resultCode=Integer.MIN_VALUE;                       
589                }});
590       
591       
592       
593       
594        dialog.setOnCancelListener(new OnCancelListener(){
595
596                        @Override
597                        public void onCancel(DialogInterface dialog) {
598                                FilesToPDFSignActivity.this.data=null;
599                                FilesToPDFSignActivity.this.requestCode=Integer.MIN_VALUE;
600                                FilesToPDFSignActivity.this.resultCode=Integer.MIN_VALUE;                               
601                        }});
602       
603        dialog.show();
604       
605        }
606
607
608    @Override
609    public void setAlias(String alias) {
610
611        if (alias == null) {
612                Toast.makeText(CustomKeyChain.activity, "alias null", Toast.LENGTH_LONG).show();
613
614            finish();
615            return;
616        }
617       // Toast.makeText(this, "setAlias="+alias, Toast.LENGTH_LONG).show();
618       
619        this.privateKeyAlias = alias;
620        Intent intent = new Intent(this, CertValidatorActivity.class);
621        intent.putExtra(IntentExtraField.ALIAS, alias);
622        intent.putExtra(IntentExtraField.EMBED_SIGNATURE_IN_PDF, true);
623        intent.putParcelableArrayListExtra(IntentExtraField.FILES, TypeUtils.convertToUriArrayList(this.selected));
624        startActivityForResult(intent, ActivityResult.CHECK_CERTIFICATE_VALIDITY);
625    }
626       
627
628}
Note: See TracBrowser for help on using the repository browser.