eu.codeplumbers.cosi.services.CosiFileDownloadService.java Source code

Java tutorial

Introduction

Here is the source code for eu.codeplumbers.cosi.services.CosiFileDownloadService.java

Source

/*
 *     Cos android client for Cozy Cloud
 *
 *     Copyright (C)  2016 Hamza Abdelkebir
 *
 *     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 eu.codeplumbers.cosi.services;

import android.app.IntentService;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Environment;
import android.support.v4.content.WakefulBroadcastReceiver;
import android.support.v7.app.NotificationCompat;
import android.util.Base64;
import android.util.Log;

import org.greenrobot.eventbus.EventBus;

import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.ArrayList;

import eu.codeplumbers.cosi.R;
import eu.codeplumbers.cosi.db.models.Device;
import eu.codeplumbers.cosi.db.models.File;
import eu.codeplumbers.cosi.services.events.FileSyncEvent;
import eu.codeplumbers.cosi.utils.Constants;

import static eu.codeplumbers.cosi.utils.Constants.REFRESH;
import static eu.codeplumbers.cosi.utils.Constants.SERVICE_ERROR;

/**
 * Created by thor on 10/29/16.
 */

public class CosiFileDownloadService extends IntentService {

    private String authHeader;
    private String fileUrl;

    private int notification_id = 1340;
    private NotificationManager mNotifyManager;
    private NotificationCompat.Builder mBuilder;
    private boolean mSyncRunning;
    private boolean stopSync;

    public CosiFileDownloadService() {
        super("CosiFileDownloadService");

        mSyncRunning = false;
    }

    public CosiFileDownloadService(String name) {
        super(name);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        // Do the task here
        Log.i(CosiFileDownloadService.class.getName(), "Cosi Service running");

        // Release the wake lock provided by the WakefulBroadcastReceiver.
        WakefulBroadcastReceiver.completeWakefulIntent(intent);

        Device device = Device.registeredDevice();

        // cozy register device url
        fileUrl = device.getUrl() + "/ds-api/data/";

        // concatenate username and password with colon for authentication
        final String credentials = device.getLogin() + ":" + device.getPassword();
        authHeader = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);

        showNotification();

        if (isNetworkAvailable()) {
            try {

                ArrayList<String> fileStrings = intent.getStringArrayListExtra("fileToDownload");

                for (int i = 0; i < fileStrings.size(); i++) {
                    File file = File.load(File.class, Long.valueOf(fileStrings.get(i)));
                    String binaryRemoteId = file.getRemoteId();

                    if (!binaryRemoteId.isEmpty()) {
                        mBuilder.setProgress(100, 0, false);
                        mBuilder.setContentText("Downloading file: " + file.getName());
                        mNotifyManager.notify(notification_id, mBuilder.build());

                        URL urlO = null;
                        try {
                            urlO = new URL(fileUrl + binaryRemoteId + "/binaries/file");
                            HttpURLConnection conn = (HttpURLConnection) urlO.openConnection();
                            conn.setConnectTimeout(5000);
                            conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
                            conn.setRequestProperty("Authorization", authHeader);
                            conn.setDoInput(true);
                            conn.setRequestMethod("GET");

                            conn.connect();
                            int lenghtOfFile = conn.getContentLength();

                            // read the response
                            int status = conn.getResponseCode();

                            if (status >= HttpURLConnection.HTTP_BAD_REQUEST) {
                                EventBus.getDefault()
                                        .post(new FileSyncEvent(SERVICE_ERROR, conn.getResponseMessage()));
                                stopSelf();
                            } else {
                                int count = 0;
                                InputStream in = new BufferedInputStream(conn.getInputStream(), 8192);

                                java.io.File newFile = file.getLocalPath();

                                if (!newFile.exists()) {
                                    newFile.createNewFile();
                                }

                                // Output stream to write file
                                OutputStream output = new FileOutputStream(Environment.getExternalStorageDirectory()
                                        + java.io.File.separator + Constants.APP_DIRECTORY + java.io.File.separator
                                        + "files" + file.getPath() + "/" + file.getName());

                                byte data[] = new byte[1024];
                                long total = 0;
                                while ((count = in.read(data)) != -1) {
                                    total += count;

                                    mBuilder.setProgress(lenghtOfFile, (int) total, false);
                                    mBuilder.setContentText("Downloading file: " + file.getName());
                                    mNotifyManager.notify(notification_id, mBuilder.build());

                                    // writing data to file
                                    output.write(data, 0, count);
                                }

                                // flushing output
                                output.flush();

                                // closing streams
                                output.close();
                                in.close();

                                file.setDownloaded(true);
                                file.save();
                            }
                        } catch (MalformedURLException e) {
                            EventBus.getDefault().post(new FileSyncEvent(SERVICE_ERROR, e.getLocalizedMessage()));
                            stopSelf();
                        } catch (ProtocolException e) {
                            EventBus.getDefault().post(new FileSyncEvent(SERVICE_ERROR, e.getLocalizedMessage()));
                            stopSelf();
                        } catch (IOException e) {
                            EventBus.getDefault().post(new FileSyncEvent(SERVICE_ERROR, e.getLocalizedMessage()));
                            stopSelf();
                        }
                    }
                }

                mNotifyManager.cancel(notification_id);
                EventBus.getDefault().post(new FileSyncEvent(REFRESH, "Sync OK"));
            } catch (Exception e) {
                e.printStackTrace();
                mSyncRunning = false;
                EventBus.getDefault().post(new FileSyncEvent(SERVICE_ERROR, e.getLocalizedMessage()));
            }
        } else {
            mSyncRunning = false;
            EventBus.getDefault().post(new FileSyncEvent(SERVICE_ERROR, "No Internet connection"));
            mBuilder.setContentText("Sync failed because no Internet connection was available");
            mNotifyManager.notify(notification_id, mBuilder.build());
        }
    }

    private boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(
                Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
    }

    public void showNotification() {
        //PendingIntent pendingIntent = PendingIntent.getActivity(this, notification_id, this,PendingIntent.FLAG_UPDATE_CURRENT);

        mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        mBuilder = new NotificationCompat.Builder(this);
        mBuilder.setContentTitle(getString(R.string.lbl_files))
                .setContentText(getString(R.string.lbl_files_downloading)).setSmallIcon(R.drawable.ic_fa_file)
                //.addAction(R.drawable.ic_action_cancel, "Dismiss", getPendingIntent())
                .setOngoing(true);
    }
}