Android Open Source - dejalist Backup Intent Service






From Project

Back to project page dejalist.

License

The source code is released under:

Apache License

If you think the Android project dejalist listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.luboganev.dejalist.data;
//from   w w w. j ava2s .  com
import static nl.qbusict.cupboard.CupboardFactory.cupboard;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import nl.qbusict.cupboard.QueryResultIterable;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.luboganev.dejalist.R;
import com.luboganev.dejalist.data.DejalistContract.Categories;
import com.luboganev.dejalist.data.DejalistContract.Products;
import com.luboganev.dejalist.data.entities.Category;
import com.luboganev.dejalist.data.entities.Product;

import android.app.IntentService;
import android.app.NotificationManager;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.support.v4.app.NotificationCompat;

public class BackupIntentService extends IntentService {
  private static final String SERVICE_NAME = "BackupRestoreService";
  public static final String INTENT_EXTRA_ACTION = "action";
  private static final int NOTIFICATION_ID = 42; // The answer to everything
  public static enum Action {BACKUP, RESTORE}; 
  
  private static final String BACKUP_FOLDER_NAME = "DejalistBackup";
  private static final String BACKUP_FOLDER_NOMEDIA = ".nomedia";
  private static final String BACKUP_METADATA_FILE_NAME = "data.txt";
  
  private static final String CATEGORY_BACKUP_PRODUCTS_JSON = "products";
  private static final String PRODUCT_IMAGE_FILENAME = "image_filename";
  
  private JSONArray mData;
  private List<File> mProductImageFiles;
  private NotificationManager mNotifManager;
  private NotificationCompat.Builder mNotifBuilder;
  private String mErrorString = "";
  
  public BackupIntentService() {
    super(SERVICE_NAME);
  }
  
  @Override
  public void onCreate() {
    super.onCreate();
    mNotifManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
  }
  
  @Override
  protected void onHandleIntent(Intent intent) {
    Action receivedAction = (Action)intent.getSerializableExtra(INTENT_EXTRA_ACTION);
    mNotifBuilder = new NotificationCompat.Builder(getApplicationContext())
      .setSmallIcon(R.drawable.ic_stat_backup_restore);
    switch (receivedAction) {
    case BACKUP:
      mNotifBuilder.setContentTitle(getString(R.string.backup_notif_title))
        .setContentText(getString(R.string.backup_notif_text));
      mNotifBuilder.setProgress(0, 0, true);
      mNotifManager.notify(NOTIFICATION_ID, mNotifBuilder.build());
      if(backup()) mNotifBuilder.setContentText(getString(R.string.backup_notif_text_finished));
      else mNotifBuilder.setContentTitle(getString(R.string.backup_notif_title_failed))
          .setContentText(mErrorString);
      mNotifBuilder.setProgress(0,0,false);
            mNotifManager.notify(NOTIFICATION_ID, mNotifBuilder.build());
      break;
    case RESTORE:
      mNotifBuilder.setContentTitle(getString(R.string.restore_notif_title))
      .setContentText(getString(R.string.restore_notif_text));
      mNotifBuilder.setProgress(0, 0, true);
      mNotifManager.notify(NOTIFICATION_ID, mNotifBuilder.build());
      if(restore()) mNotifBuilder.setContentText(getString(R.string.restore_notif_text_finished));
      else mNotifBuilder.setContentTitle(getString(R.string.restore_notif_title_failed))
          .setContentText(mErrorString);
      mNotifBuilder.setProgress(0,0,false);
            mNotifManager.notify(NOTIFICATION_ID, mNotifBuilder.build());
      break;
    default:
      // do nothing
      break;
    }
  }
  
  private static File getBackupDir() {
    File backupDir = new File(Environment.getExternalStorageDirectory() + File.separator + BACKUP_FOLDER_NAME);
    if(!backupDir.exists()) backupDir.mkdir();
    return backupDir;
  }
  
