Java tutorial
/* * 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.apache.commons.io.IOUtils; import org.greenrobot.eventbus.EventBus; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.URL; import java.util.ArrayList; import java.util.List; 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 eu.codeplumbers.cosi.utils.FileUtils; import static eu.codeplumbers.cosi.utils.Constants.REFRESH; import static eu.codeplumbers.cosi.utils.Constants.SERVICE_ERROR; import static eu.codeplumbers.cosi.utils.Constants.SYNC_MESSAGE; /** * Created by thor on 10/29/16. */ public class CosiFileService extends IntentService { private List<File> allFiles; private String errorMessage; private String authHeader; private String folderUrl; private String fileUrl; private int notification_id = 1340; private NotificationManager mNotifyManager; private NotificationCompat.Builder mBuilder; private boolean mSyncRunning; private boolean stopSync; public CosiFileService() { super("CosiFileService"); stopSync = false; mSyncRunning = false; } public CosiFileService(String name) { super(name); } @Override protected void onHandleIntent(Intent intent) { // Do the task here Log.i(CosiFileService.class.getName(), "Cosi Service running"); // Release the wake lock provided by the WakefulBroadcastReceiver. WakefulBroadcastReceiver.completeWakefulIntent(intent); allFiles = new ArrayList<>(); Device device = Device.registeredDevice(); // cozy register device url folderUrl = device.getUrl() + "/ds-api/request/folder/cosiall/"; fileUrl = device.getUrl() + "/ds-api/request/file/cosiall/"; // 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 { // read local sms log first getAllRemoteFolders(); getAllRemoteFiles(); mBuilder.setContentText(getString(R.string.lbl_sms_sync_done)); mBuilder.setProgress(0, 0, false); mNotifyManager.notify(notification_id, mBuilder.build()); if (!allFiles.isEmpty()) { mNotifyManager.cancel(notification_id); EventBus.getDefault().post(new FileSyncEvent(REFRESH, "Sync OK")); } else { EventBus.getDefault().post(new FileSyncEvent(SERVICE_ERROR, "Sync failed")); } } 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 void getAllRemoteFiles() { URL urlO = null; try { urlO = new URL(fileUrl); 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("POST"); // read the response int status = conn.getResponseCode(); InputStream in = null; if (status >= HttpURLConnection.HTTP_BAD_REQUEST) { in = conn.getErrorStream(); } else { in = conn.getInputStream(); } StringWriter writer = new StringWriter(); IOUtils.copy(in, writer, "UTF-8"); String result = writer.toString(); JSONArray jsonArray = new JSONArray(result); if (jsonArray != null) { for (int i = 0; i < jsonArray.length(); i++) { JSONObject fileJson = jsonArray.getJSONObject(i).getJSONObject("value"); File file = File.getByRemoteId(fileJson.get("_id").toString()); if (file == null) { file = new File(fileJson, false); } else { file.setName(fileJson.getString("name")); file.setPath(fileJson.getString("path")); file.setCreationDate(fileJson.getString("creationDate")); file.setLastModification(fileJson.getString("lastModification")); file.setTags(fileJson.getString("tags")); if (fileJson.has("binary")) { file.setBinary(fileJson.getJSONObject("binary").toString()); } file.setIsFile(true); file.setFileClass(fileJson.getString("class")); file.setMimeType(fileJson.getString("mime")); file.setSize(fileJson.getLong("size")); } mBuilder.setProgress(jsonArray.length(), i, false); mBuilder.setContentText("Indexing file : " + file.getName()); mNotifyManager.notify(notification_id, mBuilder.build()); EventBus.getDefault() .post(new FileSyncEvent(SYNC_MESSAGE, "Indexing file : " + file.getName())); file.setDownloaded(FileUtils.checkFileExists(Environment.getExternalStorageDirectory() + java.io.File.separator + Constants.APP_DIRECTORY + java.io.File.separator + "files" + file.getPath() + "/" + file.getName())); file.save(); allFiles.add(file); } } else { EventBus.getDefault() .post(new FileSyncEvent(SERVICE_ERROR, new JSONObject(result).getString("error"))); mNotifyManager.notify(notification_id, mBuilder.build()); stopSelf(); } in.close(); conn.disconnect(); } catch (MalformedURLException e) { e.printStackTrace(); EventBus.getDefault().post(new FileSyncEvent(SERVICE_ERROR, e.getLocalizedMessage())); stopSelf(); } catch (ProtocolException e) { e.printStackTrace(); EventBus.getDefault().post(new FileSyncEvent(SERVICE_ERROR, e.getLocalizedMessage())); stopSelf(); } catch (IOException e) { e.printStackTrace(); EventBus.getDefault().post(new FileSyncEvent(SERVICE_ERROR, e.getLocalizedMessage())); stopSelf(); } catch (JSONException e) { e.printStackTrace(); EventBus.getDefault().post(new FileSyncEvent(SERVICE_ERROR, e.getLocalizedMessage())); stopSelf(); } } private void getAllRemoteFolders() { //File.deleteAllFolders(); URL urlO = null; try { urlO = new URL(folderUrl); 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("POST"); // read the response int status = conn.getResponseCode(); InputStream in = null; if (status >= HttpURLConnection.HTTP_BAD_REQUEST) { in = conn.getErrorStream(); } else { in = conn.getInputStream(); } StringWriter writer = new StringWriter(); IOUtils.copy(in, writer, "UTF-8"); String result = writer.toString(); JSONArray jsonArray = new JSONArray(result); if (jsonArray != null) { for (int i = 0; i < jsonArray.length(); i++) { JSONObject folderJson = jsonArray.getJSONObject(i).getJSONObject("value"); File file = File.getByRemoteId(folderJson.get("_id").toString()); if (file == null) { file = new File(folderJson, true); } else { file.setName(folderJson.getString("name")); file.setPath(folderJson.getString("path")); file.setCreationDate(folderJson.getString("creationDate")); file.setLastModification(folderJson.getString("lastModification")); file.setTags(folderJson.getString("tags")); } mBuilder.setProgress(jsonArray.length(), i, false); mBuilder.setContentText("Indexing remote folder : " + file.getName()); mNotifyManager.notify(notification_id, mBuilder.build()); EventBus.getDefault() .post(new FileSyncEvent(SYNC_MESSAGE, "Indexing remote folder : " + file.getName())); file.save(); createFolder(file.getPath(), file.getName()); allFiles.add(file); } } else { EventBus.getDefault().post(new FileSyncEvent(SERVICE_ERROR, "Failed to parse API response")); stopSelf(); } in.close(); conn.disconnect(); } catch (MalformedURLException e) { e.printStackTrace(); EventBus.getDefault().post(new FileSyncEvent(SERVICE_ERROR, e.getLocalizedMessage())); stopSelf(); } catch (ProtocolException e) { e.printStackTrace(); EventBus.getDefault().post(new FileSyncEvent(SERVICE_ERROR, e.getLocalizedMessage())); stopSelf(); } catch (IOException e) { e.printStackTrace(); EventBus.getDefault().post(new FileSyncEvent(SERVICE_ERROR, e.getLocalizedMessage())); stopSelf(); } catch (JSONException e) { e.printStackTrace(); EventBus.getDefault().post(new FileSyncEvent(SERVICE_ERROR, e.getLocalizedMessage())); stopSelf(); } } private void createFolder(String path, String folderName) { java.io.File dir = new java.io.File( Environment.getExternalStorageDirectory() + java.io.File.separator + Constants.APP_DIRECTORY + java.io.File.separator + "files" + (path.equals("") ? "/" : path + "/") + folderName); if (!dir.exists()) { Log.d("Cosi", "Creating folder:" + dir.getAbsolutePath()); dir.mkdirs(); } } private boolean isNetworkAvailable() { ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService( Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); return activeNetworkInfo != null && activeNetworkInfo.isConnected(); } public void showNotification() { mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); mBuilder = new NotificationCompat.Builder(this); mBuilder.setContentTitle(getString(R.string.lbl_files)) .setContentText(getString(R.string.lbl_notes_ongoing_sync)) .setSmallIcon(R.drawable.ic_call_black_24dp).setOngoing(true); } }