public class Article implements Serializable, Parcelable {

    private final static long serialVersionUID = 8755682695955568073L;
    public final Parcelable.Creator<Article> CREATOR = new Parcelable.Creator<Article>() {
        @Override
        public Article createFromParcel(Parcel parcel) {
            return new Article(parcel);
        }

        @Override
        public Article[] newArray(int i) {
            return new Article[i];
        }

    };
    @SerializedName("author")
    private String author;
    @SerializedName("title")
    private String title;
    @SerializedName("description")
    private String description;
    @SerializedName("url")
    private String url;
    @SerializedName("urlToImage")
    private String urlToImage;
    @SerializedName("publishedAt")
    private String publishedAt;

    public Article(String mTitle, String mAuthor, String mDescription, String mUrl, String mUrlToImage, String mPublishedAt) {
        this.title = mTitle;
        this.author = mAuthor;
        this.description = mDescription;
        this.url = mUrl;
        this.urlToImage = mUrlToImage;
        this.publishedAt = mPublishedAt;
    }


    private Article(Parcel in) {
        this.author = in.readString();
        this.title = in.readString();
        this.description = in.readString();
        this.url = in.readString();
        this.urlToImage = in.readString();
        this.publishedAt = in.readString();
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUrlToImage() {
        return urlToImage;
    }

    public void setUrlToImage(String urlToImage) {
        this.urlToImage = urlToImage;
    }

    public String getPublishedAt() {
        return publishedAt;
    }

    public void setPublishedAt(String publishedAt) {
        this.publishedAt = publishedAt;
    }

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeValue(author);
        dest.writeValue(title);
        dest.writeValue(description);
        dest.writeValue(url);
        dest.writeValue(urlToImage);
        dest.writeValue(publishedAt);
    }