  /* ------------------------------------- BACKUP ------------------------------------------ */
  
  private boolean clearBackupFolder() {
    File backupDir = getBackupDir();
    if(!backupDir.exists() || !backupDir.isDirectory()) {
      mErrorString = getString(R.string.br_error_backup_folder_cannot_create);
      return false;
    }
    for(File file: backupDir.listFiles()) file.delete();
    File nomedia = new File(backupDir, BACKUP_FOLDER_NOMEDIA);
    try {
      nomedia.createNewFile();
    } catch (IOException e) {
      mErrorString = getString(R.string.br_error_backup_folder_nomedia_create);
      return false;
    }
    return true;
  }
  
  private static Category getNoCategory() {
    Category cat = new Category();
    cat._id = Products.PRODUCT_CATEGORY_NONE_ID;
    cat.name = "";
    cat.color = 0;
    return cat;
  }
  
  private boolean backupCategoryWithProducts(Context context, Category category, JSONArray container, List<File> imageFilesContainer) {
    // backup the category
    JSONArray productsContainer = backupCategory(category, container);
    if(productsContainer == null) {
      return false;
    }
    // Get products with in this category
    QueryResultIterable<Product> productsItr = null;
    if(category._id == Products.PRODUCT_CATEGORY_NONE_ID) {
      productsItr = cupboard().withContext(context).query(Products.CONTENT_URI, Product.class).withSelection(Products.SELECTION_NO_CATEGORY, (String[])null).query();
    }
    else productsItr = cupboard().withContext(context).query(Products.buildCategoryProductsUri(category._id), Product.class).query();
    for (Product p : productsItr) {
      // backup each product in this category
      if(!backupProduct(p, productsContainer, imageFilesContainer)) {
        productsItr.close();
        return false;
      }
    }
    productsItr.close();
    return true;
  }
  
  private JSONArray backupCategory(Category category, JSONArray container) {
    JSONObject obj = new JSONObject();
    JSONArray productsContainer = new JSONArray();
    try {
      obj.put(DejalistContract.Categories._ID, category._id);
      obj.put(DejalistContract.Categories.CATEGORY_NAME, category.name);
      obj.put(DejalistContract.Categories.CATEGORY_COLOR, category.color);
      
      // json array with all products that belong to this category
      obj.put(CATEGORY_BACKUP_PRODUCTS_JSON, productsContainer);
      
      // add to the json array with categories
      container.put(obj);
    } catch (JSONException e) {
      mErrorString = getString(R.string.br_error_backup_json_category);
      return null;
    }
    return productsContainer;
  }
  
  private boolean backupProduct(Product product, JSONArray container, List<File> imageFilesContainer) {
    JSONObject obj = new JSONObject();
    try {
      obj.put(DejalistContract.Products.PRODUCT_NAME, product.name);
      obj.put(DejalistContract.Products.PRODUCT_USED_COUNT, product.usedCount);
      obj.put(DejalistContract.Products.PRODUCT_LAST_USED, product.lastUsed);
      if(product.uri != null) {
        File imageFile = new File(Uri.parse(product.uri).getPath());
        obj.put(PRODUCT_IMAGE_FILENAME, imageFile.getName());
        imageFilesContainer.add(imageFile);
      }
      // add to the json array with products
      container.put(obj);
    } catch (JSONException e) {
      mErrorString = getString(R.string.br_error_backup_json_product);
      return false;
    }
    return true;
  }
  
