com.armtimes.downloaders.ArticleInfoDownloaderService.java Source code

Java tutorial

Introduction

Here is the source code for com.armtimes.downloaders.ArticleInfoDownloaderService.java

Source

/*
 * Copyright (C) 2015 Victor Apoyan.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.armtimes.downloaders;

import android.app.Service;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

import com.armtimes.database.NewsContract;
import com.armtimes.database.NewsDatabaseHelper;
import com.armtimes.drawer.CommonFragment;
import com.armtimes.utils.Logger;
import com.armtimes.utils.Utils;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public final class ArticleInfoDownloaderService extends Service
        implements ArticleInfoDownloader.ArticleInfoDownloaderListener {

    private final static String TAG = ArticleInfoDownloaderService.class.getSimpleName();

    public final static String EXTRA_CATEGORY = "CATEGORY";

    private ExecutorService mExecutor = null;
    private NewsDatabaseHelper mDatabaseHelper = null;
    private SQLiteDatabase mDatabase = null;

    @Override
    public void onCreate() {
        super.onCreate();

        mDatabaseHelper = new NewsDatabaseHelper(getApplicationContext());
        // Open database that will be used for reading and writing.
        mDatabase = mDatabaseHelper.getWritableDatabase();
        mExecutor = Executors.newSingleThreadExecutor();

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        int result = START_STICKY;
        // If there are not any pending start commands to be delivered
        // to the service, it will be called with a null intent object
        if (intent == null) {
            //          Logger.t(getApplicationContext(), "onStartCommand", "No any pending start commands!", "#8BC34A");
            return result;
        }
        final String category = intent.getStringExtra(EXTRA_CATEGORY);

        mExecutor.execute(new QueryDatabaseAsync(category));

        return result;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        // Clean-up ...
        if (mExecutor != null)
            mExecutor.shutdown();
        if (mDatabase != null && mDatabase.isOpen())
            mDatabase.close();
        if (mDatabaseHelper != null)
            mDatabaseHelper.close();

        super.onDestroy();
    }

    @Override
    public void onDownloadCompleted(Set<ArticleInfo> articleInfoSet, String tableName) {
        if (articleInfoSet != null) {
            for (ArticleInfo articleInfo : articleInfoSet) {
                if (articleInfo.processed) {
                    // Update single item info in database.
                    ContentValues cv = new ContentValues();
                    cv.put(NewsContract.COL_NAME_NEWS_DESC_LONG, articleInfo.description);
                    cv.put(NewsContract.COL_NAME_NEWS_IMAGE_URL, articleInfo.imageLink);
                    cv.put(NewsContract.COL_NAME_NEWS_IMAGE_PATH, articleInfo.thumbnailImagePath);
                    mDatabase.update(tableName.toUpperCase(), cv,
                            String.format("%s=\"%s\"", NewsContract.COL_NAME_NEWS_URL, articleInfo.url), null);
                }
            }

            // Notify that current portion of items were downloaded.
            Intent intent = new Intent("event-downloaded");
            intent.putExtra(CommonFragment.EXTRA_CATEGORY, tableName);
            LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
        }

        // Check if all tasks are done close service.
        if (ArticleInfoDownloader.workDone()) {
            // Create Intent for broadcast receiver in order to
            // notify that all data were downloaded.
            Intent intent = new Intent("event-downloaded");
            intent.putExtra(CommonFragment.EXTRA_CATEGORY, "all");
            LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

            stopSelf();
        }
    }

    /**
     *
     */
    final class QueryDatabaseAsync implements Runnable {

        private final static String QUERY_SELECT_ALL_DESC = "SELECT * FROM %s ORDER BY %s DESC";

        private final String mCategory;
        private final Set<ArticleInfo> mArticleInfoSet;
        private final String mQueryString;

        private QueryDatabaseAsync(final String category) {
            mCategory = category;
            mArticleInfoSet = new HashSet<>();
            mQueryString = String.format(QUERY_SELECT_ALL_DESC, mCategory.toUpperCase(),
                    NewsContract.COL_NAME_NEWS_DATE);
        }

        @Override
        public void run() {
            if (mDatabase == null) {
                Logger.e(TAG, "Database is null!");
                return;
            }

            Cursor cursor = mDatabase.rawQuery(mQueryString, null);
            if (cursor != null && cursor.getCount() > 0) {
                while (cursor.moveToNext()) {
                    final String url = cursor
                            .getString(cursor.getColumnIndexOrThrow(NewsContract.COL_NAME_NEWS_URL));
                    final String description = cursor
                            .getString(cursor.getColumnIndexOrThrow(NewsContract.COL_NAME_NEWS_DESC_LONG));
                    final String imageLink = cursor
                            .getString(cursor.getColumnIndexOrThrow(NewsContract.COL_NAME_NEWS_IMAGE_URL));

                    ArticleInfo articleInfo = new ArticleInfo(url, description, imageLink);
                    if (!articleInfo.hasAllData()
                            || !Utils.thumbnailImageExistsOnDisk(getApplicationContext(), imageLink))
                        mArticleInfoSet.add(articleInfo);
                }
                cursor.close();
            }

            Logger.d(TAG,
                    String.format(
                            "All information were queried from database for %s. " + "Total items count is: %d",
                            mCategory, mArticleInfoSet.size()));

            ArticleInfoDownloader.startDownloading(getApplicationContext(), mCategory,
                    ArticleInfoDownloaderService.this, mArticleInfoSet);
        }
    }
}