source: dispositivos_moviles/TibisayMovil/src/ve/gob/cenditel/tibisaymovil/DownloaderActivity.java @ c14b8d2

Last change on this file since c14b8d2 was 56b06e2, checked in by Antonio Araujo Brett <aaraujo@…>, 11 years ago

*- Carga de certificados de servidores confiables al momento de descargar archivos a través de https.

  • Property mode set to 100644
File size: 23.8 KB
Line 
1package ve.gob.cenditel.tibisaymovil;
2
3
4import java.io.BufferedInputStream;
5import java.io.File;
6import java.io.FileInputStream;
7import java.io.FileOutputStream;
8import java.io.IOException;
9import java.io.InputStream;
10import java.io.OutputStream;
11import java.lang.reflect.Field;
12import java.net.HttpURLConnection;
13import java.net.URL;
14import java.security.KeyStore;
15import java.security.cert.Certificate;
16import java.security.cert.CertificateFactory;
17import java.util.ArrayList;
18
19import javax.net.ssl.HttpsURLConnection;
20import javax.net.ssl.SSLContext;
21import javax.net.ssl.TrustManagerFactory;
22
23
24import android.net.Uri;
25import android.os.AsyncTask;
26import android.os.Bundle;
27import android.os.Environment;
28import android.os.Looper;
29import android.app.Activity;
30import android.app.AlertDialog;
31import android.app.Dialog;
32import android.app.ProgressDialog;
33import android.content.DialogInterface;
34import android.content.Intent;
35import android.util.Log;
36import android.view.Menu;
37import android.view.Window;
38import android.webkit.MimeTypeMap;
39import android.widget.Toast;
40
41public class DownloaderActivity extends Activity {
42
43        // cadena que mantiene la ruta para almacenar los archivos
44    // extraidos de un contendor BDOC
45    private String extractedDirFiles;
46   
47    // cadena que mantiene la ruta para almacenar los archivos
48    // descargados desde un servidor para verificar su firma
49    private String downloadedDirFiles;
50   
51    // ruta absoluta al archivo a verificar
52    private String fileToVerify;
53   
54    // extension del archivo a verificar
55    private String fileToVerifyExtension;
56       
57    // cadena que mantiene la URL al descargar archivo con https
58    String urlhttps = null;
59       
60        // Progress Dialog
61    private ProgressDialog mProgressDialog;
62   
63    // Progress dialog type (0 - for Horizontal progress bar)
64    public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
65
66   
67   
68        @Override
69        protected void onCreate(Bundle savedInstanceState) {
70               
71                //Estilando la barra de titulo
72                final boolean customTitleSupported = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
73                               
74                super.onCreate(savedInstanceState);
75                //setContentView(R.layout.activity_downloader);
76                setContentView(R.layout.activity_verify_result_bdoc);
77               
78                //Estilando Barra de titulo
79                if(customTitleSupported)
80                        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title_bar);
81               
82                // ------------------------------------------------------------------------------------
83                // el siguiente segmento de codigo permite obtener los nombres de los archivos
84                // que estan en /res/raw
85                ArrayList<String> list = new ArrayList<String>();
86                Field[] fields = R.raw.class.getFields();
87               
88                for (int l=0; l < fields.length; l++) {
89                        try {
90                                Toast.makeText(getApplicationContext(), "DownloaderActivity: "+Integer.toString(l)+ " "+ Integer.toString(fields[l].getInt(null)), Toast.LENGTH_SHORT).show();
91                        } catch (IllegalArgumentException e) {
92                                // TODO Auto-generated catch block
93                                Toast.makeText(getApplicationContext(), "DownloaderActivity: IllegalArgumentException "+e.getMessage(), Toast.LENGTH_SHORT).show();
94                        } catch (IllegalAccessException e) {
95                                // TODO Auto-generated catch block
96                                Toast.makeText(getApplicationContext(), "DownloaderActivity: IllegalAccessException "+e.getMessage(), Toast.LENGTH_SHORT).show();
97                        }
98                }
99               
100                /*
101                for(Field f : fields)
102                try {
103                        Toast.makeText(getApplicationContext(), "DownloaderActivity: Fields.length: "+Integer.toString(fields.length), Toast.LENGTH_SHORT).show();
104                        Toast.makeText(getApplicationContext(), "DownloaderActivity: "+f.getName(), Toast.LENGTH_SHORT).show();
105                        //list.add(splitString[0]);
106                } catch (IllegalArgumentException e) {
107                        Toast.makeText(getApplicationContext(), "DownloaderActivity: IllegalArgumentException "+e.getMessage(), Toast.LENGTH_SHORT).show();
108                }
109                */
110                // ------------------------------------------------------------------------------------
111               
112               
113               
114                // chequear si intent tiene data
115        final android.content.Intent intent = getIntent();
116
117        final Bundle bundle = getIntent().getExtras();
118       
119              if (intent != null) {
120                  Toast.makeText(getApplicationContext(), "DownloaderActivity: intent != null", Toast.LENGTH_SHORT).show();
121
122                  final android.net.Uri data = intent.getData ();
123                 
124                      if (data != null) {
125                          Toast.makeText(getApplicationContext(), "data != null", Toast.LENGTH_SHORT).show();
126                         
127                          // verificar el tipo de scheme
128                          String scheme = data.getScheme();
129                           
130                          // verificacion de un archivo que esta en el dispositivo
131                          if (scheme.equals("file")) {
132                                  Toast.makeText(getApplicationContext(), "file: "+data.getPath(), Toast.LENGTH_SHORT).show();
133                                 
134                                  // verificar el archivo
135                                  if (data.getPath().endsWith("bdoc")){
136                                          fileToVerify = data.getPath();
137                                         
138                                          // ejecutar la verificacion           
139                                          //doBdocVerification(data.getPath());
140                                                }else{
141                                                        Toast.makeText(getApplicationContext(), "¡Por Implementar!", Toast.LENGTH_SHORT).show();
142                                                       
143                                                }
144                                 
145                          }
146                           
147                          // verificacion de un archivo que se debe descargar
148                          if (scheme.equals("https")) {
149                                  Toast.makeText(getApplicationContext(), "scheme: "+data.toString(), Toast.LENGTH_SHORT).show();
150                                 
151                                  //Toast.makeText(getApplicationContext(), "externalStorage: "+Environment.getExternalStorageDirectory().toString(), Toast.LENGTH_SHORT).show();
152                                 
153                                  urlhttps = data.toString();
154                                  new DownloadFileAsync().execute(data.toString(), "false");
155                                 
156                                  //new DownloadFileFromURL().execute("http://farm1.static.flickr.com/114/298125983_0e4bf66782_b.jpg");
157                                 
158                                  //Toast.makeText(getApplicationContext(), "****despues de execute()", Toast.LENGTH_SHORT).show();
159                                  // verificar el archivo
160                                  //Toast.makeText(getApplicationContext(), "Ahora viene la verificación del archivo", Toast.LENGTH_SHORT).show();
161                          }
162                         
163                         
164                          return;
165                      }
166                     
167                      // verificacion de archivo desde la Activity principal
168                      if (bundle != null) {
169                        fileToVerify = bundle.getString("fileToVerify");
170                        fileToVerifyExtension = bundle.getString("fileExtension"); 
171                       
172                                       
173                        Toast.makeText(getApplicationContext(), "fileToVerify bundle!=null: "+fileToVerify, Toast.LENGTH_SHORT).show();
174                       
175                        if (fileToVerifyExtension.equals("bdoc")){
176                                Toast.makeText(getApplicationContext(), "verificacion de archivo desde la Activity principal", Toast.LENGTH_SHORT).show();
177                                        // ejecutar la verificacion             
178                                        //doBdocVerification(fileToVerify);
179                                }else{
180                                        Toast.makeText(getApplicationContext(), "¡Por Implementar!", Toast.LENGTH_SHORT).show();
181                                       
182                                }
183                       
184                        //return;
185                      }
186                                 
187              }else{
188                  Toast.makeText(getApplicationContext(), "intent == null", Toast.LENGTH_SHORT).show();
189              }
190               
191        }
192
193       
194        /**
195     * Prepara directorio
196     * @return boolean
197     */
198    private boolean prepareDirectory(String dir) 
199    {
200        try
201        {
202            if (makedirs(dir)) 
203            {
204                return true;
205            } else {
206                return false;
207            }
208        } catch (Exception e) 
209        {
210            e.printStackTrace();
211            Toast.makeText(this, "Could not initiate File System.. Is Sdcard mounted properly?", Toast.LENGTH_LONG).show();
212            return false;
213        }
214    }
215 
216    /**
217     * Crea directorio utilizando la variable tmpDir
218     * @return boolean
219     */
220    private boolean makedirs(String dir) 
221    {
222        //File tempdir = new File(extractedDirFiles);
223        File tempdir = new File(dir);
224        if (!tempdir.exists())
225            tempdir.mkdirs();
226 
227//        if (tempdir.isDirectory())
228//        {
229//            File[] files = tempdir.listFiles();
230//            for (File file : files)
231//            {
232//                if (!file.delete())
233//                {
234//                    System.out.println("Failed to delete " + file);
235//                }
236//            }
237//        }
238        return (tempdir.isDirectory());
239    }
240       
241       
242        /**
243     * Showing Dialog for downloading file
244     * */
245    @Override
246    protected Dialog onCreateDialog(int id) {
247        switch (id) {
248        case DIALOG_DOWNLOAD_PROGRESS: // we set this to 0
249                mProgressDialog = new ProgressDialog(this);
250                mProgressDialog.setMessage("Descargando archivo. Por favor espere...");
251                mProgressDialog.setIndeterminate(false);
252                mProgressDialog.setMax(100);
253                mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
254                mProgressDialog.setCancelable(true);
255                mProgressDialog.show();
256            return mProgressDialog;
257        default:
258            return null;
259        }
260    }
261       
262   
263 // clase para descargar archivo
264        private class DownloadFileAsync extends AsyncTask<String, String, ArrayList<String>> {
265
266                File rootDir = Environment.getExternalStorageDirectory();
267               
268                /**
269         * Before starting background thread
270         * Show Progress Bar Dialog
271         * */
272        @Override
273        protected void onPreExecute() {
274            super.onPreExecute();
275            showDialog(DIALOG_DOWNLOAD_PROGRESS);
276        }
277               
278               
279        /**
280         * Downloading file in background thread
281         * */
282        @Override
283        protected ArrayList<String> doInBackground(String... params) {
284           
285                // para solventar error:
286                // Can't create handler inside thread that has not called Looper.prepare()
287                Looper.prepare();
288               
289                int count;
290               
291                Log.d("doInBackground", params[0]);
292           
293            // resultArray [0] -> 0 para ruta de archivo valida
294            // resultArray [0] -> 1 ocurrio un error
295            // resultArray [1] -> ruta del archivo descargado
296            // resultArray [1] -> mensaje de la excepcion
297            ArrayList<String> resultArray = new ArrayList<String>();
298            resultArray.clear();
299               
300           
301            String outputString = null;
302            try {
303                URL url = new URL(params[0]);
304               
305                int lenghtOfFile = 0;
306                InputStream input = null;
307               
308                if (url.getProtocol().equals("http")){
309                        HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
310                        input = new BufferedInputStream(httpConnection.getInputStream());
311                        lenghtOfFile = httpConnection.getContentLength();
312                   
313                }else{ // https
314                       
315                        // ejecutar la descarga despues de haber aceptado que el certificado
316                        // no es conocido
317                        if (params[1].equals("true")){
318                                Log.d("***", "params[1].equals(true)");
319                               
320                                // descarga del certificado del servidor
321                               
322                                // crear certificate factory
323                                CertificateFactory cf = CertificateFactory.getInstance("X.509");
324                               
325                                // crear un KeyStore
326                                String keyStoreType = KeyStore.getDefaultType();
327                        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
328                        keyStore.load(null, null);
329                               
330                        // obtener vector de campos de /res/raw
331                                Field[] fields = R.raw.class.getFields();
332                               
333                                InputStream caInput = null; 
334                               
335                                // iterar sobre todos los certificados incluidos en /res/raw y cargarlos
336                                // en el KeyStore
337                                for (int l=0; l < fields.length; l++) {
338                                        try {
339                                                Toast.makeText(getApplicationContext(), "DownloaderActivity: "+Integer.toString(l)+ " "+ 
340                                                        Integer.toString(fields[l].getInt(null)), Toast.LENGTH_SHORT).show();
341
342                                                caInput = new BufferedInputStream(getResources().openRawResource(fields[l].getInt(null))); 
343
344                                        } catch (IllegalArgumentException e) {
345                                                // TODO Auto-generated catch block
346                                                Toast.makeText(getApplicationContext(), "DownloaderActivity: IllegalArgumentException "+e.getMessage(),                                         Toast.LENGTH_SHORT).show();
347                                        } catch (IllegalAccessException e) {
348                                                // TODO Auto-generated catch block
349                                                Toast.makeText(getApplicationContext(), "DownloaderActivity: IllegalAccessException "+e.getMessage(),                                   Toast.LENGTH_SHORT).show();
350                                        }
351                                                                         
352                            Certificate ca;
353                            try {
354                                ca = cf.generateCertificate(caInput);
355                                //Log.d("**ca:", ((X509Certificate) ca).getSubjectDN());
356                                           
357                                //Log.d("*** try: ca.toString()", ca.toString());
358                                } finally {
359                                    caInput.close();
360                                }
361                                        keyStore.setCertificateEntry("ca"+Integer.toString(l), ca);
362                                }// fin de la iteracion sobre /res/raw
363
364                                // Create a TrustManager that trusts the CAs in our KeyStore
365                                String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
366                                TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
367                                tmf.init(keyStore);
368                                Log.d("***", "despues de crear TrustManager");
369
370                                // Create an SSLContext that uses our TrustManager
371                                SSLContext context = SSLContext.getInstance("TLS");
372                                context.init(null, tmf.getTrustManagers(), null);
373                                Log.d("***", "despues de crear SSLContext");
374                               
375                                HttpsURLConnection httpsConnection = (HttpsURLConnection) url.openConnection();
376                                Log.d("***", "despues de crear httpsConnection");
377                               
378                                httpsConnection.setSSLSocketFactory(context.getSocketFactory());
379                                Log.d("***", "despues de crear setSSLSocketFactory");
380                               
381                                //input = new BufferedInputStream(httpsConnection.getInputStream());
382                                input = httpsConnection.getInputStream();
383                               
384                                Log.d("***", "despues de crear BufferedInputStream");
385                               
386                                lenghtOfFile = httpsConnection.getContentLength();
387                                Log.d("***", "se acepto la excepcion");
388
389                               
390                                /*
391                                // descarga del certificado del servidor
392                                CertificateFactory cf = CertificateFactory.getInstance("X.509");
393                                InputStream caInput = new BufferedInputStream(getResources().openRawResource(R.raw.gestion));
394                                Certificate ca;
395                                try {
396                                    ca = cf.generateCertificate(caInput);
397                                    //Log.d("**ca:", ((X509Certificate) ca).getSubjectDN());
398                                   
399                                    //Log.d("*** try: ca.toString()", ca.toString());
400                                } finally {
401                                    caInput.close();
402                                }
403                                Log.d("***", "despues de Certificate ca");
404                               
405                                // Create a KeyStore containing our trusted CAs
406                                String keyStoreType = KeyStore.getDefaultType();
407                                KeyStore keyStore = KeyStore.getInstance(keyStoreType);
408                                keyStore.load(null, null);
409                                keyStore.setCertificateEntry("ca", ca);
410                                Log.d("***", "despues de crear KeyStore");
411                               
412                                // Create a TrustManager that trusts the CAs in our KeyStore
413                                String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
414                                TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
415                                tmf.init(keyStore);
416                                Log.d("***", "despues de crear TrustManager");
417
418                                // Create an SSLContext that uses our TrustManager
419                                SSLContext context = SSLContext.getInstance("TLS");
420                                context.init(null, tmf.getTrustManagers(), null);
421                                Log.d("***", "despues de crear SSLContext");
422                               
423                                HttpsURLConnection httpsConnection = (HttpsURLConnection) url.openConnection();
424                                Log.d("***", "despues de crear httpsConnection");
425                               
426                                httpsConnection.setSSLSocketFactory(context.getSocketFactory());
427                                Log.d("***", "despues de crear setSSLSocketFactory");
428                               
429                                //input = new BufferedInputStream(httpsConnection.getInputStream());
430                                input = httpsConnection.getInputStream();
431                               
432                                Log.d("***", "despues de crear BufferedInputStream");
433                               
434                                lenghtOfFile = httpsConnection.getContentLength();
435                                Log.d("***", "se acepto la excepcion");
436                               
437                                */
438                               
439                        }else{                 
440                                HttpsURLConnection httpsConnection = (HttpsURLConnection) url.openConnection();
441                                input = new BufferedInputStream(httpsConnection.getInputStream());
442                                lenghtOfFile = httpsConnection.getContentLength();
443                        }
444                }
445               
446               
447                // Crear directorio DownloadedFiles donde se almacenan los archivos descargados
448                        // desde un servidor para verificar su firma
449                        downloadedDirFiles = Environment.getExternalStorageDirectory() + "/" +
450                        getResources().getString(R.string.app_name) + "/" +
451                        getResources().getString(R.string.downloaded_dir_files) + "/";                 
452                        prepareDirectory(downloadedDirFiles);
453
454                //int lenghtOfFile = conexion.getContentLength();
455                Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
456
457                //InputStream input = new BufferedInputStream(url.openStream());               
458                //InputStream input = new BufferedInputStream(conexion.getInputStream());
459               
460                //OutputStream output = new FileOutputStream("/mnt/sdcard/TibisayMovil/ExtractedFiles/photo.jpg");
461               
462                //OutputStream output = new FileOutputStream(new File(rootDir+"/midescarga/", "foto.jpg"));
463
464                String urlString = url.toString();
465                String[] values = urlString.split("/");
466               
467                //OutputStream output = new FileOutputStream(new File(downloadedDirFiles, "acta.2.bdoc"));
468                OutputStream output = new FileOutputStream(new File(downloadedDirFiles, values[values.length-1]));
469               
470                byte data[] = new byte[1024];
471
472                long total = 0;
473
474                while ((count = input.read(data)) != -1) {
475                    total += count;
476                    publishProgress(""+(int)((total*100)/lenghtOfFile));
477                    output.write(data, 0, count);
478                }
479
480                output.flush();
481                               
482                output.close();
483                input.close();
484               
485                resultArray.add("0");
486                //resultArray.add(output.toString());
487                resultArray.add(downloadedDirFiles+values[values.length-1]);
488 
489            } catch (Exception e) {
490               
491                Log.e("Error: ", e.getMessage());
492                outputString = e.getMessage();
493               
494                resultArray.add("1");
495                resultArray.add(e.toString());
496               
497            }
498
499            //return null;
500            return resultArray;
501           
502        }
503       
504        protected void onProgressUpdate(String... progress) {
505            Log.d("ANDRO_ASYNC",progress[0]);
506            mProgressDialog.setProgress(Integer.parseInt(progress[0]));
507       }
508
509       @Override
510       protected void onPostExecute(ArrayList<String> result) {
511           dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
512           //Toast.makeText(getApplicationContext(), "onPostExecute: "+ result.get(0), Toast.LENGTH_LONG).show();
513           
514           // ocurrio una excepcion
515           if (result.get(0).equals("1")){
516               
517                   //Toast.makeText(getApplicationContext(), "onPostExecute: dentro del if" , Toast.LENGTH_LONG).show();
518               
519                        // ocurrio un problema
520                        AlertDialog.Builder builder = new AlertDialog.Builder(DownloaderActivity.this);
521                       
522                        String exception = "";
523                        boolean fileFound = true;
524                       
525                        if (result.get(1).contains("Trust anchor for certification path not found")){
526                                exception = "Intenta descargar un archivo de un servidor con certificado no confiable. ¿Desea continuar?.";
527                               
528                        }
529                        if (result.get(1).contains("java.io.FileNotFoundException")){
530                                String [] v = result.get(1).split("/");
531                                int length = v.length;
532                               
533                                exception = "No se encontró el archivo "+ v[length-1] +" en el servidor.";
534                                fileFound = false;                             
535                        }
536                       
537                        builder.setMessage(exception).setTitle("Error al descargar el archivo");
538                       
539                        if (fileFound){
540                       
541                                builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
542                        public void onClick(DialogInterface dialog, int id) {
543                            // User clicked OK button
544                   
545                                Log.d("***", "DownloadFileAsync().execute(urlhttps, true)");
546                                Toast.makeText(getApplicationContext(), "DownloadFileAsync().execute("+urlhttps+", true)", Toast.LENGTH_LONG).show();
547                                // pasar como segundo argmento que se acepta que el sertivor es desconocido
548                                new DownloadFileAsync().execute(urlhttps, "true");
549                        }
550                                });
551                               
552                        }
553                       
554                        builder.setNegativeButton("Cancelar", new DialogInterface.OnClickListener() {
555                   public void onClick(DialogInterface dialog, int id) {
556                       // User cancelled the dialog
557                           DownloaderActivity.this.finish();
558                   }
559                        });
560                        AlertDialog dialog = builder.create();
561                        dialog.show();
562
563           }else{
564                   // no ocurrió excepcion
565                   Toast.makeText(getApplicationContext(), "Se descargo correctamente el archivo", Toast.LENGTH_LONG).show();
566                   
567                   Toast.makeText(getApplicationContext(), "result.get(0): "+result.get(0), Toast.LENGTH_LONG).show();
568                   Toast.makeText(getApplicationContext(), "result.get(1): "+result.get(1), Toast.LENGTH_LONG).show();
569                   Toast.makeText(getApplicationContext(), "downloadedDirFiles: "+downloadedDirFiles, Toast.LENGTH_LONG).show();
570                   
571                   // lanzar activity para mostrar resultados de verificacion
572                           Intent intent = new Intent(DownloaderActivity.this, BDOCVerifyResultActivity.class);
573                           intent.putExtra("fileToVerify", result.get(1));
574                           Toast.makeText(getApplicationContext(), "putExtra1: "+result.get(1), Toast.LENGTH_LONG).show();
575                               
576                           File f = new File(result.get(1));
577                           Uri selectedUri = Uri.fromFile(f);
578                           String fileExtension = MimeTypeMap.getFileExtensionFromUrl(selectedUri.toString());
579                           intent.putExtra("fileExtension", fileExtension);
580                           
581                        Toast.makeText(getApplicationContext(), "putExtra2: "+fileExtension, Toast.LENGTH_LONG).show();
582                           
583                           startActivity(intent);   
584                           
585                           DownloaderActivity.this.finish();
586           }
587           
588                 
589       }
590       
591
592       
593
594               
595       
596        } // fin de la clase DownloadFileAsync
597   
598
599} // fin de DownloaderActivity
Note: See TracBrowser for help on using the repository browser.