    public int describeContents() {
        return 0;
    }

} public final class NewsPreferences {

    public static boolean areNotificationsEnabled(Context context) {
        String displayNotificationsKey = context.getString(R.string.pref_enable_notifications_key);

        boolean shouldDisplayNotificationsByDefault = context
                .getResources()
                .getBoolean(R.bool.show_notifications_by_default);

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);

        boolean shouldDisplayNotifications = sp
                .getBoolean(displayNotificationsKey, shouldDisplayNotificationsByDefault);

        return shouldDisplayNotifications;
    }

    public static void saveLastNotificationTime(Context context, long timeOfNotification) {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = sp.edit();
        String lastNotificationKey = context.getString(R.string.pref_last_notification);
        editor.putLong(lastNotificationKey, timeOfNotification);
        editor.apply();
    }
} public class ApiClient {

    public static final String BASE_URL = "https://newsapi.org/v1/";
    private static Retrofit retrofit = null;


    /*public static Retrofit getClient() {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }*/
    public static Retrofit getClient2() {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .addConverterFactory(GsonConverterFactory.create())
                    .baseUrl(BASE_URL)
                    .build();
        }
        return retrofit;
    }

} public interface ApiInterface {


  /*  @GET("articles")
    Call<NewsResponse> getNews(@QueryMap Map<String, String> options);
*/

    @GET("articles")
    Observable<NewsResponse> getNews2(@QueryMap Map<String, String> options);

} public class NewsResponse {

    @SerializedName("status")
    private String status;
    @SerializedName("source")
    private String source;
    @SerializedName("sortBy")
    private String sortBy;
    @SerializedName("articles")
    private List<Article> articles = null;


    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public String getSortBy() {
        return sortBy;
    }

    public void setSortBy(String sortBy) {
        this.sortBy = sortBy;
    }

    public List<Article> getArticles() {
        return articles;
    }

    public void setArticles(List<Article> articles) {
        this.articles = articles;
    }

} public class NewsUtil {

    public static final String FAVORITE = "favorite";
    Cursor c;
    int count = 0;

    public static void CacheDelete(Context context) {

        try {

            context.getContentResolver().delete(NewsProvider.MyNews.CONTENT_URI,
                    null, null);
        } catch (Exception e) {
        }

    }

    public static void FavouriteDelete(Context context, String title) {

        try {

            context.getContentResolver().delete(NewsProvider.NewsFavourite.CONTENT_URI_FAVOURITE,
                    ColumnsNews.TITLE + "=?", new String[]{title});
        } catch (Exception e) {
        }

    }

    public static int CheckisFavourite(Context context, String title) {
        Cursor me = null;
        int flag = 0;
        try {
            me = context.getContentResolver().query(NewsProvider.NewsFavourite.CONTENT_URI_FAVOURITE,
                    null, ColumnsNews.TITLE + "=?", new String[]{title}, null);
            if (title.equals(me.getString(me.getColumnIndex(ColumnsNews.TITLE)))) {
                flag = 0;
            } else {
                flag = 1;
            }

        } catch (Exception e) {

        } finally {
            if (me != null) {
                me.close();
            }
        }
        if (flag == 1 || me.getCount() == 0) {
            return 0;
        } else {
            return 1;
        }
    }

    public Cursor allNewsCursor(Context context) {
        c = null;
        c = context.getContentResolver().query(NewsProvider.MyNews.CONTENT_URI,
                null, null, null, null);
        return c;


    }

    public Cursor favoriteNewsCursor(Context context) {
        c = null;

        c = context.getContentResolver().query(NewsProvider.NewsFavourite.CONTENT_URI_FAVOURITE,
                null, null, null, null);
        return c;
    }

    public String[] getData(Cursor onClick) {

        String mAuthor = onClick.getString(onClick.getColumnIndex(ColumnsNews.TITLE));
        String mTitle = onClick.getString(onClick.getColumnIndex(ColumnsNews.AUTHOR));
        String mDescription = onClick.getString(onClick.getColumnIndex(ColumnsNews.DESCRIPTION));
        String mUrl = onClick.getString(onClick.getColumnIndex(ColumnsNews.URL));
        String mUrlToImage = onClick.getString(onClick.getColumnIndex(ColumnsNews.URL_TO_IMAGE));
        String mPublishedAt = onClick.getString(onClick.getColumnIndex(ColumnsNews.PUBLISHED_AT));

        return new String[]{mAuthor, mTitle, mDescription, mUrl, mUrlToImage, mPublishedAt};
    }

    public int getAllNewsCount(Context context) {
        count = 0;
        count = allNewsCursor(context).getCount();
        return count;
    }

    public int getFavNewsCount(Context context) {
        count = 0;
        count = favoriteNewsCursor(context).getCount();
        return count;
    }

    public int insertData(Context context, ArrayList<Article> article, String storeF) {
        c = null;
        int flag = 0;
        ContentProviderOperation.Builder builder = null;
        try {
            ArrayList<ContentProviderOperation> batchOperations = new ArrayList<>(article.size());
            if (storeF.equals(FAVORITE)) {
                c = context.getContentResolver().query(NewsProvider.NewsFavourite.CONTENT_URI_FAVOURITE,
                        null, null, null, null);
            } else {

                c = context.getContentResolver().query(NewsProvider.MyNews.CONTENT_URI,
                        null, null, null, null);
            }


            for (Article news : article) {


                c.moveToFirst();
                while (c.isAfterLast() == false) {
                    if (news.getTitle().equalsIgnoreCase(c.getString(c.getColumnIndex(ColumnsNews.TITLE)))) {
                        // Log.d("POPULAR MOVIES","Movie Title Same"+movie.getTitle().toString()+" ="+c.getString(c.getColumnIndex(ColumnsMovies.TITLE)));
                        flag = 0;
                        break;
                    } else {
                        flag = 1;
                        // Log.d("POPULAR MOVIES","Movie Title Difference"+movie.getTitle().toString()+" ="+c.getString(c.getColumnIndex(ColumnsMovies.TITLE)));

                    }
                    c.moveToNext();
                }


                if (flag == 1 || c.getCount() == 0) {
                    if (news.getTitle() != null && news.getDescription() != null && storeF.equals(FAVORITE)) {
                        builder = ContentProviderOperation.newInsert(
                                NewsProvider.NewsFavourite.CONTENT_URI_FAVOURITE);
                    } else if (news.getTitle() != null && news.getDescription() != null) {
                        builder = ContentProviderOperation.newInsert(
                                NewsProvider.MyNews.CONTENT_URI);
                    }
                    if (builder != null) {
                        builder.withValue(ColumnsNews.TITLE, news.getTitle());
                        builder.withValue(ColumnsNews.AUTHOR, (news.getAuthor() == null) ? "" : news.getAuthor());
                        builder.withValue(ColumnsNews.DESCRIPTION, news.getDescription());
                        builder.withValue(ColumnsNews.URL, (news.getUrl() == null) ? "" : news.getUrl());
                        builder.withValue(ColumnsNews.URL_TO_IMAGE, (news.getUrlToImage() == null) ? "" : news.getUrlToImage());
                        builder.withValue(ColumnsNews.PUBLISHED_AT, (news.getPublishedAt() == null) ? "" : news.getPublishedAt());
                        batchOperations.add(builder.build());
                    }

                }
            }
            context.getContentResolver().applyBatch(NewsProvider.AUTHORITY, batchOperations);
        } catch (Exception e) {
            //Log.e("News24X7", "Error applying batch insert", e);

        }
        try {

            if (c != null || !c.isClosed()) {
                c.close();
            }
        } catch (Exception e) {
        }

        if (flag == 0) {
            return 1;
        } else {
            return 0;
        }
    }
} public class NotificationUtils {


    /**
     * Constructs and displays a notification for the newly updated weather for today.
     *
     * @param context Context used to query our ContentProvider and use various Utility methods
     */
    public static void notifyUserOfNewWeather(Context context) {
        NewsUtil mNewsUtil = new NewsUtil();

        int WEATHER_NOTIFICATION_ID = 3004;
        int i = 0;
        // we'll query our contentProvider, as always
        Cursor cursor = null;
        cursor = mNewsUtil.allNewsCursor(context);
        int rand = 1 + (int) (Math.random() * ((3 - 1) + 3));
        if (cursor != null) {
            cursor.moveToFirst();

            while (i < rand && i < cursor.getCount()) {

                Resources resources = context.getResources();
                // On Honeycomb and higher devices, we can retrieve the size of the large icon
                // Prior to that, we use a fixed size
                @SuppressLint("InlinedApi")
                int largeIconWidth = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB
                        ? resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_width)
                        : resources.getDimensionPixelSize(R.dimen.notification_large_icon_default);
                @SuppressLint("InlinedApi")
                int largeIconHeight = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB
                        ? resources.getDimensionPixelSize(android.R.dimen.notification_large_icon_height)
                        : resources.getDimensionPixelSize(R.dimen.notification_large_icon_default);

                // Retrieve the large icon
                Bitmap largeIcon;
                try {
                    largeIcon = Glide.with(context)
                            .load(cursor.getString(cursor.getColumnIndex(ColumnsNews.URL_TO_IMAGE)))
                            .asBitmap()
                            .error(placeholder)
                            .fitCenter()
                            .into(largeIconWidth, largeIconHeight).get();
                } catch (InterruptedException | ExecutionException e) {
                    //  Log.e(LOG_TAG, "Error retrieving large icon from " +cursor.getString(cursor.getColumnIndex(ColumnsNews.URL_TO_IMAGE)) , e);
                    largeIcon = BitmapFactory.decodeResource(resources, placeholder);
                }
                String title = cursor.getString(cursor.getColumnIndex(ColumnsNews.TITLE));

                // Define the text of the forecast.
                String contentText = cursor.getString(cursor.getColumnIndex(ColumnsNews.DESCRIPTION));

// Create the style object with BigPictureStyle subclass.
                NotificationCompat.BigPictureStyle notiStyle = new
                        NotificationCompat.BigPictureStyle();
                notiStyle.setBigContentTitle(title);
                notiStyle.setSummaryText(contentText);

// Add the big picture to the style.
                notiStyle.bigPicture(largeIcon);
            /*
             * NotificationCompat Builder is a very convenient way to build backward-compatible
             * notifications. In order to use it, we provide a context and specify a color for the
             * notification, a couple of different icons, the title for the notification, and
             * finally the text of the notification, which in our case in a summary of today's
             * forecast.
             */
//          COMPLETED (2) Use NotificationCompat.Builder to begin building the notification
                NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
                        .setColor(ContextCompat.getColor(context, R.color.accent))
                        .setSmallIcon(ic_stat_n)
                        .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                        .setLargeIcon(largeIcon)
                        .setContentTitle(title)
                        .setContentText(contentText)
                        .setDefaults(Notification.DEFAULT_ALL) // requires VIBRATE permission
                        .setAutoCancel(true)
                        .setStyle(notiStyle);

                Intent intent = new Intent(context, DetailsActivity.class);
                Bundle extras = new Bundle();
                extras.putString(NewsWidgetProvider.EXTRA_TITLE, cursor.getString(cursor.getColumnIndex(ColumnsNews.TITLE)));
                extras.putString(NewsWidgetProvider.EXTRA_AUTHOR, cursor.getString(cursor.getColumnIndex(ColumnsNews.AUTHOR)));
                extras.putString(NewsWidgetProvider.EXTRA_DESCRIPTION, cursor.getString(cursor.getColumnIndex(ColumnsNews.DESCRIPTION)));
                extras.putString(NewsWidgetProvider.EXTRA_IMAGE_URL, cursor.getString(cursor.getColumnIndex(ColumnsNews.URL_TO_IMAGE)));
                extras.putString(NewsWidgetProvider.EXTRA_URL, cursor.getString(cursor.getColumnIndex(ColumnsNews.URL)));
                extras.putString(NewsWidgetProvider.EXTRA_DATE, cursor.getString(cursor.getColumnIndex(ColumnsNews.PUBLISHED_AT)));
                intent.putExtras(extras);
                TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(context);
                taskStackBuilder.addNextIntentWithParentStack(intent);
                PendingIntent resultPendingIntent = taskStackBuilder
                        .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

                notificationBuilder.setContentIntent(resultPendingIntent);
                NotificationManager notificationManager = (NotificationManager)
                        context.getSystemService(Context.NOTIFICATION_SERVICE);
                notificationManager.notify(WEATHER_NOTIFICATION_ID++, notificationBuilder.build());

                NewsPreferences.saveLastNotificationTime(context, System.currentTimeMillis());
                cursor.moveToNext();
                i++;
            }


        }
        try {

            if (cursor != null || !cursor.isClosed()) {
                cursor.close();
            }
        } catch (Exception e) {
        }


    }

} public static final String LATEST = "latest"; public static final String SORTBY = "sortBy"; public static final String SOURCE = "source"; public static final String APIKEY = "apiKey"; public static final String NO_SAVE = "no";
import android.content.Context;
import com.news.news24x7.BuildConfig;
import com.news.news24x7.parcelable.Article;
import com.news.news24x7.prefs.NewsPreferences;
import com.news.news24x7.retrofit.ApiClient;
import com.news.news24x7.retrofit.ApiInterface;
import com.news.news24x7.retrofit.NewsResponse;
import com.news.news24x7.util.NewsUtil;
import com.news.news24x7.util.NotificationUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import static com.news.news24x7.fragments.NewsFragment.LATEST;
import static com.news.news24x7.fragments.NewsFragment.SORTBY;
import static com.news.news24x7.fragments.NewsFragment.SOURCE;
import static com.news.news24x7.fragments.RetrofitCall.APIKEY;
import static com.news.news24x7.fragments.RetrofitCall.NO_SAVE;
package com.news.news24x7.sync;