  private boolean writeBackup(File backupDir) {
    // validate backup dir
    if(!backupDir.exists() || !backupDir.isDirectory()) {
      mErrorString = getString(R.string.br_error_backup_folder_cannot_create);
      return false;
    }
    
    // backup the data file
    File productsFile = new File(backupDir, BACKUP_METADATA_FILE_NAME);
    FileOutputStream fos = null;
    try {
      productsFile.createNewFile();
      fos = new FileOutputStream(productsFile);
      fos.write(mData.toString().getBytes());
      fos.close();
    } catch (IOException e) {
      mErrorString = getString(R.string.br_error_saving_backup);
      if(fos != null) {
        try { fos.close(); } catch (IOException e1) {}
      }
      return false;
    }
    
    // backup the product images files
    for (File productImage : mProductImageFiles) {
      // backup the image file
      File backupProductFile = new File(backupDir, productImage.getName());
      try {
        backupProductFile.createNewFile();
      } catch (IOException e) {
        mErrorString = getString(R.string.br_error_saving_images);
        return false;
      }
      if(!ProductImageFileHelper.copy(productImage, backupProductFile)) {
        mErrorString = getString(R.string.br_error_saving_images);
        return false;
      }
    }
    return true;
  }
  
  private boolean backup() {
    // clear up and init
    clearBackupFolder();
    mData = new JSONArray();
    mProductImageFiles = new ArrayList<File>();
    
    // first add the products with no category to backup
    Category noCategory = getNoCategory();
    backupCategoryWithProducts(getApplicationContext(), noCategory, mData, mProductImageFiles);
    
    // now add all the real categories and their products
    QueryResultIterable<Category> categoriesItr = cupboard().withContext(getApplicationContext()).query(Categories.CONTENT_URI, Category.class).query();
    for (Category category : categoriesItr) {
      backupCategoryWithProducts(getApplicationContext(), category, mData, mProductImageFiles);
    }
    categoriesItr.close();
    
    // write the backup files
    return writeBackup(getBackupDir());
  }
  
  /* ------------------------------------- RESTORE ----------------------------------------- */
  
  private boolean restore() {
    JSONArray backupData = readJsonArrayFile(new File(getBackupDir(), BACKUP_METADATA_FILE_NAME));
    if(backupData == null) return false;
    
    JSONObject categoryJson = null;
    for (int i = 0; i < backupData.length(); i++) {
      try { categoryJson = backupData.getJSONObject(i); } 
      catch (JSONException e) { 
        mErrorString = getString(R.string.br_error_restore_json_data);
        return false;
      }
      if(!restoreCategoryWithProducts(getApplicationContext(), categoryJson)) return false;
    }
    
    return true;
  }
  
  private boolean restoreProducts(Context context, JSONArray productsContainer, long categoryId) {
    for (int i = 0; i < productsContainer.length(); i++) {
      try { 
        JSONObject productJson = productsContainer.getJSONObject(i); 
        
        // Check if the same product already exists
        // In case the existing product has no image, we import the one from the backup (if it exists)
        SelectionBuilder productSelection = new SelectionBuilder();
        productSelection.where(Products.SELECTION_NAME, Products.buildNameSelectionArgs(productJson.getString(DejalistContract.Products.PRODUCT_NAME)))
        .where(Products.SELECTION_CATEGORY_ID, Products.buildCategoryIdSelectionArgs(categoryId));
        
        Product existingProduct = cupboard().withContext(context).query(Products.CONTENT_URI, Product.class)
            .withSelection(productSelection.getSelection(), productSelection.getSelectionArgs())
            .query().get();
        
        if(existingProduct != null) {
          // We have same product, see if it needs an image
          if(existingProduct.uri == null && productJson.has(PRODUCT_IMAGE_FILENAME)) {
            // existing product has no image but imported one does, 
            // then we just update the existing product with the image
            String importedFile = importImageFile(context, productJson.getString(PRODUCT_IMAGE_FILENAME));
            if(importedFile == null) return false; //error occurred
            else if(importedFile.length() > 0) { // something was wrong and the backup image was not found
              // if the new image file was imported
              ContentValues values = new ContentValues(1);
              values.put(Products.PRODUCT_URI, importedFile);
              getContentResolver().update(Products.buildProductUri(existingProduct._id), values, null, null);
            }
          }
        }
        else {
          Product p = new Product();
          p.categoryId = categoryId;
          p.name = productJson.getString(DejalistContract.Products.PRODUCT_NAME);
          p.usedCount = productJson.getInt(DejalistContract.Products.PRODUCT_USED_COUNT);
          p.lastUsed = productJson.getLong(DejalistContract.Products.PRODUCT_LAST_USED);
          
          if(productJson.has(PRODUCT_IMAGE_FILENAME)) {
            String importedFile = importImageFile(context, productJson.getString(PRODUCT_IMAGE_FILENAME));
            if(importedFile == null) return false;
            else if(importedFile.length() > 0) p.uri = importedFile;
          }
          cupboard().withContext(context).put(Products.CONTENT_URI, p);
        }
      } 
      catch (JSONException e) { 
        mErrorString = getString(R.string.br_error_restore_json_product);
        return false;
      }
    }
    return true;
  }
  
