Java tutorial
/* * Copyright 2014 Gleb Godonoga. * * 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.andrada.sitracker.tasks; import android.annotation.SuppressLint; import android.app.IntentService; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.backup.BackupManager; import android.content.Intent; import android.net.ConnectivityManager; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; import android.support.v4.app.NotificationCompat; import android.support.v4.app.TaskStackBuilder; import com.andrada.sitracker.Constants; import com.andrada.sitracker.R; import com.andrada.sitracker.db.manager.SiDBHelper; import com.andrada.sitracker.events.ImportUpdates; import com.andrada.sitracker.reader.SiteDetector; import com.andrada.sitracker.reader.SiteStrategy; import com.andrada.sitracker.ui.HomeActivity_; import com.andrada.sitracker.ui.ImportAuthorsActivity_; import com.andrada.sitracker.util.AnalyticsHelper; import com.andrada.sitracker.util.SamlibPageHelper; import com.j256.ormlite.android.apptools.OpenHelperManager; import org.androidannotations.annotations.EService; import org.androidannotations.annotations.SystemService; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import de.greenrobot.event.EventBus; import static com.andrada.sitracker.util.LogUtils.LOGW; import static com.andrada.sitracker.util.LogUtils.makeLogTag; @SuppressLint("Registered") @EService public class ImportAuthorsTask extends IntentService { public static final String AUTHOR_LIST_EXTRA = "authorsList"; private final static int NOTIFICATION_ID = 628986143; private static final String TAG = makeLogTag(ImportAuthorsTask.class); private final IBinder mBinder = new ImportAuthorsBinder(); @SystemService ConnectivityManager connectivityManager; @SystemService NotificationManager notificationManager; private volatile boolean shouldCancel = false; private SiDBHelper helper; @NotNull private List<String> authorsList = new ArrayList<String>(); private ImportProgress importProgress; public ImportAuthorsTask() { super(ImportAuthorsTask.class.getSimpleName()); } @Override public void onCreate() { super.onCreate(); helper = OpenHelperManager.getHelper(this, SiDBHelper.class); } @Override public void onDestroy() { super.onDestroy(); OpenHelperManager.releaseHelper(); } @NotNull @Override public IBinder onBind(Intent intent) { return mBinder; } @Override protected void onHandleIntent(@Nullable Intent intent) { if (intent == null) { return; } setupExtras(intent); this.importProgress = new ImportProgress(authorsList.size()); //Filter out duplicates right away try { List<String> urlIds = helper.getAuthorDao().getAuthorsUrlIds(); Map<String, String> prospectAuthorIds = new HashMap<String, String>(); for (String auth : authorsList) { prospectAuthorIds.put(SamlibPageHelper.getUrlIdFromCompleteUrl(auth), auth); } for (String urlId : urlIds) { if (prospectAuthorIds.containsKey(urlId)) { authorsList.remove(prospectAuthorIds.get(urlId)); this.importProgress.importFail(urlId); } } if (authorsList.size() == 0) { EventBus.getDefault().post(new ImportUpdates(this.importProgress)); } } catch (SQLException e) { LOGW(TAG, "Failed to filter out duplicate authors", e); } NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) .setSmallIcon(android.R.drawable.stat_notify_sync).setOngoing(true).setAutoCancel(false) .setContentTitle(getResources().getString(R.string.notification_import_title)).setAutoCancel(true); // Creates an explicit intent for an Activity in your app Intent resultIntent = new Intent(this, ImportAuthorsActivity_.class); // The stack builder object will contain an artificial back stack for the // started Activity. // This ensures that navigating backward from the Activity leads out of // your application to the Home screen. TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); // Adds the back stack for the Intent (but not the Intent itself) stackBuilder.addParentStack(ImportAuthorsActivity_.class); // Adds the Intent that starts the Activity to the top of the stack stackBuilder.addNextIntent(resultIntent); PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(resultPendingIntent); for (String authUrl : authorsList) { try { if (shouldCancel) { //Make sure to cancel it here as well notificationManager.cancel(NOTIFICATION_ID); break; } SiteStrategy strategy = SiteDetector.chooseStrategy(authUrl, helper); if (strategy == null) { this.importProgress.importFail(authUrl); } else { int returnMsg = strategy.addAuthorForUrl(authUrl); if (returnMsg == -1) { this.importProgress.importSuccess(); } else { this.importProgress.importFail(authUrl); } } if (shouldCancel) { //Make sure to cancel it here as well notificationManager.cancel(NOTIFICATION_ID); break; } EventBus.getDefault().post(new ImportUpdates(new ImportProgress(this.importProgress))); mBuilder.setContentText(getResources().getString(R.string.notification_import_progress, importProgress.getTotalProcessed(), importProgress.getTotalAuthors())).setAutoCancel(false) .setProgress(importProgress.getTotalAuthors(), importProgress.getTotalProcessed(), false); notificationManager.notify(NOTIFICATION_ID, mBuilder.build()); //Sleep for 5 seconds to avoid ban Thread.sleep(5000); if (!shouldCancel) { EventBus.getDefault().post(new ImportUpdates(this.importProgress)); } } catch (InterruptedException e) { LOGW(TAG, "Importing was forcibly stopped", e); } } if (!shouldCancel) { Intent finishIntent = HomeActivity_.intent(this).authorsProcessed(importProgress.getTotalAuthors()) .authorsSuccessfullyImported(importProgress.getSuccessfullyImported()).get(); // The stack builder object will contain an artificial back stack for the // started Activity. // This ensures that navigating backward from the Activity leads out of // your application to the Home screen. stackBuilder = TaskStackBuilder.create(this); // Adds the back stack for the Intent (but not the Intent itself) stackBuilder.addParentStack(HomeActivity_.class); // Adds the Intent that starts the Activity to the top of the stack stackBuilder.addNextIntent(finishIntent); BackupManager bm = new BackupManager(this); bm.dataChanged(); AnalyticsHelper.getInstance().sendEvent(Constants.GA_ADMIN_CATEGORY, Constants.GA_EVENT_AUTHOR_IMPORT, Constants.GA_EVENT_IMPORT_COMPLETE, importProgress.getTotalAuthors()); mBuilder.setProgress(0, 0, false).setOngoing(false).setAutoCancel(true) .setContentText(getResources().getString(R.string.notification_import_complete)) .setContentIntent(stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)); notificationManager.notify(NOTIFICATION_ID, mBuilder.build()); } } public void cancelImport() { this.shouldCancel = true; notificationManager.cancel(NOTIFICATION_ID); } public ImportProgress getCurrentProgress() { return this.importProgress; } @NotNull public List<String> getAuthorsList() { return authorsList; } private void setupExtras(@NotNull Intent intent) { Bundle extras = intent.getExtras(); if (extras != null) { if (extras.containsKey(AUTHOR_LIST_EXTRA)) { authorsList = (List<String>) extras.getSerializable(AUTHOR_LIST_EXTRA); } } } public static class ImportProgress { private int totalAuthors = 0; private int successfullyImported = 0; private int failedImport = 0; private int totalProcessed = 0; private List<String> failedAuthors = new ArrayList<String>(); public ImportProgress(int totalAuthors) { this.totalAuthors = totalAuthors; } public ImportProgress(@NotNull ImportProgress copy) { this.totalAuthors = copy.totalAuthors; this.successfullyImported = copy.successfullyImported; this.failedImport = copy.failedImport; this.totalProcessed = copy.totalProcessed; this.failedAuthors.addAll(copy.getFailedAuthors()); } public int getTotalProcessed() { return totalProcessed; } public int getTotalAuthors() { return totalAuthors; } public int getSuccessfullyImported() { return successfullyImported; } public int getFailedImport() { return failedImport; } @NotNull public List<String> getFailedAuthors() { return failedAuthors; } void importSuccess() { this.totalProcessed++; this.successfullyImported++; } void importFail(String authorUrl) { this.totalProcessed++; this.failedImport++; this.failedAuthors.add(authorUrl); } } public class ImportAuthorsBinder extends Binder { @NotNull public ImportAuthorsTask getService() { return ImportAuthorsTask.this; } } }