/**
 * Created by Dell on 6/6/2017.
 */






public class NewsSyncTask {

    static NewsUtil mNewsUtil;
    static ArrayList<Article> articlesList;

    synchronized public static void syncNews(final Context context) {
        mNewsUtil = new NewsUtil();
        Map<String, String> data = new HashMap<>();
        data.put(SOURCE, "the-hindu");
        data.put(SORTBY, LATEST);
        fetchNews2(context, data);

        boolean notificationsEnabled = NewsPreferences.areNotificationsEnabled(context);

        if (notificationsEnabled) {
            NotificationUtils.notifyUserOfNewWeather(context);
        }

    }
    public static void fetchNews2(final Context context, Map<String, String> data) {
        final NewsUtil mNewsUtil = new NewsUtil();
        ApiInterface apiService =
                ApiClient.getClient2().create(ApiInterface.class);

        data.put(APIKEY, BuildConfig.NEWS_API_ORG_KEY);
        Observable<NewsResponse> news= apiService.getNews2(data);

        news.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<NewsResponse>(){

                    @Override
                    public void onSubscribe(Disposable disposable) {

                    }

                    @Override
                    public void onNext(NewsResponse newsResponse) {
                        articlesList = (ArrayList<Article>) newsResponse.getArticles();
                        mNewsUtil.insertData(context, articlesList, NO_SAVE);