  /**
   * Imports an image from backup to internal storage
   * and renames it if a file with its name already exists  
   * 
   * @param context
   *     Needs context to be able to reach the needed folders    
   * @param filename
   *     The file name of the imported image
   * @return
   *     The String of the Uri of the imported image file. Null if there was error. 
   *     Empty string if there was no file with the input filename found 
   */
  private String importImageFile(Context context, String filename) {
    File backupImageFile = new File(getBackupDir(), filename);
    if(backupImageFile.exists()) {
      File internalFile = ProductImageFileHelper.getFile(context, filename);
      try {
        int uniqueFileSuffix = 0;
        while(internalFile.exists()) {
          uniqueFileSuffix++;
          internalFile = ProductImageFileHelper.getFile(context, filename + "_" + uniqueFileSuffix);
        }
        internalFile.createNewFile();
      } catch (IOException e) {
        mErrorString = getString(R.string.br_error_import_images);
        return null;
      }
      ProductImageFileHelper.copy(backupImageFile, internalFile);
      return Uri.fromFile(internalFile).toString();
    }
    return "";
  }
  
  private boolean restoreCategoryWithProducts(Context context, JSONObject categoryJson) {
    // get category data
    try {
      Category category = new Category();
      category.name = categoryJson.getString(DejalistContract.Categories.CATEGORY_NAME);
      category.color = categoryJson.getInt(DejalistContract.Categories.CATEGORY_COLOR);
      if(categoryJson.getLong(DejalistContract.Categories._ID) != Products.PRODUCT_CATEGORY_NONE_ID) {
        // Check if exactly the same category already exists
        SelectionBuilder categorySelection = new SelectionBuilder();
        categorySelection.where(Categories.SELECTION_NAME, Categories.buildNameSelectionArgs(category.name))
        .where(Categories.SELECTION_COLOR, Categories.buildColorSelectionArgs(category.color));
        
        Category foundCategory = cupboard().withContext(context).query(Categories.CONTENT_URI, Category.class)
            .withSelection(categorySelection.getSelection(), categorySelection.getSelectionArgs())
            .query().get();
        
        if(foundCategory != null) {
          // If there is the same category found, do not re-insert it and import products under it
          category._id = foundCategory._id;
        }
        else
        {
          // insert the category and get its id
          Uri insertUri = cupboard().withContext(context).put(Categories.CONTENT_URI, category);
          category._id = Categories.getCategoryId(insertUri);
        }
      }
      else category._id = Products.PRODUCT_CATEGORY_NONE_ID;
      restoreProducts(context, categoryJson.getJSONArray(CATEGORY_BACKUP_PRODUCTS_JSON), category._id);
    } catch (JSONException e) {
      mErrorString = getString(R.string.br_error_restore_json_category);
      return false;
    }
    return true;
  }
  
