com.haha01haha01.harail.DatabaseDownloader.java Source code

Java tutorial

Introduction

Here is the source code for com.haha01haha01.harail.DatabaseDownloader.java

Source

/* HaRail - Public transport fastest-route finder for Israel Railways
 * Copyright(C) 2014  haha01haha01
    
 * 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 3 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, see <http://www.gnu.org/licenses/>.*/

package com.haha01haha01.harail;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;

import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.os.Environment;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

public class DatabaseDownloader extends IntentService {
    public static final String FINISHED = "com.haha01haha01.harail.DatabaseDownloader.FINISHED";
    public static final String EXTENDED_SUCCESS = "com.haha01haha01.harail.DatabaseDownloader.EXTENDED_SUCCESS";
    private static final String NAME = "HARAIL_DATABASE_DOWNLOADER";
    private static final String irw_gtfs_server = "gtfs.mot.gov.il";
    private static final int irw_gtfs_port = 21;
    private static final String irw_gtfs_filename = "irw_gtfs.zip";

    public DatabaseDownloader() {
        super(NAME);
    }

    @Override
    protected void onHandleIntent(Intent workIntent) {
        PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, NAME);

        NotificationManager notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        Notification.Builder builder = new Notification.Builder(this);
        builder.setContentTitle("HaRail GTFS Database").setContentText("Downloading file")
                .setSmallIcon(android.R.drawable.ic_popup_sync).setProgress(0, 0, true);
        notifyManager.notify(1, builder.build());

        wakeLock.acquire();
        try {
            String filename = "harail_irw_gtfs_" + Utils.getCurrentDateString() + ".zip";
            File zip_file = new File(
                    new File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DOWNLOADS), filename);
            if (downloadFile(irw_gtfs_server, irw_gtfs_port, "anonymous", "", irw_gtfs_filename, zip_file)) {
                sendFinished(extractDb(zip_file, notifyManager, builder));
            } else {
                sendFinished(false);
            }
            wakeLock.release();
        } catch (IOException e) {
            sendFinished(false);
            builder.setContentText("Download failed").setSmallIcon(android.R.drawable.ic_dialog_alert)
                    .setProgress(0, 0, false);
            notifyManager.notify(1, builder.build());
            wakeLock.release();
        }
    }

    private Boolean downloadFile(String server, int portNumber, String user, String password, String filename,
            File localFile) throws IOException {
        FTPClient ftp = null;

        try {
            ftp = new FTPClient();
            ftp.setBufferSize(1024 * 1024);
            ftp.connect(server, portNumber);
            Log.d(NAME, "Connected. Reply: " + ftp.getReplyString());
            if (!ftp.login(user, password)) {
                return false;
            }
            Log.d(NAME, "Logged in");
            if (!ftp.setFileType(FTP.BINARY_FILE_TYPE)) {
                return false;
            }
            Log.d(NAME, "Downloading");
            ftp.enterLocalPassiveMode();

            OutputStream outputStream = null;
            boolean success = false;
            try {
                outputStream = new BufferedOutputStream(new FileOutputStream(localFile));
                success = ftp.retrieveFile(filename, outputStream);
            } finally {
                if (outputStream != null) {
                    outputStream.close();
                }
            }

            return success;
        } finally {
            if (ftp != null) {
                ftp.logout();
                ftp.disconnect();
            }
        }
    }

    private boolean extractDb(File zip_path, NotificationManager notifyManager, Notification.Builder builder) {
        builder.setContentText("Unzipping...");
        notifyManager.notify(1, builder.build());
        File irw_folder = new File(Environment.getExternalStorageDirectory(), "irw_gtfs");
        if (irw_folder.exists()) {
            if (irw_folder.isDirectory()) {
                for (String file : irw_folder.list()) {
                    new File(irw_folder, file).delete();
                }
            } else {
                irw_folder.delete();
            }
        }
        if (!irw_folder.exists()) {
            if (!irw_folder.mkdir()) {
                builder.setContentText("Makedir failed").setSmallIcon(android.R.drawable.ic_dialog_alert)
                        .setProgress(0, 0, false);
                notifyManager.notify(1, builder.build());
                return false;
            }
        }
        unpackZip(irw_folder, zip_path);
        builder.setContentText("Finished").setProgress(0, 0, false).setSmallIcon(android.R.drawable.ic_dialog_info);
        notifyManager.notify(1, builder.build());
        return true;
    }

    private boolean unpackZip(File output_dir, File zipname) {
        InputStream is;
        ZipInputStream zis;
        try {
            String filename;
            is = new FileInputStream(zipname);
            zis = new ZipInputStream(new BufferedInputStream(is));
            ZipEntry ze;
            byte[] buffer = new byte[1024];
            int count;

            while ((ze = zis.getNextEntry()) != null) {
                filename = ze.getName();

                // Need to create directories if not exists, or
                // it will generate an Exception...
                if (ze.isDirectory()) {
                    File fmd = new File(output_dir, filename);
                    fmd.mkdirs();
                    continue;
                }

                FileOutputStream fout = new FileOutputStream(new File(output_dir, filename));

                while ((count = zis.read(buffer)) != -1) {
                    fout.write(buffer, 0, count);
                }

                fout.close();
                zis.closeEntry();
            }

            zis.close();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    private void sendFinished(boolean success) {
        Intent intent = new Intent(FINISHED).putExtra(EXTENDED_SUCCESS, success);
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }
}