├── .gitignore
├── .idea
├── .name
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── gradle.xml
├── libraries
│ └── support_v4_19_0_0.xml
├── misc.xml
├── modules.xml
├── scopes
│ └── scope_settings.xml
└── vcs.xml
├── AsyncAndroid.iml
├── AsyncAndroid
├── .gitignore
├── AsyncAndroid-AsyncAndroid.iml
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── packt
│ │ └── asyncandroid
│ │ ├── CompatibleActivity.java
│ │ ├── LaunchActivity.java
│ │ ├── SafeAsyncTask.java
│ │ ├── SquareImage.java
│ │ ├── SquareLayout.java
│ │ ├── Streams.java
│ │ ├── chapter1
│ │ ├── example1
│ │ │ └── ANRActivity.java
│ │ └── example2
│ │ │ └── ChoreographerActivity.java
│ │ ├── chapter2
│ │ ├── AsyncTaskMedleyActivity.java
│ │ ├── PrimeCalculator.java
│ │ ├── example1
│ │ │ ├── Example1Activity.java
│ │ │ └── PrimesTask.java
│ │ ├── example2
│ │ │ ├── Example2Activity.java
│ │ │ └── PrimesTask.java
│ │ ├── example3
│ │ │ ├── Example3Activity.java
│ │ │ └── PrimesTask.java
│ │ ├── example4
│ │ │ ├── Example4Activity.java
│ │ │ └── PrimesTask.java
│ │ ├── example5
│ │ │ ├── AsyncListener.java
│ │ │ ├── Example5Activity.java
│ │ │ └── PrimesFragment.java
│ │ └── example6
│ │ │ └── Example6Activity.java
│ │ ├── chapter3
│ │ ├── example1
│ │ │ ├── ExplicitHandlerPrimesActivity.java
│ │ │ └── ViewHandlerPrimesActivity.java
│ │ ├── example2
│ │ │ └── PostDelayedActivity.java
│ │ ├── example3
│ │ │ └── EchoActivity.java
│ │ ├── example4
│ │ │ └── HandlerThreadActivity.java
│ │ └── example5
│ │ │ ├── CompassActivity.java
│ │ │ └── CompassView.java
│ │ ├── chapter4
│ │ ├── ThumbnailLoader.java
│ │ ├── example1
│ │ │ └── ThumbnailActivity.java
│ │ ├── example2
│ │ │ ├── MediaCursorAdapter.java
│ │ │ └── MediaStoreActivity.java
│ │ ├── example3
│ │ │ ├── MediaCursorAdapter.java
│ │ │ ├── MediaStoreActivity.java
│ │ │ └── ThumbnailCallbacks.java
│ │ ├── example4
│ │ │ ├── PrimeView.java
│ │ │ └── PrimesActivity.java
│ │ └── example5
│ │ │ └── FileListActivity.java
│ │ ├── chapter5
│ │ ├── example1
│ │ │ ├── PendingIntentPrimesActivity.java
│ │ │ └── PendingIntentPrimesIntentService.java
│ │ ├── example2
│ │ │ ├── NotifyingPrimesActivity.java
│ │ │ └── NotifyingPrimesIntentService.java
│ │ ├── example3
│ │ │ ├── MessageSendingPrimesActivity.java
│ │ │ └── MessageSendingPrimesIntentService.java
│ │ ├── example4
│ │ │ ├── BroadcastReceivingPrimesActivity.java
│ │ │ └── BroadcastingPrimesIntentService.java
│ │ └── example5
│ │ │ ├── ImageUploader.java
│ │ │ ├── MediaCursorAdapter.java
│ │ │ ├── ThumbnailCallbacks.java
│ │ │ ├── ThumbnailLoader.java
│ │ │ ├── UploadIntentService.java
│ │ │ └── UploadPhotoActivity.java
│ │ ├── chapter6
│ │ ├── ConcurrentDownloadService.java
│ │ ├── ConcurrentIntentService.java
│ │ ├── LocalDownloadCache.java
│ │ ├── SimpleDownloader.java
│ │ ├── example1
│ │ │ ├── PrimesActivity.java
│ │ │ └── PrimesConcurrentIntentService.java
│ │ ├── example2
│ │ │ ├── LocalPrimesActivity.java
│ │ │ └── LocalPrimesService.java
│ │ ├── example3
│ │ │ ├── MessageReceivingPrimesActivity.java
│ │ │ └── MessageSendingPrimesService.java
│ │ ├── example4
│ │ │ ├── BroadcastReceivingPrimesActivity.java
│ │ │ └── BroadcastingPrimesService.java
│ │ ├── example5
│ │ │ └── DownloadActivity.java
│ │ └── example6
│ │ │ ├── DownloadTask.java
│ │ │ ├── NasaImageOfTheDayActivity.java
│ │ │ ├── NasaRSS.java
│ │ │ └── NasaRSSParser.java
│ │ └── chapter7
│ │ ├── example1
│ │ ├── AlarmReceiver.java
│ │ └── StaticReceiverAlarmActivity.java
│ │ ├── example2
│ │ └── DynamicReceiverAlarmActivity.java
│ │ ├── example3
│ │ ├── AlarmSettingActivity.java
│ │ └── AsyncBroadcastReceiver.java
│ │ ├── example4
│ │ └── SetServiceAlarmActivity.java
│ │ ├── example5
│ │ ├── AlarmReceiver.java
│ │ ├── AwakeIntentService.java
│ │ ├── AwakePrimesIntentService.java
│ │ └── SetBroadcastAlarmActivity.java
│ │ └── example6
│ │ └── SetActivityAlarmActivity.java
│ └── res
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ └── ic_launcher.png
│ ├── layout
│ ├── book_activity_cell.xml
│ ├── book_layout.xml
│ ├── ch1_example1_layout.xml
│ ├── ch1_example2_layout.xml
│ ├── ch2_example6_layout.xml
│ ├── ch2_example_layout.xml
│ ├── ch2_medley_layout.xml
│ ├── ch3_example1a_layout.xml
│ ├── ch3_example1b_layout.xml
│ ├── ch3_example2_layout.xml
│ ├── ch3_example3_layout.xml
│ ├── ch3_example4_layout.xml
│ ├── ch3_example5_compass_layout.xml
│ ├── ch4_example1_layout.xml
│ ├── ch4_example2_cell.xml
│ ├── ch4_example2_layout.xml
│ ├── ch4_example3_cell.xml
│ ├── ch4_example3_layout.xml
│ ├── ch4_example4_layout.xml
│ ├── ch4_example5_cell.xml
│ ├── ch4_example5_layout.xml
│ ├── ch5_example5_cell.xml
│ ├── ch5_example5_layout.xml
│ ├── ch5_example_layout.xml
│ ├── ch6_example5_layout.xml
│ ├── ch6_example6_layout.xml
│ ├── ch6_example6_row_img_left.xml
│ ├── ch6_example6_row_img_right.xml
│ ├── ch6_example_layout.xml
│ ├── ch7_example1_layout.xml
│ ├── ch7_example2_layout.xml
│ ├── ch7_example3_layout.xml
│ ├── ch7_example4_layout.xml
│ ├── ch7_example5_layout.xml
│ └── ch7_example6_layout.xml
│ ├── values-land
│ └── dimens.xml
│ ├── values-port
│ └── dimens.xml
│ ├── values-small-land
│ └── dimens.xml
│ ├── values-small-port
│ └── dimens.xml
│ ├── values-v11
│ └── styles.xml
│ ├── values-v14
│ └── styles.xml
│ └── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── README.md
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | build
3 | /local.properties
4 | /.idea/workspace.xml
5 | .DS_Store
6 | *.apk
7 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | AsyncAndroid
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/.idea/libraries/support_v4_19_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | Android API 19 Platform
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | 1.7.0_07
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/scopes/scope_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AsyncAndroid/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/AsyncAndroid/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | mavenCentral()
4 | }
5 | dependencies {
6 | classpath 'com.android.tools.build:gradle:1.0.0-rc2'
7 | }
8 | }
9 | apply plugin: 'android'
10 |
11 | repositories {
12 | mavenCentral()
13 | }
14 |
15 | android {
16 | compileSdkVersion 19
17 | buildToolsVersion '19.1.0'
18 |
19 | defaultConfig {
20 | minSdkVersion 7
21 | targetSdkVersion 19
22 | }
23 | }
24 |
25 | dependencies {
26 | compile 'com.android.support:support-v4:19.0.0'
27 | }
28 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/CompatibleActivity.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.app.FragmentActivity;
5 |
6 | /**
7 | * Adds support for isChangingConfigurations when minSdkVersion
8 | * targets api-levels below 11.
9 | *
10 | * Unfortunately onSaveInstanceState is invoked AFTER onPause,
11 | * so on platforms below 11 isChangingConfigurations will only
12 | * report correctly in onStop() or onDestroy().
13 | */
14 | public class CompatibleActivity extends FragmentActivity {
15 |
16 | private boolean isConfigChange;
17 |
18 | @Override
19 | protected void onSaveInstanceState(Bundle outState) {
20 | super.onSaveInstanceState(outState);
21 | isConfigChange = true;
22 | }
23 |
24 | @Override
25 | public boolean isChangingConfigurations() {
26 | if (android.os.Build.VERSION.SDK_INT >= 11)
27 | return super.isChangingConfigurations();
28 | else
29 | return isConfigChange;
30 | }
31 |
32 | @Override
33 | protected void onStop() {
34 | super.onStop();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/SafeAsyncTask.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid;
2 |
3 | import android.os.AsyncTask;
4 | import android.util.Log;
5 |
6 | public abstract class SafeAsyncTask
7 | extends AsyncTask> {
8 |
9 | static class Result {
10 | private T result;
11 | private Exception exc;
12 | }
13 |
14 | protected abstract R doSafelyInBackground(Void... params) throws Exception;
15 |
16 | @Override
17 | protected final Result doInBackground(Void... params) {
18 | Result result = new Result();
19 | try {
20 | result.result = doSafelyInBackground(params);
21 | } catch (Exception exc) {
22 | result.exc = exc;
23 | }
24 | return result;
25 | }
26 |
27 | @Override
28 | protected final void onPostExecute(Result result) {
29 | if (result.exc != null) {
30 | onCompletedWithException(result.exc);
31 | } else {
32 | onCompletedWithResult(result.result);
33 | }
34 | }
35 |
36 | @Override
37 | protected final void onCancelled(Result result) {
38 | onCancelledWithResult(result.result);
39 | }
40 |
41 | // override me if you want to handle exceptions
42 | protected void onCompletedWithException(Exception exc) {
43 | Log.e(LaunchActivity.TAG, exc.getMessage(), exc);
44 | }
45 |
46 | // override me if you want to handle the result
47 | protected void onCompletedWithResult(R result) {
48 | }
49 |
50 | // override me if you to handle the partial result
51 | // but _don't_ call super if you override
52 | protected void onCancelledWithResult(R result) {
53 | onCancelled();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/SquareImage.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.ImageView;
6 |
7 | public class SquareImage extends ImageView {
8 |
9 | public SquareImage(Context context, AttributeSet attrs) {
10 | super(context, attrs);
11 | }
12 |
13 | @Override
14 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
15 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
16 | setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/SquareLayout.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.LinearLayout;
6 |
7 | public class SquareLayout extends LinearLayout {
8 |
9 | public SquareLayout(Context context, AttributeSet attrs) {
10 | super(context, attrs);
11 | }
12 |
13 | @Override
14 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
15 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
16 | setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth());
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/Streams.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid;
2 |
3 | import android.util.Log;
4 |
5 | import java.io.Closeable;
6 | import java.io.IOException;
7 |
8 | public class Streams {
9 |
10 | public static void close(Closeable... streams) {
11 | for (Closeable c : streams) {
12 | close(c);
13 | }
14 | }
15 |
16 | public static void close(Closeable stream) {
17 | try {
18 | if (stream != null)
19 | stream.close();
20 | } catch (IOException anExc) {
21 | Log.w(LaunchActivity.TAG, "problem closing stream", anExc);
22 | }
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter1/example1/ANRActivity.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter1.example1;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.view.View;
6 | import android.widget.Button;
7 |
8 | import com.packt.asyncandroid.R;
9 |
10 | /**
11 | * DELIBERATELY trigger's an Application Not Responding dialog,
12 | * thereby crashing the containing app.
13 | */
14 | public class ANRActivity extends Activity {
15 | @Override
16 | protected void onCreate(Bundle savedInstanceState) {
17 | super.onCreate(savedInstanceState);
18 |
19 | setContentView(R.layout.ch1_example1_layout);
20 |
21 | makeEvil((Button)findViewById(R.id.button1));
22 | makeEvil((Button)findViewById(R.id.button2));
23 | makeEvil((Button)findViewById(R.id.button3));
24 | }
25 |
26 | private void makeEvil(Button button) {
27 | button.setOnClickListener(new View.OnClickListener() {
28 | @Override
29 | public void onClick(View v) {
30 | try {
31 | Thread.sleep(6000L);
32 | } catch (InterruptedException anExc) {
33 | anExc.printStackTrace();
34 | }
35 | }
36 | });
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter1/example2/ChoreographerActivity.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter1.example2;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Canvas;
5 | import android.os.Bundle;
6 | import android.view.ViewGroup;
7 | import android.widget.TextView;
8 |
9 | import com.packt.asyncandroid.R;
10 |
11 | public class ChoreographerActivity extends Activity {
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 |
17 | setContentView(R.layout.ch1_example2_layout);
18 |
19 | ViewGroup root = (ViewGroup) findViewById(R.id.root);
20 |
21 | root.addView(new TextView(this){
22 | @Override
23 | protected void onDraw(Canvas canvas) {
24 | super.onDraw(canvas);
25 | long sleep = (long)(Math.random() * 1000L);
26 | setText("" + sleep);
27 | try {
28 | Thread.sleep(sleep);
29 | } catch (Exception exc) {}
30 | }
31 | });
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter2/PrimeCalculator.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter2;
2 |
3 | import java.math.BigInteger;
4 |
5 | public class PrimeCalculator {
6 |
7 | interface ProgressListener {
8 | public void onProgress(int percent);
9 | }
10 |
11 | interface Status {
12 | public boolean isCalculationCancelled();
13 | }
14 |
15 | private ProgressMeter meter;
16 |
17 | public PrimeCalculator(long timeoutMillis) {
18 | meter = new ProgressMeter(timeoutMillis);
19 | }
20 |
21 | public BigInteger findHighestProbablePrime() {
22 | return findHighestProbablePrime(new NoOpProgressListener());
23 | }
24 |
25 | public BigInteger findHighestProbablePrime(ProgressListener listener) {
26 | return findHighestProbablePrime(listener, new UnknownCancellationStatus());
27 | }
28 |
29 | public BigInteger findHighestProbablePrime(ProgressListener listener, Status status) {
30 | meter.start();
31 | BigInteger prime = new BigInteger("2");
32 |
33 | while(!meter.isComplete() && !status.isCalculationCancelled()) {
34 | prime = prime.nextProbablePrime();
35 | listener.onProgress(meter.calculateProgress());
36 | }
37 |
38 | return prime;
39 | }
40 |
41 | private static class ProgressMeter
42 | {
43 | long startTime, onePercent;
44 | int percentComplete;
45 |
46 | public ProgressMeter(long timeoutMillis) {
47 | onePercent = timeoutMillis / 100L;
48 | percentComplete = 0;
49 | }
50 |
51 | public void start() {
52 | startTime = System.currentTimeMillis();
53 | }
54 |
55 | public int calculateProgress() {
56 | long now = System.currentTimeMillis();
57 | return percentComplete = (int)((now - startTime) / onePercent);
58 | }
59 |
60 | public boolean isComplete() {
61 | return percentComplete >= 100;
62 | }
63 | }
64 |
65 | private static class NoOpProgressListener implements ProgressListener {
66 | public void onProgress(int aPercent){
67 | // deliberately doing nothing
68 | }
69 | }
70 |
71 | private static class UnknownCancellationStatus implements Status {
72 | public boolean isCalculationCancelled() {
73 | return false;
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter2/example1/Example1Activity.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter2.example1;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.view.View;
6 | import android.widget.Button;
7 | import android.widget.TextView;
8 |
9 | import com.packt.asyncandroid.R;
10 |
11 | public class Example1Activity extends Activity {
12 |
13 | @Override
14 | protected void onCreate(Bundle savedInstanceState) {
15 | super.onCreate(savedInstanceState);
16 | setContentView(R.layout.ch2_example_layout);
17 |
18 | Button goButton = (Button) findViewById(R.id.go);
19 | goButton.setOnClickListener(new View.OnClickListener() {
20 | @Override
21 | public void onClick(View view) {
22 | // find the nth probable prime in the background using AsyncTask
23 | new PrimesTask((TextView) findViewById(R.id.result)).execute(500);
24 | }
25 | });
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter2/example1/PrimesTask.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter2.example1;
2 |
3 | import android.os.AsyncTask;
4 | import android.widget.TextView;
5 |
6 | import java.math.BigInteger;
7 |
8 | public class PrimesTask extends AsyncTask {
9 | private TextView resultView;
10 |
11 | public PrimesTask(TextView resultView) {
12 | this.resultView = resultView;
13 | }
14 |
15 | @Override
16 | protected BigInteger doInBackground(Integer... params) {
17 | int primeToFind = params[0];
18 | BigInteger prime = new BigInteger("2");
19 | for (int i=0; i {
13 | private Context ctx;
14 | private ProgressDialog progress;
15 | private TextView resultView;
16 |
17 | public PrimesTask(Context ctx, TextView resultView) {
18 | this.ctx = ctx;
19 | this.resultView = resultView;
20 | }
21 |
22 | @Override
23 | protected void onPreExecute() {
24 | progress = new ProgressDialog(ctx);
25 | progress.setTitle(R.string.calculating);
26 | progress.setCancelable(false);
27 | progress.show();
28 | }
29 |
30 | @Override
31 | protected BigInteger doInBackground(Integer... params) {
32 | int primeToFind = params[0];
33 | BigInteger prime = new BigInteger("2");
34 | for (int i=0; i {
13 | private Context ctx;
14 | private ProgressDialog progress;
15 | private TextView resultView;
16 |
17 | public PrimesTask(Context ctx, TextView resultView) {
18 | this.ctx = ctx;
19 | this.resultView = resultView;
20 | }
21 |
22 | @Override
23 | protected void onPreExecute() {
24 | progress = new ProgressDialog(ctx);
25 | progress.setTitle(R.string.calculating);
26 | progress.setCancelable(false);
27 | progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
28 | progress.setProgress(0);
29 | progress.setMax(100);
30 | progress.show();
31 | }
32 |
33 | @Override
34 | protected BigInteger doInBackground(Integer... params) {
35 | int primeToFind = params[0];
36 | BigInteger prime = new BigInteger("2");
37 | for (int i=0; i {
14 | private Context ctx;
15 | private ProgressDialog progress;
16 | private TextView resultView;
17 |
18 | public PrimesTask(Context ctx, TextView resultView) {
19 | this.ctx = ctx;
20 | this.resultView = resultView;
21 | }
22 |
23 | @Override
24 | protected void onPreExecute() {
25 | progress = new ProgressDialog(ctx);
26 | progress.setTitle(R.string.calculating);
27 | progress.setCancelable(true);
28 | progress.setOnCancelListener(new DialogInterface.OnCancelListener() {
29 | @Override
30 | public void onCancel(DialogInterface dialog) {
31 | PrimesTask.this.cancel(false);
32 | }
33 | });
34 | progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
35 | progress.setProgress(0);
36 | progress.setMax(100);
37 | progress.show();
38 | }
39 |
40 | @Override
41 | protected BigInteger doInBackground(Integer... params) {
42 | int primeToFind = params[0];
43 | BigInteger prime = new BigInteger("2");
44 | for (int i=0; i {
4 | void onPreExecute();
5 | void onProgressUpdate(Progress... progress);
6 | void onPostExecute(Result result);
7 | void onCancelled(Result result);
8 | }
9 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter2/example5/Example5Activity.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter2.example5;
2 |
3 | import android.app.ProgressDialog;
4 | import android.content.DialogInterface;
5 | import android.os.Bundle;
6 | import android.support.v4.app.FragmentActivity;
7 | import android.support.v4.app.FragmentManager;
8 | import android.support.v4.app.FragmentTransaction;
9 | import android.view.View;
10 | import android.widget.Button;
11 | import android.widget.TextView;
12 |
13 | import com.packt.asyncandroid.R;
14 |
15 | import java.math.BigInteger;
16 |
17 | public class Example5Activity extends FragmentActivity
18 | implements AsyncListener {
19 |
20 | public static final String PRIMES = "primes";
21 | private ProgressDialog dialog;
22 | private TextView resultView;
23 | private Button goButton;
24 |
25 | @Override
26 | protected void onCreate(Bundle savedInstanceState) {
27 | super.onCreate(savedInstanceState);
28 | setContentView(R.layout.ch2_example_layout);
29 | ((TextView)findViewById(R.id.title)).setText(R.string.ch2_ex5);
30 | ((TextView)findViewById(R.id.description)).setText(R.string.ch2_ex5_desc);
31 |
32 | resultView = (TextView)findViewById(R.id.result);
33 | goButton = (Button)findViewById(R.id.go);
34 | goButton.setOnClickListener(new View.OnClickListener(){
35 | @Override
36 | public void onClick(View v) {
37 | PrimesFragment primes = (PrimesFragment)
38 | getSupportFragmentManager().findFragmentByTag(PRIMES);
39 |
40 | if (primes == null) {
41 | primes = new PrimesFragment();
42 | FragmentTransaction transaction =
43 | getSupportFragmentManager().beginTransaction();
44 | transaction.add(primes, PRIMES);
45 | transaction.commit();
46 | }
47 | }
48 | });
49 | }
50 |
51 | public void onPreExecute() {
52 | onProgressUpdate(0);
53 | }
54 |
55 | public void onProgressUpdate(Integer... progress) {
56 | if (dialog == null) {
57 | prepareProgressDialog();
58 | }
59 | dialog.setProgress(progress[0]);
60 | }
61 |
62 | public void onPostExecute(BigInteger result) {
63 | resultView.setText(result.toString());
64 | cleanUp();
65 | }
66 |
67 | public void onCancelled(BigInteger result) {
68 | resultView.setText("cancelled at " + result);
69 | cleanUp();
70 | }
71 |
72 | private void prepareProgressDialog() {
73 | dialog = new ProgressDialog(this);
74 | dialog.setTitle(R.string.calculating);
75 | dialog.setCancelable(true);
76 | dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
77 | @Override
78 | public void onCancel(DialogInterface dialog) {
79 | PrimesFragment primes = (PrimesFragment)
80 | getSupportFragmentManager().findFragmentByTag(PRIMES);
81 | primes.cancel();
82 | }
83 | });
84 | dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
85 | dialog.setProgress(0);
86 | dialog.setMax(100);
87 | dialog.show();
88 | }
89 |
90 | private void cleanUp() {
91 | dialog.dismiss();
92 | dialog = null;
93 | FragmentManager fm = getSupportFragmentManager();
94 | PrimesFragment primes = (PrimesFragment) fm.findFragmentByTag(PRIMES);
95 | fm.beginTransaction().remove(primes).commit();
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter2/example5/PrimesFragment.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter2.example5;
2 |
3 | import android.app.Activity;
4 | import android.os.AsyncTask;
5 | import android.os.Bundle;
6 | import android.support.v4.app.Fragment;
7 |
8 | import java.math.BigInteger;
9 |
10 | public class PrimesFragment extends Fragment {
11 |
12 | private AsyncListener listener;
13 | private PrimesTask task;
14 |
15 | @Override
16 | public void onCreate(Bundle savedInstanceState) {
17 | super.onCreate(savedInstanceState);
18 | setRetainInstance(true);
19 | task = new PrimesTask();
20 | task.execute(2000);
21 | }
22 |
23 | @Override
24 | public void onAttach(Activity activity) {
25 | super.onAttach(activity);
26 | listener = (AsyncListener)activity;
27 | }
28 |
29 | @Override
30 | public void onDetach() {
31 | super.onDetach();
32 | listener = null;
33 | }
34 |
35 | public void cancel() {
36 | task.cancel(false);
37 | }
38 |
39 | class PrimesTask extends AsyncTask {
40 | @Override
41 | protected void onPreExecute() {
42 | if (listener != null) listener.onPreExecute();
43 | }
44 |
45 | @Override
46 | protected BigInteger doInBackground(Integer... params) {
47 | int primeToFind = params[0];
48 | BigInteger prime = new BigInteger("2");
49 | for (int i=0; i {
33 | private static Random random = new Random();
34 |
35 | private TextView resultView;
36 |
37 | public ExceptionalPrimesTask(TextView resultView) {
38 | this.resultView = resultView;
39 | }
40 |
41 | @Override
42 | protected BigInteger doSafelyInBackground(Void... params) throws Exception {
43 | if (random.nextBoolean()) {
44 | throw new RuntimeException("bang");
45 | } else {
46 | return new BigInteger("12345");
47 | }
48 | }
49 |
50 | @Override
51 | protected void onCompletedWithResult(BigInteger result) {
52 | resultView.setText(result.toString());
53 | }
54 |
55 | @Override
56 | protected void onCompletedWithException(Exception exc) {
57 | resultView.setText(exc.getMessage());
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter3/example1/ExplicitHandlerPrimesActivity.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter3.example1;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.os.Handler;
6 | import android.view.View;
7 | import android.widget.Button;
8 | import android.widget.TextView;
9 |
10 | import com.packt.asyncandroid.R;
11 |
12 | import java.math.BigInteger;
13 |
14 | /**
15 | * Illustrates creating a Handler attached to the main thread's Looper,
16 | * and posting Runnable's to the Handler for the main thread to execute.
17 | */
18 | public class ExplicitHandlerPrimesActivity extends Activity {
19 |
20 | private Handler handler;
21 |
22 | @Override
23 | protected void onCreate(Bundle savedInstanceState) {
24 | super.onCreate(savedInstanceState);
25 |
26 | setContentView(R.layout.ch3_example1a_layout);
27 |
28 | // create a Handler bound to the main thread
29 | handler = new Handler();
30 |
31 | final TextView resultView = (TextView) findViewById(R.id.result);
32 |
33 | Button goButton = (Button) findViewById(R.id.go);
34 | goButton.setOnClickListener(new View.OnClickListener() {
35 | @Override
36 | public void onClick(View view) {
37 | // find the nth probable prime in the
38 | // background using a simple thread
39 | resultView.setText(R.string.calculating);
40 | new PrimeCalculator(500, resultView, handler).start();
41 | }
42 | });
43 | }
44 |
45 | private static class PrimeCalculator extends Thread {
46 |
47 | private int primeToFind;
48 | private TextView resultView;
49 | private Handler handler;
50 |
51 | public PrimeCalculator(int primeToFind, TextView resultView, Handler handler) {
52 | this.handler = handler;
53 | this.resultView = resultView;
54 | this.primeToFind = primeToFind;
55 | // make sure to reduce the thread priority so we
56 | // don't starve the main thread!
57 | setPriority(Thread.MIN_PRIORITY);
58 | }
59 |
60 | @Override
61 | public void run() {
62 | BigInteger prime = new BigInteger("2");
63 | for (int i=0; i {
17 |
18 | private static final int LOADER_ID = "thumb_loader".hashCode();
19 |
20 | private Integer mediaId;
21 | private ImageView thumb;
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.ch4_example1_layout);
27 | thumb = (ImageView) findViewById(R.id.thumb);
28 | mediaId = getMediaIdFromIntent(getIntent());
29 | if (mediaId != null)
30 | getSupportLoaderManager().initLoader(LOADER_ID, null, this);
31 | }
32 |
33 | @Override
34 | protected void onDestroy() {
35 | super.onDestroy();
36 | if (isFinishing()) {
37 | getSupportLoaderManager().destroyLoader(LOADER_ID);
38 | }
39 | }
40 |
41 | @Override
42 | public Loader onCreateLoader(int i, Bundle bundle) {
43 | return new ThumbnailLoader(getApplicationContext(), mediaId);
44 | }
45 |
46 | @Override
47 | public void onLoadFinished(Loader loader, Bitmap bitmap) {
48 | thumb.setImageBitmap(bitmap);
49 | }
50 |
51 | @Override
52 | public void onLoaderReset(Loader loader) {
53 | // we don't need to do anything here.
54 | }
55 |
56 | private Integer getMediaIdFromIntent(Intent intent) {
57 | if (Intent.ACTION_SEND.equals(intent.getAction())) {
58 | Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
59 | return new Integer(uri.getLastPathSegment());
60 | } else {
61 | return null;
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter4/example2/MediaCursorAdapter.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter4.example2;
2 |
3 | import android.content.Context;
4 | import android.provider.MediaStore;
5 | import android.support.v4.widget.SimpleCursorAdapter;
6 |
7 | import com.packt.asyncandroid.R;
8 |
9 | public class MediaCursorAdapter extends SimpleCursorAdapter {
10 | private static String[] FIELDS = new String[]{
11 | MediaStore.Images.Media._ID,
12 | MediaStore.Images.Media.DISPLAY_NAME
13 | };
14 |
15 | private static int[] VIEWS = new int[]{
16 | R.id.media_id, R.id.display_name
17 | };
18 |
19 | public MediaCursorAdapter(Context context) {
20 | super(context, R.layout.ch4_example2_cell, null, FIELDS, VIEWS, 0);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter4/example2/MediaStoreActivity.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter4.example2;
2 |
3 | import android.database.Cursor;
4 | import android.os.Bundle;
5 | import android.provider.MediaStore;
6 | import android.support.v4.app.LoaderManager;
7 | import android.support.v4.content.CursorLoader;
8 | import android.support.v4.content.Loader;
9 | import android.widget.GridView;
10 |
11 | import com.packt.asyncandroid.R;
12 | import com.packt.asyncandroid.CompatibleActivity;
13 |
14 | public class MediaStoreActivity extends CompatibleActivity
15 | implements LoaderManager.LoaderCallbacks {
16 |
17 | public static final int MS_LOADER = "ms_crsr".hashCode();
18 |
19 | private MediaCursorAdapter adapter;
20 |
21 | @Override
22 | protected void onCreate(Bundle savedInstanceState) {
23 | super.onCreate(savedInstanceState);
24 |
25 | setContentView(R.layout.ch4_example2_layout);
26 |
27 | adapter = new MediaCursorAdapter(getApplicationContext());
28 |
29 | GridView grid = (GridView)findViewById(R.id.grid);
30 | grid.setAdapter(adapter);
31 |
32 | getSupportLoaderManager()
33 | .initLoader(MS_LOADER, null, this);
34 | }
35 |
36 | @Override
37 | public CursorLoader onCreateLoader(int id, Bundle bundle) {
38 | return new CursorLoader(this,
39 | MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
40 | new String[]{
41 | MediaStore.Images.Media._ID,
42 | MediaStore.Images.Media.DISPLAY_NAME
43 | }, "", null, null);
44 | }
45 |
46 | @Override
47 | public void onLoadFinished(Loader loader, Cursor media) {
48 | adapter.changeCursor(media);
49 | }
50 |
51 | @Override
52 | public void onLoaderReset(Loader loader) {
53 | adapter.changeCursor(null);
54 | }
55 |
56 | @Override
57 | protected void onStop() {
58 | super.onStop();
59 |
60 | if (isFinishing()) {
61 | // if we don't want to use the loaders in other activities
62 | // this is our last chance to clean it up.
63 | getSupportLoaderManager().destroyLoader(MS_LOADER);
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter4/example3/MediaCursorAdapter.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter4.example3;
2 |
3 | import android.content.Context;
4 | import android.database.Cursor;
5 | import android.provider.MediaStore;
6 | import android.support.v4.app.LoaderManager;
7 | import android.support.v4.content.Loader;
8 | import android.support.v4.widget.CursorAdapter;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.widget.ImageView;
13 |
14 | import com.packt.asyncandroid.R;
15 | import com.packt.asyncandroid.chapter4.ThumbnailLoader;
16 |
17 | import java.util.ArrayList;
18 | import java.util.List;
19 |
20 | public class MediaCursorAdapter extends CursorAdapter {
21 |
22 | private LoaderManager mgr;
23 | private LayoutInflater inf;
24 | private int count;
25 | private List ids;
26 |
27 | public MediaCursorAdapter(Context ctx, LoaderManager mgr) {
28 | super(ctx.getApplicationContext(), null, true);
29 | this.mgr = mgr;
30 | inf = (LayoutInflater) ctx.
31 | getSystemService(Context.LAYOUT_INFLATER_SERVICE);
32 | ids = new ArrayList();
33 | }
34 |
35 | @Override
36 | public View newView(final Context ctx, Cursor crsr, ViewGroup parent) {
37 | ImageView view = (ImageView) inf.
38 | inflate(R.layout.ch4_example3_cell, parent, false);
39 | view.setId(MediaCursorAdapter.class.hashCode() + ++count);
40 | mgr.initLoader(
41 | view.getId(), null, new ThumbnailCallbacks(ctx, view));
42 | ids.add(view.getId()); // remember the id, so we can clean it up later
43 | return view;
44 | }
45 |
46 | @Override
47 | public void bindView(View view, final Context context, Cursor cursor) {
48 | Loader> l = mgr.getLoader(view.getId());
49 | ThumbnailLoader loader = (ThumbnailLoader) l;
50 |
51 | Integer mediaId = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.Media._ID));
52 |
53 | // optimisation for orientation changes
54 | // that would otherwise do unnecessary work
55 | if (!mediaId.equals(loader.getMediaId())) {
56 | ImageView image = (ImageView) view;
57 | image.setImageBitmap(null);
58 | loader.setMediaId(mediaId);
59 | }
60 | }
61 |
62 | public void destroyLoaders() {
63 | for (Integer id : ids)
64 | mgr.destroyLoader(id);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter4/example3/MediaStoreActivity.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter4.example3;
2 |
3 | import android.database.Cursor;
4 | import android.os.Bundle;
5 | import android.provider.MediaStore;
6 | import android.support.v4.app.LoaderManager;
7 | import android.support.v4.content.CursorLoader;
8 | import android.support.v4.content.Loader;
9 | import android.widget.GridView;
10 |
11 | import com.packt.asyncandroid.R;
12 | import com.packt.asyncandroid.CompatibleActivity;
13 |
14 | public class MediaStoreActivity extends CompatibleActivity
15 | implements LoaderManager.LoaderCallbacks {
16 |
17 | private static final String TAG = "asyncandroid";
18 | public static final int MS_LOADER = "ms_crsr".hashCode();
19 |
20 | private MediaCursorAdapter adapter;
21 |
22 | @Override
23 | protected void onCreate(Bundle savedInstanceState) {
24 | super.onCreate(savedInstanceState);
25 |
26 | setContentView(R.layout.ch4_example3_layout);
27 |
28 | adapter = new MediaCursorAdapter(
29 | getApplicationContext(),
30 | getSupportLoaderManager());
31 |
32 | GridView grid = (GridView)findViewById(R.id.grid);
33 | grid.setAdapter(adapter);
34 |
35 | getSupportLoaderManager().initLoader(MS_LOADER, null, this);
36 | }
37 |
38 | @Override
39 | public CursorLoader onCreateLoader(int id, Bundle bundle) {
40 | return new CursorLoader(this,
41 | MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
42 | new String[]{
43 | MediaStore.Images.Media._ID,
44 | MediaStore.Images.Media.DISPLAY_NAME
45 | }, "", null, null);
46 | }
47 |
48 | @Override
49 | public void onLoadFinished(Loader loader, Cursor media) {
50 | adapter.changeCursor(media);
51 | }
52 |
53 | @Override
54 | public void onLoaderReset(Loader loader) {
55 | adapter.changeCursor(null);
56 | }
57 |
58 | @Override
59 | protected void onStop() {
60 | super.onStop();
61 |
62 | if (isFinishing()) {
63 | // if we don't want to use these loaders in other activities
64 | // this is our last chance to clean them up.
65 | getSupportLoaderManager().destroyLoader(MS_LOADER);
66 | adapter.destroyLoaders();
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter4/example3/ThumbnailCallbacks.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter4.example3;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Color;
6 | import android.graphics.drawable.BitmapDrawable;
7 | import android.graphics.drawable.ColorDrawable;
8 | import android.graphics.drawable.Drawable;
9 | import android.graphics.drawable.TransitionDrawable;
10 | import android.os.Bundle;
11 | import android.support.v4.app.LoaderManager;
12 | import android.support.v4.content.Loader;
13 | import android.widget.ImageView;
14 |
15 | import com.packt.asyncandroid.chapter4.ThumbnailLoader;
16 |
17 | /**
18 | * LoaderCallbacks implementation that expects to receive a Bitmap in onLoadFinished
19 | * and will display the bitmap with a nice fade-in effect.
20 | */
21 | public class ThumbnailCallbacks implements LoaderManager.LoaderCallbacks {
22 | private Context context;
23 | private ImageView image;
24 |
25 | public ThumbnailCallbacks(Context context, ImageView image) {
26 | // ensuring that we always only keep a handle on the Application Context
27 | // so that we don't leak references to the Activity!
28 | this.context = context.getApplicationContext();
29 | this.image = image;
30 | }
31 |
32 | @Override
33 | public Loader onCreateLoader(int i, Bundle bundle) {
34 | return new ThumbnailLoader(context);
35 | }
36 |
37 | @Override
38 | public void onLoadFinished(Loader loader, Bitmap b) {
39 | // we could just set the bitmap to the imageview, but
40 | // lets create a drawable that fades from transparent to
41 | // our bitmap, for a bit of extra swankiness...
42 | final TransitionDrawable drawable =
43 | new TransitionDrawable(new Drawable[] {
44 | new ColorDrawable(Color.TRANSPARENT),
45 | new BitmapDrawable(context.getResources(), b)
46 | });
47 |
48 | // set our fade-in drawable to the image view
49 | image.setImageDrawable(drawable);
50 |
51 | // fade in over 0.2 seconds
52 | drawable.startTransition(200);
53 | }
54 |
55 | @Override
56 | public void onLoaderReset(Loader loader) {
57 | // nothing much for us to do here.
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter4/example4/PrimeView.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter4.example4;
2 |
3 | import android.content.Context;
4 | import android.util.TypedValue;
5 | import android.view.Gravity;
6 | import android.widget.TextView;
7 |
8 | public class PrimeView extends TextView {
9 |
10 | public PrimeView(Context context) {
11 | super(context);
12 |
13 | setGravity(Gravity.CENTER);
14 | setTextSize(TypedValue.COMPLEX_UNIT_DIP, 40);
15 | }
16 |
17 | @Override
18 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
19 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
20 |
21 | // make our view square!
22 | setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth());
23 | }
24 |
25 | public void setValue(String value) {
26 | setText(value);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter5/example1/PendingIntentPrimesActivity.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter5.example1;
2 |
3 | import android.app.Activity;
4 | import android.app.PendingIntent;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 | import android.view.View;
8 | import android.widget.Button;
9 | import android.widget.TextView;
10 | import android.widget.Toast;
11 |
12 | import com.packt.asyncandroid.R;
13 |
14 | import java.math.BigInteger;
15 |
16 | public class PendingIntentPrimesActivity extends Activity{
17 |
18 | private static final int REQUEST_CODE = 0;
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 |
24 | setContentView(R.layout.ch5_example_layout);
25 | ((TextView)findViewById(R.id.title)).setText(R.string.ch5_ex1);
26 | ((TextView)findViewById(R.id.description)).setText(R.string.ch5_ex1_desc);
27 |
28 | Button go = (Button)findViewById(R.id.go);
29 | go.setOnClickListener(new View.OnClickListener() {
30 | @Override
31 | public void onClick(View v) {
32 | TextView input = (TextView) findViewById(R.id.prime_to_find);
33 | String value = input.getText().toString();
34 | if (value.matches("[1-9]+[0-9]*")) {
35 | // if the value is a number, trigger the loader to
36 | // reload when appropriate.
37 | triggerIntentService(Integer.parseInt(value));
38 | } else {
39 | Toast.makeText(PendingIntentPrimesActivity.this, "not a number!", 5000).show();
40 | }
41 | }
42 | });
43 | }
44 |
45 | @Override
46 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
47 | if (resultCode == PendingIntentPrimesIntentService.RESULT_CODE) {
48 | BigInteger result = (BigInteger) data.getSerializableExtra(
49 | PendingIntentPrimesIntentService.RESULT);
50 | TextView view = (TextView)findViewById(R.id.result);
51 | view.setText(result.toString());
52 | }
53 | super.onActivityResult(requestCode, resultCode, data);
54 | }
55 |
56 | private void triggerIntentService(int primeToFind) {
57 | PendingIntent pendingResult = createPendingResult(
58 | REQUEST_CODE, new Intent(), 0);
59 | Intent intent = new Intent(this, PendingIntentPrimesIntentService.class);
60 | intent.putExtra(PendingIntentPrimesIntentService.PARAM, primeToFind);
61 | intent.putExtra(PendingIntentPrimesIntentService.PENDING_RESULT, pendingResult);
62 | startService(intent);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter5/example1/PendingIntentPrimesIntentService.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter5.example1;
2 |
3 | import android.app.IntentService;
4 | import android.app.PendingIntent;
5 | import android.content.Intent;
6 | import android.util.Log;
7 |
8 | import com.packt.asyncandroid.LaunchActivity;
9 |
10 | import java.math.BigInteger;
11 |
12 | public class PendingIntentPrimesIntentService extends IntentService {
13 |
14 | public static final String PARAM = "prime_to_find";
15 | public static final String PENDING_RESULT = "pending_result";
16 | public static final String RESULT = "result";
17 | public static final int RESULT_CODE = "nth_prime".hashCode();
18 | public static final int INVALID = "invalid".hashCode();
19 |
20 | public PendingIntentPrimesIntentService() {
21 | super("primes");
22 | }
23 |
24 | @Override
25 | protected void onHandleIntent(Intent intent) {
26 | PendingIntent reply = intent.getParcelableExtra(PENDING_RESULT);
27 | int n = intent.getIntExtra(PARAM, -1);
28 | try {
29 | if (n < 2) {
30 | reply.send(INVALID);
31 | } else {
32 | BigInteger prime = new BigInteger("2");
33 | Intent result = new Intent();
34 | for (int i=0; i= 200) && (conn.getResponseCode() < 400)) {
67 | Log.i(TAG, "Uploaded Successfully!");
68 | return true;
69 | } else {
70 | Log.w(TAG, "Upload failed with return-code " + conn.getResponseCode());
71 | return false;
72 | }
73 | } catch (IOException exc) {
74 | Log.e(TAG, "upload failed", exc);
75 | return false;
76 | } finally {
77 | conn.disconnect();
78 | }
79 | }
80 |
81 | private int getContentLength(Uri uri)
82 | throws IOException {
83 | ParcelFileDescriptor pfd = null;
84 | try {
85 | pfd = content.openFileDescriptor(uri, "r");
86 | return (int)pfd.getStatSize();
87 | } finally {
88 | if (pfd != null)
89 | pfd.close();
90 | }
91 | }
92 |
93 | private void pump(InputStream in, OutputStream out, ProgressCallback callback, int len)
94 | throws IOException {
95 | try {
96 | int length,i=0,size=256;
97 | byte[] buffer = new byte[size];
98 |
99 | while ((length = in.read(buffer)) > -1) {
100 | out.write(buffer, 0, length);
101 | out.flush();
102 | callback.onProgress(len, ++i*size);
103 | }
104 | } finally {
105 | Streams.close(in, out);
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter5/example5/MediaCursorAdapter.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter5.example5;
2 |
3 | import android.content.Context;
4 | import android.database.Cursor;
5 | import android.provider.MediaStore;
6 | import android.support.v4.app.LoaderManager;
7 | import android.support.v4.content.Loader;
8 | import android.support.v4.widget.CursorAdapter;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.widget.ImageView;
13 |
14 | import com.packt.asyncandroid.R;
15 |
16 | import java.util.ArrayList;
17 | import java.util.List;
18 |
19 | public class MediaCursorAdapter extends CursorAdapter {
20 |
21 | private LoaderManager mgr;
22 | private LayoutInflater inf;
23 | private int count;
24 | private List ids;
25 |
26 | public MediaCursorAdapter(Context ctx, LoaderManager mgr) {
27 | super(ctx.getApplicationContext(), null, true);
28 | this.mgr = mgr;
29 | inf = (LayoutInflater) ctx.
30 | getSystemService(Context.LAYOUT_INFLATER_SERVICE);
31 | ids = new ArrayList();
32 | }
33 |
34 | @Override
35 | public View newView(final Context ctx, Cursor crsr, ViewGroup parent) {
36 | ImageView view = (ImageView) inf.
37 | inflate(R.layout.ch5_example5_cell, parent, false);
38 | view.setId(MediaCursorAdapter.class.hashCode() + ++count);
39 | mgr.initLoader(
40 | view.getId(), null, new ThumbnailCallbacks(ctx, view));
41 | ids.add(view.getId()); // remember the id, so we can clean it up later
42 | return view;
43 | }
44 |
45 | @Override
46 | public void bindView(View view, final Context context, Cursor cursor) {
47 | Loader> l = mgr.getLoader(view.getId());
48 | ThumbnailLoader loader = (ThumbnailLoader) l;
49 |
50 | Integer mediaId = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.Media._ID));
51 |
52 | ImageView image = (ImageView) view;
53 | image.setImageBitmap(null);
54 | loader.setMediaId(mediaId);
55 | }
56 |
57 | public void destroyLoaders() {
58 | for (Integer id : ids)
59 | mgr.destroyLoader(id);
60 | }
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter5/example5/ThumbnailCallbacks.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter5.example5;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Color;
6 | import android.graphics.drawable.BitmapDrawable;
7 | import android.graphics.drawable.ColorDrawable;
8 | import android.graphics.drawable.Drawable;
9 | import android.graphics.drawable.TransitionDrawable;
10 | import android.os.Bundle;
11 | import android.support.v4.app.LoaderManager;
12 | import android.support.v4.content.Loader;
13 | import android.widget.ImageView;
14 |
15 | /**
16 | * LoaderCallbacks implementation that expects to receive a Bitmap in onLoadFinished
17 | * and will display the bitmap with a nice fade-in effect.
18 | */
19 | public class ThumbnailCallbacks implements LoaderManager.LoaderCallbacks {
20 | private Context context;
21 | private ImageView image;
22 |
23 | public ThumbnailCallbacks(Context context, ImageView image) {
24 | // ensuring that we always only keep a handle on the Application Context
25 | // so that we don't leak references to the Activity!
26 | this.context = context.getApplicationContext();
27 | this.image = image;
28 | }
29 |
30 | @Override
31 | public Loader onCreateLoader(int i, Bundle bundle) {
32 | return new ThumbnailLoader(context);
33 | }
34 |
35 | @Override
36 | public void onLoadFinished(Loader loader, Bitmap b) {
37 | // we could just set the bitmap to the imageview, but
38 | // lets create a drawable that fades from transparent to
39 | // our bitmap, for a bit of extra swankiness...
40 | final TransitionDrawable drawable =
41 | new TransitionDrawable(new Drawable[] {
42 | new ColorDrawable(Color.TRANSPARENT),
43 | new BitmapDrawable(context.getResources(), b)
44 | });
45 |
46 | // set our fade-in drawable to the image view
47 | image.setImageDrawable(drawable);
48 |
49 | // fade in over 0.2 seconds
50 | drawable.startTransition(200);
51 | }
52 |
53 | @Override
54 | public void onLoaderReset(Loader loader) {
55 | // nothing much for us to do here.
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter5/example5/ThumbnailLoader.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter5.example5;
2 |
3 | import android.content.ContentResolver;
4 | import android.content.Context;
5 | import android.graphics.Bitmap;
6 | import android.provider.MediaStore;
7 | import android.support.v4.content.AsyncTaskLoader;
8 |
9 | /**
10 | * An AsyncTaskLoader implementation that loads a Bitmap thumbnail
11 | * in the background from the MediaStore.
12 | *
13 | * There are two good reasons to load these thumbnails off the UI thread:
14 | *
15 | * (1) Loading bitmaps entails IO, which we should always try to keep
16 | * off the main thread if we want our apps to be responsive.
17 | *
18 | * (2) The first time we request a thumbnail from the MediaStore it is
19 | * quite possibly going to have to be created by scaling down the
20 | * original image - this is a potentially expensive operation and
21 | * we definitely don't want to do that on the main thread!
22 | *
23 | * Notice that:
24 | *
25 | * (i) The Loader does not know or care what the bitmap will be used for.
26 | * Its job is purely to load the image, to cache the image for future
27 | * use, and to properly clean up in the lifecycle callbacks.
28 | *
29 | * (ii) Bitmaps are "special", in that their data is managed off-heap, and
30 | * is potentially large. We will clean them up expediently by calling
31 | * recycle when the bitmap is no longer needed.
32 | */
33 | public class ThumbnailLoader extends AsyncTaskLoader {
34 |
35 | private Bitmap data, old;
36 | private Integer mediaId;
37 |
38 | public ThumbnailLoader(Context context, Integer mediaId) {
39 | super(context);
40 | this.mediaId = mediaId;
41 | }
42 |
43 | public ThumbnailLoader(Context context) {
44 | super(context);
45 | }
46 |
47 | public Integer getMediaId() {
48 | return mediaId;
49 | }
50 |
51 | public void setMediaId(Integer mediaId) {
52 | this.mediaId = mediaId;
53 | // notify the machinery of AsyncTaskLoader that something
54 | // has changed, so that it will trigger a reload when
55 | // necessary.
56 | onContentChanged();
57 | }
58 |
59 | @Override
60 | public Bitmap loadInBackground() {
61 | ContentResolver res = getContext().getContentResolver();
62 | if (mediaId != null) {
63 | return MediaStore.Images.Thumbnails.getThumbnail(
64 | res, mediaId, MediaStore.Images.Thumbnails.MINI_KIND, null);
65 | }
66 | return null;
67 | }
68 |
69 | @Override
70 | protected void onStartLoading() {
71 | // if we already have a loaded bitmap, deliver
72 | // it to the callbacks...
73 | if (data != null)
74 | deliverResult(data);
75 |
76 | // if we've been notified that the content
77 | // changed, or if we don't currently have
78 | // a bitmap at all ...
79 | if (takeContentChanged() || data == null) {
80 | // kick-start loading of the new data
81 | forceLoad();
82 | }
83 | }
84 |
85 | @Override
86 | public void deliverResult(Bitmap data) {
87 | super.deliverResult(this.data = data);
88 | }
89 |
90 | @Override
91 | protected void onStopLoading() {
92 | // cancel and make sure to clean up
93 | cancelLoad();
94 | }
95 |
96 | @Override
97 | public void onCanceled(Bitmap data) {
98 | // loading was cancelled before we got
99 | // here, so we must discard the loaded
100 | // bitmap (if there was one).
101 | if (data != null)
102 | data.recycle();
103 | old = null;
104 | }
105 |
106 | @Override
107 | protected void onReset() {
108 | // if we have a bitmap, make sure it is
109 | // recycled asap.
110 | if (data != null) {
111 | data.recycle();
112 | data = null;
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter5/example5/UploadIntentService.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter5.example5;
2 |
3 | import android.app.IntentService;
4 | import android.app.NotificationManager;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.net.Uri;
8 | import android.support.v4.app.NotificationCompat;
9 |
10 | import com.packt.asyncandroid.R;
11 |
12 | public class UploadIntentService extends IntentService {
13 |
14 | private ImageUploader uploader;
15 |
16 | public UploadIntentService() {
17 | super("upload");
18 | }
19 |
20 | @Override
21 | public void onCreate() {
22 | super.onCreate();
23 | uploader = new ImageUploader(getContentResolver());
24 | }
25 |
26 | @Override
27 | protected void onHandleIntent(Intent intent) {
28 | Uri data = intent.getData();
29 | int id = Integer.parseInt(data.getLastPathSegment());
30 | String msg = String.format("Uploading %s.jpg",id);
31 | ProgressNotificationCallback progress =
32 | new ProgressNotificationCallback(this, id, msg);
33 | if (uploader.upload(data, progress)) {
34 | progress.onComplete(
35 | String.format("Successfully uploaded %s.jpg", id));
36 | } else {
37 | progress.onComplete(
38 | String.format("Upload failed %s.jpg", id));
39 | }
40 | }
41 |
42 | private class ProgressNotificationCallback
43 | implements ImageUploader.ProgressCallback {
44 |
45 | private NotificationCompat.Builder builder;
46 | private NotificationManager nm;
47 | private int id, prev;
48 |
49 | public ProgressNotificationCallback(Context ctx, int id, String msg) {
50 | this.id = id;
51 | prev = 0;
52 | builder = new NotificationCompat.Builder(ctx)
53 | .setSmallIcon(android.R.drawable.stat_sys_upload_done)
54 | .setContentTitle(getString(R.string.upload_service))
55 | .setContentText(msg)
56 | .setProgress(100,0,false);
57 | nm = (NotificationManager)
58 | getSystemService(Context.NOTIFICATION_SERVICE);
59 | nm.notify(id, builder.build());
60 | }
61 |
62 | @Override
63 | public void onProgress(int max, int progress) {
64 | int percent = (int)((100f*progress)/max);
65 | if (percent > (prev + 5)) {
66 | builder.setProgress(100, percent, false);
67 | nm.notify(id, builder.build());
68 | prev = percent;
69 | }
70 | }
71 |
72 | @Override
73 | public void onComplete(String msg) {
74 | builder.setProgress(0, 0, false);
75 | builder.setContentText(msg);
76 | nm.notify(id, builder.build());
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter5/example5/UploadPhotoActivity.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter5.example5;
2 |
3 | import android.content.Intent;
4 | import android.database.Cursor;
5 | import android.net.Uri;
6 | import android.os.Bundle;
7 | import android.provider.MediaStore;
8 | import android.support.v4.app.LoaderManager;
9 | import android.support.v4.content.CursorLoader;
10 | import android.support.v4.content.Loader;
11 | import android.view.View;
12 | import android.widget.AdapterView;
13 | import android.widget.GridView;
14 |
15 | import com.packt.asyncandroid.CompatibleActivity;
16 | import com.packt.asyncandroid.R;
17 |
18 | public class UploadPhotoActivity extends CompatibleActivity
19 | implements LoaderManager.LoaderCallbacks {
20 |
21 | private static final String TAG = "asyncandroid";
22 | public static final int MS_LOADER = "ms_crsr".hashCode();
23 |
24 | private MediaCursorAdapter adapter;
25 |
26 | @Override
27 | protected void onCreate(Bundle savedInstanceState) {
28 | super.onCreate(savedInstanceState);
29 |
30 | setContentView(R.layout.ch5_example5_layout);
31 |
32 | adapter = new MediaCursorAdapter(
33 | getApplicationContext(),
34 | getSupportLoaderManager());
35 |
36 | GridView grid = (GridView)findViewById(R.id.grid);
37 | grid.setAdapter(adapter);
38 | grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
39 | @Override
40 | public void onItemClick(AdapterView> parent, View view, int position, long id) {
41 | Cursor cursor = (Cursor)adapter.getItem(position);
42 | int mediaId = cursor.getInt(
43 | cursor.getColumnIndex(MediaStore.Images.Media._ID));
44 | Uri uri = Uri.withAppendedPath(
45 | MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
46 | Integer.toString(mediaId));
47 | Intent intent = new Intent(
48 | UploadPhotoActivity.this, UploadIntentService.class);
49 | intent.setData(uri);
50 | startService(intent);
51 | }
52 | });
53 |
54 | final CursorLoader loader = (CursorLoader)
55 | getSupportLoaderManager().initLoader(MS_LOADER, null, this);
56 |
57 | loader.setUpdateThrottle(10000L);
58 | }
59 |
60 | @Override
61 | public CursorLoader onCreateLoader(int id, Bundle bundle) {
62 | return new CursorLoader(this,
63 | MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
64 | new String[]{
65 | MediaStore.Images.Media._ID,
66 | MediaStore.Images.Media.DISPLAY_NAME
67 | }, "", null, null);
68 | }
69 |
70 | @Override
71 | public void onLoadFinished(Loader loader, Cursor media) {
72 | adapter.changeCursor(media);
73 | }
74 |
75 | @Override
76 | public void onLoaderReset(Loader loader) {
77 | adapter.changeCursor(null);
78 | }
79 |
80 | @Override
81 | protected void onStop() {
82 | super.onStop();
83 |
84 | if (isFinishing()) {
85 | // if we don't want to use these loaders in other activities
86 | // this is our last chance to clean them up.
87 | getSupportLoaderManager().destroyLoader(MS_LOADER);
88 | adapter.destroyLoaders();
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter6/ConcurrentDownloadService.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter6;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.net.Uri;
6 | import android.os.Message;
7 | import android.os.Messenger;
8 | import android.os.Process;
9 | import android.os.RemoteException;
10 | import android.util.Log;
11 |
12 | import com.packt.asyncandroid.LaunchActivity;
13 |
14 | import java.io.IOException;
15 | import java.util.concurrent.Executor;
16 | import java.util.concurrent.Executors;
17 | import java.util.concurrent.ThreadFactory;
18 |
19 | public class ConcurrentDownloadService extends ConcurrentIntentService {
20 |
21 | public static final int MAX_CONCURRENT_DOWNLOADS = 3;
22 | public static final Executor DOWNLOAD_THREAD_POOL =
23 | Executors.newFixedThreadPool(
24 | MAX_CONCURRENT_DOWNLOADS, new ThreadFactory(){
25 | @Override
26 | public Thread newThread(Runnable r) {
27 | Thread t = new Thread(r);
28 | Process.setThreadPriority(
29 | Process.THREAD_PRIORITY_BACKGROUND);
30 | t.setName("download");
31 | return t;
32 | }
33 | });
34 | public static final String DOWNLOAD_FROM_URL = "from_url";
35 | public static final String MESSENGER = "messenger";
36 | public static final int SUCCESSFUL = "download_successful".hashCode();
37 | public static final int FAILED = "download_failed".hashCode();
38 |
39 | public static int startDownload(String url, Context ctx, Messenger messenger) {
40 | Intent intent = new Intent(ctx, ConcurrentDownloadService.class);
41 | intent.putExtra(ConcurrentDownloadService.DOWNLOAD_FROM_URL, url);
42 | intent.putExtra(ConcurrentDownloadService.REQUEST_ID, url.hashCode());
43 | intent.putExtra(ConcurrentDownloadService.MESSENGER, messenger);
44 | ctx.startService(intent);
45 | return url.hashCode();
46 | }
47 |
48 | private SimpleDownloader downloader;
49 |
50 | public ConcurrentDownloadService() {
51 | super(DOWNLOAD_THREAD_POOL);
52 | }
53 |
54 | @Override
55 | public void onCreate() {
56 | super.onCreate();
57 | downloader = new SimpleDownloader(this);
58 | }
59 |
60 | @Override
61 | protected void onHandleIntent(Intent intent) {
62 | Messenger messenger = intent.getParcelableExtra(MESSENGER);
63 | String url = intent.getStringExtra(DOWNLOAD_FROM_URL);
64 | try {
65 | Uri local = downloader.download(url);
66 | sendMessage(messenger, SUCCESSFUL, url.hashCode(), local);
67 | } catch (IOException exc) {
68 | sendMessage(messenger, FAILED, url.hashCode(), null);
69 | }
70 | }
71 |
72 | private void sendMessage(Messenger messenger, int status, int requestId, Uri data) {
73 | try {
74 | messenger.send(
75 | Message.obtain(null, status, requestId, 0, data));
76 | } catch (RemoteException exc) {
77 | Log.e(LaunchActivity.TAG, "unable to send success message to client.");
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter6/ConcurrentIntentService.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter6;
2 |
3 | import android.app.Service;
4 | import android.content.Intent;
5 | import android.os.Handler;
6 | import android.os.IBinder;
7 | import android.os.Message;
8 | import android.util.Log;
9 |
10 | import com.packt.asyncandroid.LaunchActivity;
11 |
12 | import java.util.concurrent.Executor;
13 |
14 | /**
15 | * A Service that implements Intent-driven behavior - like IntentService,
16 | * but uses an ExecutorService to perform the background work instead of
17 | * IntentService's single worker thread, giving complete control over the
18 | * level of concurrency to the sub-class through its configuration of
19 | * the ExecutorService.
20 | *
21 | * Also like IntentService, ConcurrentIntentService will stop itself
22 | * when all pending tasks have completed, so there is no need for
23 | * clients to ever ask the service to stop.
24 | */
25 | public abstract class ConcurrentIntentService extends Service {
26 |
27 | public static final String REQUEST_ID = "request_id";
28 |
29 | private final CompletionHandler handler = new CompletionHandler();
30 | private final Executor executor;
31 | private int counter;
32 |
33 | public ConcurrentIntentService(Executor executor) {
34 | this.executor = executor;
35 | }
36 |
37 | /**
38 | * Runs in the background using the ExecutorService.
39 | *
40 | * When all requests have been handled, this Service stops itself,
41 | * so you should not call {@link #stopSelf}.
42 | *
43 | * @param intent The value passed to {@link
44 | * android.content.Context#startService(android.content.Intent)}.
45 | */
46 | protected abstract void onHandleIntent(Intent intent);
47 |
48 | @Override
49 | public final int onStartCommand(final Intent intent, int flags, int startId) {
50 | counter++;
51 | executor.execute(new Runnable(){
52 | @Override
53 | public void run() {
54 | try {
55 | onHandleIntent(intent);
56 | } finally {
57 | handler.sendMessage(Message.obtain(handler));
58 | }
59 | }
60 | });
61 | return START_NOT_STICKY;
62 | }
63 |
64 | @Override
65 | public IBinder onBind(Intent intent) {
66 | return null;
67 | }
68 |
69 | private class CompletionHandler extends Handler {
70 | @Override
71 | public void handleMessage(Message msg) {
72 | if (--counter == 0) {
73 | Log.i(LaunchActivity.TAG, "no more tasks, stopping");
74 | stopSelf();
75 | } else {
76 | Log.i(LaunchActivity.TAG, counter + " active tasks");
77 | }
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter6/LocalDownloadCache.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter6;
2 |
3 | import android.content.Context;
4 | import android.net.Uri;
5 |
6 | import java.io.BufferedOutputStream;
7 | import java.io.File;
8 | import java.io.FileOutputStream;
9 | import java.io.IOException;
10 | import java.io.OutputStream;
11 |
12 | /**
13 | * Very simple cache - most definitely not advised for
14 | * production use!
15 | */
16 | public class LocalDownloadCache {
17 |
18 | public static final long FIVE_MINUTES = 5L * 60L * 1000L;
19 |
20 | private File dir;
21 |
22 | public LocalDownloadCache(Context ctx) {
23 | dir = ctx.getCacheDir();
24 | }
25 |
26 | public boolean exists(String url) {
27 | File f = getCacheFile(url);
28 | if (f.exists()) {
29 | if (expired(f)) {
30 | f.delete();
31 | return false;
32 | } else {
33 | return true;
34 | }
35 | }
36 | return false;
37 | }
38 |
39 | public Uri get(String url)
40 | throws IOException {
41 | File f = getCacheFile(url);
42 | return Uri.fromFile(f);
43 | }
44 |
45 | public OutputStream getOutputStream(String url)
46 | throws IOException {
47 | File f = getCacheFile(url);
48 | return new BufferedOutputStream(new FileOutputStream(f));
49 | }
50 |
51 | private boolean expired(File f) {
52 | return System.currentTimeMillis() - f.lastModified() > FIVE_MINUTES;
53 | }
54 |
55 | private File getCacheFile(String url) {
56 | String name = url.substring(url.lastIndexOf("/")+1, url.length());
57 | return new File(dir, url.hashCode() + "_" + name);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter6/SimpleDownloader.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter6;
2 |
3 | import android.content.Context;
4 | import android.net.Uri;
5 |
6 | import com.packt.asyncandroid.Streams;
7 |
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 | import java.io.OutputStream;
11 | import java.net.HttpURLConnection;
12 | import java.net.URL;
13 | import java.util.concurrent.ConcurrentHashMap;
14 |
15 | public class SimpleDownloader {
16 |
17 | private LocalDownloadCache cache;
18 | private ConcurrentHashMap locks;
19 |
20 | public SimpleDownloader(Context ctx){
21 | cache = new LocalDownloadCache(ctx);
22 | locks = new ConcurrentHashMap();
23 | }
24 |
25 | public Uri download(String from) throws IOException {
26 | locks.putIfAbsent(from,from);
27 | from = locks.get(from);
28 | try {
29 | synchronized(from) {
30 | if (!cache.exists(from)) {
31 | doDownload(from);
32 | }
33 | return cache.get(from);
34 | }
35 | } finally {
36 | locks.remove(from);
37 | }
38 | }
39 |
40 | private void doDownload(String from) throws IOException {
41 | URL url = new URL(from);
42 | HttpURLConnection conn = (HttpURLConnection)url.openConnection();
43 | try {
44 | InputStream in = conn.getInputStream();
45 | OutputStream out = cache.getOutputStream(from);
46 | int length;
47 | byte[] buffer = new byte[1024];
48 | while ((length = in.read(buffer)) > -1) {
49 | out.write(buffer, 0, length);
50 | out.flush();
51 | }
52 | Streams.close(in, out);
53 | } finally {
54 | conn.disconnect();
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter6/example1/PrimesActivity.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter6.example1;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.os.Handler;
7 | import android.os.Message;
8 | import android.os.Messenger;
9 | import android.util.Log;
10 | import android.view.View;
11 | import android.widget.Button;
12 | import android.widget.LinearLayout;
13 | import android.widget.TextView;
14 | import android.widget.Toast;
15 |
16 | import com.packt.asyncandroid.LaunchActivity;
17 | import com.packt.asyncandroid.R;
18 |
19 | public class PrimesActivity extends Activity {
20 |
21 | private static PrimesHandler handler = new PrimesHandler();
22 | private static Messenger messenger = new Messenger(handler);
23 |
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 |
28 | setContentView(R.layout.ch6_example_layout);
29 | ((TextView)findViewById(R.id.title)).setText(R.string.ch6_ex1);
30 | ((TextView)findViewById(R.id.description)).setText(R.string.ch6_ex1_desc);
31 |
32 | Button go = (Button)findViewById(R.id.go);
33 | go.setOnClickListener(new View.OnClickListener() {
34 | @Override
35 | public void onClick(View v) {
36 | TextView input = (TextView) findViewById(R.id.prime_to_find);
37 | String[] values = input.getText().toString().split(",|\\s");
38 | for (String value : values) {
39 | if (value.trim().matches("[1-9]+[0-9]*")) {
40 | triggerService(Integer.parseInt(value.trim()));
41 | } else {
42 | Toast.makeText(PrimesActivity.this, "not a number!", 5000).show();
43 | }
44 | }
45 | }
46 | });
47 | }
48 |
49 | @Override
50 | protected void onResume() {
51 | super.onResume();
52 | handler.attach((LinearLayout)findViewById(R.id.results));
53 | }
54 |
55 | @Override
56 | protected void onPause() {
57 | super.onPause();
58 | handler.detach();
59 | }
60 |
61 | private void triggerService(int primeToFind) {
62 | Intent intent = new Intent(this, PrimesConcurrentIntentService.class);
63 | intent.putExtra(PrimesConcurrentIntentService.PARAM, primeToFind);
64 | intent.putExtra(PrimesConcurrentIntentService.MSNGR, messenger);
65 | startService(intent);
66 | }
67 |
68 | private static class PrimesHandler extends Handler {
69 | private LinearLayout view;
70 |
71 | @Override
72 | public void handleMessage(Message message) {
73 | if (message.what == PrimesConcurrentIntentService.RESULT) {
74 | if (view != null) {
75 | TextView text = new TextView(view.getContext());
76 | text.setText(message.arg1 + "th prime: " + message.obj.toString());
77 | view.addView(text);
78 | } else {
79 | Log.i(LaunchActivity.TAG, "received a result, ignoring because we're detached");
80 | }
81 | } else if (message.what == PrimesConcurrentIntentService.INVALID) {
82 | if (view != null) {
83 | TextView text = new TextView(view.getContext());
84 | text.setText("Invalid request");
85 | view.addView(text);
86 | }
87 | } else {
88 | super.handleMessage(message);
89 | }
90 | }
91 |
92 | public void attach(LinearLayout view) {
93 | this.view = view;
94 | }
95 |
96 | public void detach() {
97 | this.view = null;
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter6/example1/PrimesConcurrentIntentService.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter6.example1;
2 |
3 | import android.content.Intent;
4 | import android.os.Message;
5 | import android.os.Messenger;
6 | import android.os.RemoteException;
7 | import android.util.Log;
8 |
9 | import com.packt.asyncandroid.LaunchActivity;
10 | import com.packt.asyncandroid.chapter6.ConcurrentIntentService;
11 |
12 | import java.math.BigInteger;
13 | import java.util.concurrent.Executors;
14 | import java.util.concurrent.ThreadFactory;
15 |
16 | public class PrimesConcurrentIntentService extends ConcurrentIntentService {
17 |
18 | private static final int MAX_CONCURRENT_CALCULATIONS = 5;
19 | public static final String PARAM = "prime_to_find";
20 | public static final String MSNGR = "messenger";
21 | public static final int INVALID = "invalid".hashCode();
22 | public static final int RESULT = "nth_prime".hashCode();
23 |
24 | public PrimesConcurrentIntentService() {
25 | super(Executors.newFixedThreadPool(
26 | MAX_CONCURRENT_CALCULATIONS,
27 | new ThreadFactory(){
28 | @Override
29 | public Thread newThread(Runnable r) {
30 | Thread t = new Thread(r);
31 | t.setPriority(Thread.MIN_PRIORITY);
32 | t.setName("download");
33 | return t;
34 | }
35 | }));
36 | }
37 |
38 | @Override
39 | protected void onHandleIntent(Intent intent) {
40 | int primeToFind = intent.getIntExtra(PARAM, -1);
41 | Messenger messenger = intent.getParcelableExtra(MSNGR);
42 | try {
43 | if (primeToFind < 2) {
44 | messenger.send(Message.obtain(null, INVALID));
45 | } else {
46 | messenger.send(Message.obtain(null, RESULT, primeToFind, 0, calculateNthPrime(primeToFind)));
47 | }
48 | } catch (RemoteException anExc) {
49 | Log.e(LaunchActivity.TAG, "Unable to send message", anExc);
50 | }
51 | }
52 |
53 | private BigInteger calculateNthPrime(int primeToFind) {
54 | BigInteger prime = new BigInteger("2");
55 | for (int i=0; i maybeCallback =
43 | new WeakReference(activity);
44 | new AsyncTask(){
45 | @Override
46 | protected BigInteger doInBackground(Void... params) {
47 | BigInteger prime = new BigInteger("2");
48 | for (int i=0; i(){
45 | @Override
46 | protected Void doInBackground(Void... params) {
47 | BigInteger prime = new BigInteger("2");
48 | for (int i=0; i= 11
59 | }
60 |
61 | private void notifyUser(int primeToFind, String result) {
62 | String msg = String.format("The %sth prime is %s",
63 | primeToFind, result);
64 | NotificationCompat.Builder builder =
65 | new NotificationCompat.Builder(this)
66 | .setSmallIcon(android.R.drawable.stat_notify_chat)
67 | .setContentTitle(getString(R.string.primes_service))
68 | .setContentText(msg);
69 | NotificationManager nm = (NotificationManager)
70 | getSystemService(Context.NOTIFICATION_SERVICE);
71 | nm.notify(primeToFind, builder.build());
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter6/example4/BroadcastingPrimesService.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter6.example4;
2 |
3 | import android.app.NotificationManager;
4 | import android.app.Service;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.os.AsyncTask;
8 | import android.os.Binder;
9 | import android.os.IBinder;
10 | import android.support.v4.app.NotificationCompat;
11 | import android.support.v4.content.LocalBroadcastManager;
12 |
13 | import com.packt.asyncandroid.R;
14 |
15 | import java.math.BigInteger;
16 |
17 | public class BroadcastingPrimesService extends Service {
18 |
19 | public static final String PRIMES_BROADCAST = "com.packt.CH6_PRIMES_BROADCAST";
20 | public static final String HANDLED = "intent_handled";
21 | public static final String RESULT = "nth_prime";
22 |
23 | public class Access extends Binder {
24 | public BroadcastingPrimesService getService() {
25 | return BroadcastingPrimesService.this;
26 | }
27 | };
28 |
29 | private final Access binder = new Access();
30 |
31 | @Override
32 | public IBinder onBind(Intent intent) {
33 | return binder;
34 | }
35 |
36 | @Override
37 | public int onStartCommand(Intent intent, int flags, int startId) {
38 | return START_STICKY;
39 | }
40 |
41 | public void calculateNthPrime(final int n) {
42 | new AsyncTask(){
43 | @Override
44 | protected BigInteger doInBackground(Void... params) {
45 | BigInteger prime = new BigInteger("2");
46 | for (int i=0; i= 11
57 | }
58 |
59 | private boolean broadcastResult(String result) {
60 | Intent intent = new Intent(PRIMES_BROADCAST);
61 | intent.putExtra(RESULT, result);
62 | LocalBroadcastManager.getInstance(this).
63 | sendBroadcastSync(intent);
64 | return intent.getBooleanExtra(HANDLED, false);
65 | }
66 |
67 | private void notifyUser(int primeToFind, String result) {
68 | String msg = String.format("The %sth prime is %s",
69 | primeToFind, result);
70 | NotificationCompat.Builder builder =
71 | new NotificationCompat.Builder(this)
72 | .setSmallIcon(android.R.drawable.stat_notify_chat)
73 | .setContentTitle(getString(R.string.primes_service))
74 | .setContentText(msg);
75 | NotificationManager nm = (NotificationManager)
76 | getSystemService(Context.NOTIFICATION_SERVICE);
77 | nm.notify(primeToFind, builder.build());
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter6/example5/DownloadActivity.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter6.example5;
2 |
3 | import android.app.Activity;
4 | import android.net.Uri;
5 | import android.os.Bundle;
6 | import android.os.Handler;
7 | import android.os.Message;
8 | import android.os.Messenger;
9 | import android.util.Log;
10 | import android.widget.ImageView;
11 |
12 | import com.packt.asyncandroid.LaunchActivity;
13 | import com.packt.asyncandroid.R;
14 | import com.packt.asyncandroid.chapter6.ConcurrentDownloadService;
15 |
16 | public class DownloadActivity extends Activity {
17 |
18 | public static final String URL =
19 | "http://www.nasa.gov/images/content/158270main_solarflare.jpg";
20 |
21 | private static final BitmapHandler handler = new BitmapHandler();
22 | private static final Messenger messenger = new Messenger(handler);
23 |
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 |
28 | setContentView(R.layout.ch6_example5_layout);
29 | }
30 |
31 | @Override
32 | protected void onResume() {
33 | super.onResume();
34 |
35 | handler.attach((ImageView)findViewById(R.id.img));
36 |
37 | ConcurrentDownloadService.startDownload(URL, this, messenger);
38 | }
39 |
40 | @Override
41 | protected void onPause() {
42 | super.onPause();
43 |
44 | handler.detach();
45 | }
46 |
47 | private static class BitmapHandler extends Handler {
48 | private ImageView view;
49 |
50 | @Override
51 | public void handleMessage(Message message) {
52 | if (message.what == ConcurrentDownloadService.SUCCESSFUL) {
53 | if (view != null)
54 | view.setImageURI((Uri)message.obj);
55 | } else {
56 | Log.w(LaunchActivity.TAG, "startDownload failed :(");
57 | }
58 | }
59 |
60 | public void attach(ImageView view) {
61 | this.view = view;
62 | }
63 |
64 | public void detach() {
65 | this.view = null;
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter6/example6/NasaImageOfTheDayActivity.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter6.example6;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.net.Uri;
7 | import android.os.Bundle;
8 | import android.util.Log;
9 | import android.view.ViewGroup;
10 | import android.widget.ImageView;
11 | import android.widget.TextView;
12 |
13 | import com.packt.asyncandroid.LaunchActivity;
14 | import com.packt.asyncandroid.R;
15 | import com.packt.asyncandroid.Streams;
16 |
17 | import java.io.IOException;
18 | import java.io.InputStream;
19 |
20 | public class NasaImageOfTheDayActivity extends Activity {
21 |
22 | private static final String RSS_URL = "http://www.nasa.gov/rss/dyn/lg_image_of_the_day.rss";
23 | private static NasaRSSParser parser = new NasaRSSParser();
24 |
25 | @Override
26 | protected void onCreate(Bundle savedInstanceState) {
27 | super.onCreate(savedInstanceState);
28 |
29 | setContentView(R.layout.ch6_example6_layout);
30 | }
31 |
32 | @Override
33 | protected void onResume() {
34 | super.onResume();
35 |
36 | downloadRSS();
37 | }
38 |
39 | @Override
40 | protected void onPause() {
41 | super.onPause();
42 |
43 | // prevent memory leaks by clearing the references
44 | // to the callbacks which, being non-static inner
45 | // classes, have an implicit reference to the Activity.
46 | DownloadTask.clearCallbacks();
47 | }
48 |
49 | private void downloadRSS(){
50 | new DownloadTask(RSS_URL) {
51 | @Override
52 | public NasaRSS convertInBackground(Uri data)
53 | throws Exception {
54 | InputStream in = null;
55 | try {
56 | in = openStream(data);
57 | return parser.parse(in);
58 | } finally {
59 | Streams.close(in);
60 | }
61 | }
62 |
63 | @Override
64 | public void onSuccess(NasaRSS rss) {
65 | for (int i=0; i(url) {
84 | @Override
85 | public Bitmap convertInBackground(Uri data) throws Exception {
86 | InputStream in = null;
87 | try {
88 | BitmapFactory.Options opts = new BitmapFactory.Options();
89 | opts.inSampleSize = sampleSize;
90 | in = openStream(data);
91 | return BitmapFactory.decodeStream(in, null, opts);
92 | } finally {
93 | Streams.close(in);
94 | }
95 | }
96 |
97 | @Override
98 | public void onSuccess(Bitmap data) {
99 | ImageView image = (ImageView)
100 | getRow(i).findViewById(R.id.img);
101 | image.setImageBitmap(data);
102 | }
103 | }.execute(this);
104 | }
105 |
106 | private ViewGroup getRow(int i) {
107 | ViewGroup root = (ViewGroup)findViewById(R.id.root);
108 | return (ViewGroup)root.getChildAt(i);
109 | }
110 |
111 | private InputStream openStream(Uri uri) {
112 | try {
113 | return getContentResolver().openInputStream(uri);
114 | } catch (IOException exc) {
115 | Log.e(LaunchActivity.TAG, "bad uri?", exc);
116 | return null;
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter6/example6/NasaRSS.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter6.example6;
2 |
3 | import android.os.Parcel;
4 | import android.os.Parcelable;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | public class NasaRSS implements Parcelable {
10 |
11 | public static final Parcelable.Creator CREATOR = new Parcelable.Creator(){
12 | @Override
13 | public NasaRSS createFromParcel(Parcel source) {
14 | return new NasaRSS(source);
15 | }
16 |
17 | @Override
18 | public NasaRSS[] newArray(int size) {
19 | return new NasaRSS[size];
20 | }
21 | };
22 |
23 | public static class Item {
24 | public String url;
25 | public String title;
26 | public Item(String url, String title) {
27 | this.url = url;
28 | this.title = title;
29 | }
30 | }
31 |
32 | private List- items;
33 |
34 | public NasaRSS(Parcel parcel) {
35 | items = new ArrayList
- ();
36 | int len = parcel.readInt();
37 | for (int i=0; i();
45 | }
46 |
47 | public void add(String url, String title) {
48 | items.add(new Item(url, title));
49 | }
50 |
51 | public int size() {
52 | return items.size();
53 | }
54 |
55 | public Item get(int i){
56 | return items.get(i);
57 | }
58 |
59 | @Override
60 | public int describeContents() {
61 | return 0;
62 | }
63 |
64 | @Override
65 | public void writeToParcel(Parcel dest, int flags) {
66 | dest.writeInt(items.size());
67 | for (Item i : items) {
68 | dest.writeString(i.url);
69 | dest.writeString(i.title);
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter6/example6/NasaRSSParser.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter6.example6;
2 |
3 | import org.xml.sax.Attributes;
4 | import org.xml.sax.InputSource;
5 | import org.xml.sax.SAXException;
6 | import org.xml.sax.XMLReader;
7 | import org.xml.sax.helpers.DefaultHandler;
8 |
9 | import java.io.InputStream;
10 |
11 | import javax.xml.parsers.SAXParser;
12 | import javax.xml.parsers.SAXParserFactory;
13 |
14 | public class NasaRSSParser {
15 |
16 | private SAXParserFactory factory;
17 |
18 | public NasaRSSParser(){
19 | factory = SAXParserFactory.newInstance();
20 | }
21 |
22 | public NasaRSS parse(InputStream in)
23 | throws Exception {
24 | SAXParser parser = factory.newSAXParser();
25 | XMLReader reader = parser.getXMLReader();
26 | NasaRSSHandler rss = new NasaRSSHandler();
27 | reader.setContentHandler(rss);
28 |
29 | reader.parse(new InputSource(in));
30 | return rss.result;
31 | }
32 |
33 | class NasaRSSHandler extends DefaultHandler {
34 | NasaRSS result = new NasaRSS();
35 |
36 | private String el;
37 | private String url;
38 | private StringBuilder title = new StringBuilder();
39 |
40 | @Override
41 | public void startElement(
42 | String uri, String localName,
43 | String qName, Attributes attributes
44 | ) throws SAXException {
45 | if ("item".equals(qName)) {
46 | title.setLength(0);
47 | url = null;
48 | } else if ("enclosure".equals(qName)) {
49 | url = attributes.getValue("url");
50 | }
51 | el = localName;
52 | }
53 |
54 | @Override
55 | public void characters(char[] ch, int start, int length) throws SAXException {
56 | if ("title".equals(el))
57 | title.append(ch,start,length);
58 | }
59 |
60 | @Override
61 | public void endElement(String uri, String localName, String qName) throws SAXException {
62 | if ("item".equals(localName) && url != null) {
63 | result.add(url, title.toString());
64 | }
65 | }
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter7/example1/AlarmReceiver.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter7.example1;
2 |
3 | import android.app.NotificationManager;
4 | import android.content.BroadcastReceiver;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.support.v4.app.NotificationCompat;
8 |
9 | import com.packt.asyncandroid.R;
10 |
11 | public class AlarmReceiver extends BroadcastReceiver {
12 |
13 | public static final String MSG = "message";
14 |
15 | @Override
16 | public void onReceive(Context context, Intent intent) {
17 | NotificationCompat.Builder builder =
18 | new NotificationCompat.Builder(context)
19 | .setSmallIcon(android.R.drawable.stat_notify_chat)
20 | .setContentTitle(context.getString(R.string.ch7_ex1))
21 | .setContentText(intent.getStringExtra(MSG));
22 | NotificationManager nm = (NotificationManager)
23 | context.getSystemService(Context.NOTIFICATION_SERVICE);
24 | nm.notify(R.string.ch7_ex1, builder.build());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter7/example1/StaticReceiverAlarmActivity.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter7.example1;
2 |
3 | import android.app.Activity;
4 | import android.app.AlarmManager;
5 | import android.app.PendingIntent;
6 | import android.content.Intent;
7 | import android.content.IntentFilter;
8 | import android.os.Bundle;
9 | import android.view.View;
10 | import android.widget.Button;
11 |
12 | import com.packt.asyncandroid.R;
13 |
14 | import java.util.concurrent.TimeUnit;
15 |
16 | public class StaticReceiverAlarmActivity extends Activity {
17 |
18 | private static final long FIVE_SECONDS = TimeUnit.SECONDS.toMillis(5);
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 |
24 | setContentView(R.layout.ch7_example1_layout);
25 |
26 | Button schedule = (Button)findViewById(R.id.schedule);
27 | schedule.setOnClickListener(new View.OnClickListener() {
28 | @Override
29 | public void onClick(View v) {
30 | AlarmManager am = (AlarmManager)
31 | getSystemService(ALARM_SERVICE);
32 | am.set(
33 | AlarmManager.RTC, System.currentTimeMillis()+FIVE_SECONDS,
34 | createPendingIntent());
35 | }
36 | });
37 |
38 | Button unschedule = (Button)findViewById(R.id.unschedule);
39 | unschedule.setOnClickListener(new View.OnClickListener() {
40 | @Override
41 | public void onClick(View v) {
42 | AlarmManager am = (AlarmManager)
43 | getSystemService(ALARM_SERVICE);
44 | am.cancel(createPendingIntent());
45 | }
46 | });
47 | }
48 |
49 | private PendingIntent createPendingIntent() {
50 | Intent intent = new Intent("static_receiver");
51 | intent.putExtra(AlarmReceiver.MSG, "Remember to try out the alarm examples!");
52 | return PendingIntent.getBroadcast(
53 | this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter7/example3/AlarmSettingActivity.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter7.example3;
2 |
3 | import android.app.Activity;
4 | import android.app.AlarmManager;
5 | import android.app.PendingIntent;
6 | import android.content.Intent;
7 | import android.os.Bundle;
8 | import android.text.format.Time;
9 | import android.view.View;
10 | import android.widget.Button;
11 | import android.widget.EditText;
12 |
13 | import com.packt.asyncandroid.R;
14 |
15 | import java.util.Calendar;
16 | import java.util.Date;
17 | import java.util.concurrent.TimeUnit;
18 |
19 | public class AlarmSettingActivity extends Activity {
20 |
21 | private static final long THIRTY_SECONDS = TimeUnit.SECONDS.toMillis(30);
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 |
27 | setContentView(R.layout.ch7_example3_layout);
28 |
29 | Button go = (Button) findViewById(R.id.go);
30 | go.setOnClickListener(new View.OnClickListener() {
31 | @Override
32 | public void onClick(View v) {
33 | EditText input = (EditText) findViewById(R.id.prime_to_find);
34 | String value = input.getText().toString();
35 | if (value.matches("[1-9]+[0-9]*")) {
36 | Intent intent = new Intent("primes_async_receiver");
37 | intent.putExtra(
38 | AsyncBroadcastReceiver.PRIME_TO_FIND, Integer.parseInt(value));
39 | final PendingIntent pending = PendingIntent.getBroadcast(
40 | AlarmSettingActivity.this,
41 | 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
42 |
43 | AlarmManager am = (AlarmManager)
44 | getSystemService(ALARM_SERVICE);
45 |
46 | Calendar calendar = Calendar.getInstance();
47 | if (calendar.get(Calendar.HOUR_OF_DAY) >= 13) {
48 | calendar.add(Calendar.DATE, 1);
49 | }
50 | calendar.set(Calendar.HOUR_OF_DAY, 13);
51 | calendar.set(Calendar.MINUTE, 0);
52 | calendar.set(Calendar.SECOND, 0);
53 |
54 | System.out.println(calendar.getTime());
55 |
56 | am.set(AlarmManager.RTC, System.currentTimeMillis()+THIRTY_SECONDS, pending);
57 | }
58 | }
59 | });
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/java/com/packt/asyncandroid/chapter7/example3/AsyncBroadcastReceiver.java:
--------------------------------------------------------------------------------
1 | package com.packt.asyncandroid.chapter7.example3;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.app.NotificationManager;
5 | import android.content.BroadcastReceiver;
6 | import android.content.Context;
7 | import android.content.Intent;
8 | import android.os.AsyncTask;
9 | import android.os.Build;
10 | import android.os.SystemClock;
11 | import android.support.v4.app.NotificationCompat;
12 |
13 | import com.packt.asyncandroid.R;
14 |
15 | import java.math.BigInteger;
16 |
17 | /**
18 | * Demonstrates a BroadcastReceiver using the "goAsync" method
19 | * introduced in API level 11. Note that we are still subject to
20 | * the 10 second budget, but we can work in the background instead
21 | * of on the main thread without worrying about being shut-down
22 | * when the onReceive method completes.
23 | *
24 | * We MUST call result.finish within our 10 second budget (give or
25 | * take) to terminate the receive otherwise the system will shut
26 | * us down with ANR, so this is not suitable for long running
27 | * tasks or things that have dependencies outside our control (e.g
28 | * data connection speeds).
29 | */
30 | public class AsyncBroadcastReceiver extends BroadcastReceiver {
31 |
32 | public static final String PRIME_TO_FIND = "prime_to_find";
33 |
34 | @SuppressLint("NewApi")
35 | @Override
36 | public void onReceive(final Context context, final Intent intent) {
37 | if (Build.VERSION.SDK_INT > 11) {
38 | final PendingResult result = goAsync();
39 | final int n = intent.getIntExtra(PRIME_TO_FIND, 2);
40 | new AsyncTask(){
41 | @Override
42 | protected BigInteger doInBackground(Void... params) {
43 | BigInteger prime = new BigInteger("2");
44 | for (int i=0; i= 19) {
56 | am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + FIFTEEN_SECONDS, pending);
57 | } else {
58 | am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + FIFTEEN_SECONDS, pending);
59 | }
60 | }
61 | });
62 |
63 | Button getActivities = (Button) findViewById(R.id.get_activities);
64 | getActivities.setOnClickListener(new View.OnClickListener() {
65 | @Override
66 | public void onClick(View v) {
67 | Intent first = new Intent(
68 | SetActivityAlarmActivity.this,
69 | LaunchActivity.class);
70 | first.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP );
71 | Intent second = new Intent(
72 | SetActivityAlarmActivity.this,
73 | SetActivityAlarmActivity.class);
74 | second.putExtra(ALARMED, true);
75 |
76 | final PendingIntent pending = PendingIntent.getActivities(
77 | SetActivityAlarmActivity.this, 0,
78 | new Intent[]{first, second},
79 | PendingIntent.FLAG_UPDATE_CURRENT);
80 |
81 | AlarmManager am = (AlarmManager)
82 | getSystemService(ALARM_SERVICE);
83 |
84 | if (Build.VERSION.SDK_INT >= 19) {
85 | am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + FIFTEEN_SECONDS, pending);
86 | } else {
87 | am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + FIFTEEN_SECONDS, pending);
88 | }
89 | }
90 | });
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/steveliles/AsyncAndroid/c56b0d04fca3afa6fe4e8836763163e9c62d550f/AsyncAndroid/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/steveliles/AsyncAndroid/c56b0d04fca3afa6fe4e8836763163e9c62d550f/AsyncAndroid/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/steveliles/AsyncAndroid/c56b0d04fca3afa6fe4e8836763163e9c62d550f/AsyncAndroid/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/steveliles/AsyncAndroid/c56b0d04fca3afa6fe4e8836763163e9c62d550f/AsyncAndroid/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/book_activity_cell.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
15 |
16 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/book_layout.xml:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch1_example1_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
17 |
18 |
23 |
24 |
29 |
30 |
36 |
37 |
43 |
44 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch1_example2_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
17 |
18 |
23 |
24 |
29 |
30 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch2_example6_layout.xml:
--------------------------------------------------------------------------------
1 |
13 |
14 |
20 |
21 |
27 |
28 |
34 |
35 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch2_example_layout.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
23 |
29 |
30 |
36 |
37 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch2_medley_layout.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
22 |
23 |
29 |
30 |
36 |
37 |
40 |
41 |
45 |
46 |
51 |
52 |
57 |
58 |
63 |
64 |
69 |
70 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch3_example1a_layout.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
15 |
16 |
20 |
21 |
27 |
28 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch3_example1b_layout.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
15 |
16 |
20 |
21 |
27 |
28 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch3_example2_layout.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
15 |
16 |
20 |
21 |
27 |
28 |
33 |
34 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch3_example3_layout.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
15 |
16 |
20 |
21 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch3_example4_layout.xml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
17 |
18 |
22 |
23 |
28 |
29 |
32 |
33 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch3_example5_compass_layout.xml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
21 |
22 |
26 |
27 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch4_example1_layout.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
15 |
16 |
20 |
21 |
25 |
26 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch4_example2_cell.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
12 |
13 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch4_example2_layout.xml:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch4_example3_cell.xml:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch4_example3_layout.xml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch4_example4_layout.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
15 |
16 |
20 |
21 |
25 |
26 |
33 |
34 |
39 |
40 |
41 |
42 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch4_example5_cell.xml:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch4_example5_layout.xml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch5_example5_cell.xml:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch5_example5_layout.xml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch5_example_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
17 |
18 |
23 |
24 |
30 |
31 |
37 |
38 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch6_example5_layout.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
14 |
15 |
20 |
21 |
25 |
26 |
33 |
34 |
40 |
41 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch6_example6_layout.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
11 |
12 |
15 |
16 |
19 |
20 |
23 |
24 |
27 |
28 |
31 |
32 |
35 |
36 |
39 |
40 |
43 |
44 |
47 |
48 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch6_example6_row_img_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
16 |
17 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch6_example6_row_img_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
18 |
19 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch6_example_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
16 |
17 |
22 |
23 |
29 |
30 |
36 |
37 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch7_example1_layout.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
15 |
16 |
21 |
22 |
28 |
29 |
32 |
33 |
38 |
39 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch7_example2_layout.xml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
16 |
17 |
22 |
23 |
29 |
30 |
33 |
34 |
39 |
40 |
45 |
46 |
47 |
48 |
53 |
54 |
57 |
58 |
63 |
64 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch7_example3_layout.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
15 |
16 |
21 |
22 |
28 |
29 |
34 |
35 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch7_example4_layout.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
15 |
16 |
21 |
22 |
28 |
29 |
34 |
35 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch7_example5_layout.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
15 |
16 |
21 |
22 |
28 |
29 |
34 |
35 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/layout/ch7_example6_layout.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
15 |
16 |
21 |
22 |
29 |
30 |
35 |
36 |
42 |
43 |
48 |
49 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/values-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4
4 |
5 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/values-port/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 2
4 |
5 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/values-small-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 2
4 |
5 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/values-small-port/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1
4 |
5 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #ffffffff
4 | #ff000000
5 | #ffff0000
6 | #ffff9900
7 | #ff88dd00
8 | #ff0099ff
9 | #ffff0099
10 | #ff9900ff
11 | #ff229900
12 |
13 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 16dp
3 | 16dp
4 | 30dp
5 |
6 |
--------------------------------------------------------------------------------
/AsyncAndroid/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
21 |
22 |
25 |
26 |
34 |
35 |
41 |
42 |
49 |
50 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Asynchronous Android
2 | ====================
3 |
4 | This project contains the example code for the book "Asynchronous Android" (ISBN 978-1-78328-687-4).
5 |
6 | Check out [the book](http://steveliles.github.io/asynchronous_android.html) for detailed coverage and explanation of all of the constructs presented in these examples. You can easily run the examples on your own device - either build this project or get [the app](https://play.google.com/store/apps/details?id=com.packt.asyncandroid) from Google Play.
7 |
8 | This project has been developed with Android Studio with the Gradle build system and the Android 4.4 (KitKat) platform. With the exception of a few examples that use newer API's, the examples should run fine on Android devices running 2.1 upwards.
9 |
10 | The examples are arranged in a single app, and grouped by chapter as follows:
11 |
12 | Chapter 1 - The Process Model
13 | -----------------------------
14 | In chapter 1 we learn about Android's single threaded event loop and the main/ui thread. The examples show some of the bad things that can happen when you do too much work on the main thread.
15 |
16 | Chapter 2 - Staying responsive with AsyncTask
17 | ---------------------
18 | Covers the poster-child of concurrent programming in Android. We learn how AsyncTask works, how to use it correctly, and how to avoid the common pitfalls that catch out even experienced developers.
19 |
20 | Chapter 3 - Distributing work with Handler, HandlerThread, and Looper
21 | ----------------------------------------------
22 | Details the fundamental and related topics of Handler, HandlerThread, and Looper, and illustrates their use to schedule tasks on the main thread, and to coordinate and communicate work between cooperating background threads.
23 |
24 | Chapter 4 - Asynchronous IO with Loader
25 | ---------------------------------------
26 | Introduces the Loader framework and tackles the important task of loading data asynchronously to keep the user-interface responsive and glitch-free.
27 |
28 | Chapter 5 - Queuing work with IntentService
29 | -------------------------------------------
30 | Gives us the means to perform background operations beyond the scope of a single Activity lifecycle, and to ensure that our work is completed even if the user leaves the application.
31 |
32 | Chapter 6 - Long-running tasks with Service
33 | -------------------------------------------
34 | Extends the capabilities we discovered with IntentService, and gives us control over the level of concurrency applied to our long-running background tasks.
35 |
36 | Chapter 7 - Scheduling work with AlarmManager
37 | ---------------------------------------------
38 | Completes our toolkit, enabling us to arrange for work to be done far in the future and on repeating schedules, to build apps that alert users to new content and start instantly with fresh data.
39 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/steveliles/AsyncAndroid/c56b0d04fca3afa6fe4e8836763163e9c62d550f/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Mar 19 21:43:57 GMT 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':AsyncAndroid'
2 |
--------------------------------------------------------------------------------