  private JSONArray readJsonArrayFile(File file) {
    try{
          FileInputStream fis = new FileInputStream(file);
          StringBuilder sb = new StringBuilder();
        {
            int rc = 0;
            while((rc = fis.read()) >= 0)
            {
                sb.append((char) rc);
            }
        }
        fis.close();
          return new JSONArray(sb.toString());
      }
      catch(JSONException e) {
        mErrorString = getString(R.string.br_error_restore_json_data);
          return null;
      }
      catch(IOException e) {
        mErrorString = getString(R.string.br_error_restore_file_data);
          return null;
      }
  }
}




Java Source Code List

com.larswerkman.colorpicker.ColorPicker.java
com.larswerkman.colorpicker.OpacityBar.java
com.larswerkman.colorpicker.SVBar.java
com.larswerkman.colorpicker.SaturationBar.java
com.larswerkman.colorpicker.ValueBar.java
com.luboganev.dejalist.Utils.java
com.luboganev.dejalist.crop.CropActivity.java
com.luboganev.dejalist.crop.CropDialogSave.java
com.luboganev.dejalist.crop.CropHighlightView.java
com.luboganev.dejalist.crop.CropUtils.java
com.luboganev.dejalist.crop.CropView.java
com.luboganev.dejalist.crop.ImageViewTouchBase.java
com.luboganev.dejalist.crop.RotateBitmap.java
com.luboganev.dejalist.data.BackupIntentService.java
com.luboganev.dejalist.data.CacheManager.java
com.luboganev.dejalist.data.DejalistContract.java
com.luboganev.dejalist.data.DejalistDatabase.java
com.luboganev.dejalist.data.DejalistProvider.java
com.luboganev.dejalist.data.ProductImageFileHelper.java
com.luboganev.dejalist.data.SelectionBuilder.java
com.luboganev.dejalist.data.entities.Category.java
com.luboganev.dejalist.data.entities.Product.java
com.luboganev.dejalist.ui.AboutActivity.java
com.luboganev.dejalist.ui.CategoriesListCursorAdapter$ViewHolder$$ViewInjector.java
com.luboganev.dejalist.ui.CategoriesListCursorAdapter.java
com.luboganev.dejalist.ui.CategoryDialogFragment$$ViewInjector.java
com.luboganev.dejalist.ui.CategoryDialogFragment.java
com.luboganev.dejalist.ui.CheckableRelativeLayout.java
com.luboganev.dejalist.ui.ChecklistActionTaker.java
com.luboganev.dejalist.ui.ChecklistController.java
com.luboganev.dejalist.ui.ChecklistCursorAdapter$ViewHolder$$ViewInjector.java
com.luboganev.dejalist.ui.ChecklistCursorAdapter.java
com.luboganev.dejalist.ui.ChecklistFragment$$ViewInjector.java
com.luboganev.dejalist.ui.ChecklistFragment.java
com.luboganev.dejalist.ui.ConfirmBackResDialogFragment.java
com.luboganev.dejalist.ui.MainActivity$$ViewInjector.java
com.luboganev.dejalist.ui.MainActivity.java
com.luboganev.dejalist.ui.NavigationCursorAdapter$ViewHolder$$ViewInjector.java
com.luboganev.dejalist.ui.NavigationCursorAdapter.java
com.luboganev.dejalist.ui.ProductActivity$$ViewInjector.java
com.luboganev.dejalist.ui.ProductActivity.java
com.luboganev.dejalist.ui.ProductsGalleryActionTaker.java
com.luboganev.dejalist.ui.ProductsGalleryController.java
com.luboganev.dejalist.ui.ProductsGalleryCursorAdapter$ViewHolder$$ViewInjector.java
com.luboganev.dejalist.ui.ProductsGalleryCursorAdapter.java
com.luboganev.dejalist.ui.ProductsGalleryFragment$$ViewInjector.java
com.luboganev.dejalist.ui.ProductsGalleryFragment.java
com.luboganev.dejalist.ui.SetProductsCategoryDialogFragment.java
com.luboganev.dejalist.ui.UndoBarController.java