tag:blogger.com,1999:blog-67333823399313343702024-03-19T05:44:48.212-07:00Exploring AndroidAnonymoushttp://www.blogger.com/profile/02050057953923357165noreply@blogger.comBlogger3125tag:blogger.com,1999:blog-6733382339931334370.post-68478750157352467002016-02-10T13:10:00.002-08:002016-02-11T03:33:13.034-08:00Setting a Custom Progress Bar using Linear Interpolator<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
Here we will be creating a custom progress bar with linear animation of progress.<br />
<br />
<div style="font-family: 'helvetica neue'; font-size: 14px;">
Screenshot:</div>
<div style="font-family: 'helvetica neue'; font-size: 14px;">
<br /></div>
<div class="separator" style="clear: both; font-family: 'helvetica neue'; font-size: 14px; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihFtoH-JtEUeq-K_vz7_BihsuxLDaxmCSuNXCHgfxMmudJLKn2CLDu9ILS5pTCwv2JcF_QZW4NDRO7vc-NBMzbuPF70tkS3qIkwHm1w97V7M0T5Wy_uw2y35PlTYPxcVSVByc35GBbh0s/s1600/retry.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihFtoH-JtEUeq-K_vz7_BihsuxLDaxmCSuNXCHgfxMmudJLKn2CLDu9ILS5pTCwv2JcF_QZW4NDRO7vc-NBMzbuPF70tkS3qIkwHm1w97V7M0T5Wy_uw2y35PlTYPxcVSVByc35GBbh0s/s320/retry.png" width="180" /></a></div>
<div>
<br /></div>
<br />
We need to create a progress bar in activity_main.xml layout file with a progressDrawable which sets the background color and progress color of ProgressBar widget.<br />
<br />
In activity_main.xml<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #007700;"><ProgressBar</span>
<span style="color: #0000cc;">android:id=</span><span style="background-color: #fff0f0;">"@+id/progress_bar_retry"</span>
<span style="color: #0000cc;">style=</span><span style="background-color: #fff0f0;">"?android:attr/progressBarStyleHorizontal"</span>
<span style="color: #0000cc;">android:layout_width=</span><span style="background-color: #fff0f0;">"match_parent"</span>
<span style="color: #0000cc;">android:layout_height=</span><span style="background-color: #fff0f0;">"5dp"</span>
<span style="color: #0000cc;">android:layout_centerInParent=</span><span style="background-color: #fff0f0;">"true"</span>
<span style="color: #0000cc;">android:indeterminate=</span><span style="background-color: #fff0f0;">"false"</span>
<span style="color: #0000cc;">android:progress=</span><span style="background-color: #fff0f0;">"0"</span>
<span style="color: #0000cc;">android:progressDrawable =</span><span style="background-color: #fff0f0;">"@drawable/progress_bar_retry_style"</span> <span style="color: #007700;">/></span>
</pre>
</div>
<br />
<br />
In progress_bar_retry_style.xml<br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #557799;"><?xml version="1.0" encoding="utf-8"?></span>
<span style="color: #007700;"><layer-list</span> <span style="color: #0000cc;">xmlns:android=</span><span style="background-color: #fff0f0;">"http://schemas.android.com/apk/res/android"</span><span style="color: #007700;">></span>
<span style="color: #007700;"><item</span> <span style="color: #0000cc;">android:id=</span><span style="background-color: #fff0f0;">"@android:id/background"</span><span style="color: #007700;">></span>
<span style="color: #007700;"><shape></span>
<span style="color: #007700;"><solid</span> <span style="color: #0000cc;">android:color=</span><span style="background-color: #fff0f0;">"@color/light_grey"</span><span style="color: #007700;">/></span>
<span style="color: #007700;"></shape></span>
<span style="color: #007700;"></item></span>
<span style="color: #007700;"><item</span> <span style="color: #0000cc;">android:id=</span><span style="background-color: #fff0f0;">"@android:id/progress"</span><span style="color: #007700;">></span>
<span style="color: #007700;"><clip></span>
<span style="color: #007700;"><shape></span>
<span style="color: #007700;"><solid</span> <span style="color: #0000cc;">android:color=</span><span style="background-color: #fff0f0;">"@color/light_red"</span><span style="color: #007700;">/></span>
<span style="color: #007700;"></shape></span>
<span style="color: #007700;"></clip></span>
<span style="color: #007700;"></item></span>
<span style="color: #007700;"></layer-list></span>
</pre>
</div>
<br />
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Now, </span><span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">we have to set maximum value of progress:</span></div>
<b id="docs-internal-guid-87bd4c39-cd20-2c63-c449-5a9f8ca052e8" style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Suppose, if you set max to 100 and your phone has 1400 pixels between 1 and 100 point.</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: transparent; color: black; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Then when you set progress value 1 to 2, it will cover 14 pixels which will not be shown smooth to user.</span></div>
<br />
<span style="font-family: "arial"; font-size: 13.3333333333333px; vertical-align: baseline; white-space: pre-wrap;">So, that’s why we choose max to 500, so that when you cover progress 1 to progress 2 , it will cover 2.8 pixels(1400/500), which will be smooth for users.</span></div>
<br />
<div>
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">private</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">setProgress</span><span style="color: #333333;">()</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">if</span> <span style="color: #333333;">(</span>mRetryHandler <span style="color: #333333;">==</span> <span style="color: #008800; font-weight: bold;">null</span><span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
mRetryHandler <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> Handler<span style="color: #333333;">();</span>
<span style="color: #333333;">}</span>
progress<span style="color: #333333;">++;</span>
count<span style="color: #333333;">++;</span>
mRetryProgressBar<span style="color: #333333;">.</span><span style="color: #0000cc;">setProgress</span><span style="color: #333333;">(</span>progress<span style="color: #333333;">);</span>
<span style="color: #008800; font-weight: bold;">if</span> <span style="color: #333333;">(</span>progress <span style="color: #333333;">>=</span> MAX_PROGRESS<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
Toast<span style="color: #333333;">.</span><span style="color: #0000cc;">makeText</span><span style="color: #333333;">(</span>getActivity<span style="color: #333333;">(),</span> <span style="background-color: #fff0f0;">"Your timer has finished"</span><span style="color: #333333;">,</span> Toast<span style="color: #333333;">.</span><span style="color: #0000cc;">LENGTH_SHORT</span><span style="color: #333333;">).</span><span style="color: #0000cc;">show</span><span style="color: #333333;">();</span>
<span style="color: #008800; font-weight: bold;">return</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span> <span style="color: #008800; font-weight: bold;">else</span> <span style="color: #333333;">{</span>
mRetryHandler<span style="color: #333333;">.</span><span style="color: #0000cc;">postDelayed</span><span style="color: #333333;">(</span>mRetryRunnable<span style="color: #333333;">,</span> <span style="color: #0000dd; font-weight: bold;">200</span><span style="color: #333333;">);</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<br />
<br />
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
</div>
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
</div>
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
<div>
<div dir="ltr" style="line-height: 1.680000032697403; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; color: #333333; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Basically above function will give animation, but it will feel very slow, because here we are updating progress value by 1, 5 times in 1 sec, i.e. by updating progress value to 5 in 1 sec.</span></div>
<b id="docs-internal-guid-87bd4c39-cd1f-a9e2-2fd1-c49cfe302fe6" style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.680000032697403; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; color: #333333; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">We should not calculate intermediate progress values</span><span style="background-color: white; color: #333333; font-family: "arial"; font-size: 13.333333333333332px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">(by what progress values to be incremented in 1 sec). We should use LinerInterpolator to calculate intermediate values of progress to update in a sec.</span></div>
<br />
<span style="background-color: white; color: #333333; font-family: "arial"; font-size: 13.3333333333333px; vertical-align: baseline; white-space: pre-wrap;">Now, we will use ObjectAnimator to set LinearInterpolator to provide smooth animation by setting linearInterpolator on ObjectAnimator instance.</span></div>
<div>
<span style="font-size: 12px;"><span style="font-family: "menlo";"><br />
</span></span></div>
<div>
<span style="color: #660e7a; font-weight: bold;">mRetryObjectAnimator</span>.setInterpolator(<span style="color: #660e7a; font-weight: bold;">mInterpolator</span>);<br />
<br /></div>
<div>
</div>
<div>
<a href="http://developer.android.com/reference/android/animation/ObjectAnimator.html"></a><a href="http://developer.android.com/reference/android/animation/ObjectAnimator.html">http://developer.android.com/reference/android/animation/ObjectAnimator.html</a></div>
<div>
</div>
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
<br /></div>
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
<div style="font-family: 'Helvetica Neue';">
<div dir="ltr" style="margin-left: 0pt;">
<table style="border-collapse: collapse; border: none;"><colgroup><col width="136"></col><col width="404"></col></colgroup><tbody>
<tr style="height: 0px;"><td style="border-bottom: solid #dddddd 1px; border-left: solid #dddddd 1px; border-right: solid #dddddd 1px; border-top: solid #dddddd 1px; padding: 4px 12px 4px 12px; vertical-align: top;"><div dir="ltr" style="line-height: 1.680000032697403; margin-bottom: 0pt; margin-top: 0pt; text-align: right;">
<span style="background-color: #f7f7f7; color: #333333; font-family: "roboto"; font-size: 14px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">static </span><a href="http://developer.android.com/reference/android/animation/ObjectAnimator.html" style="text-decoration: none;"><span style="background-color: #f7f7f7; color: #039be5; font-family: "roboto"; font-size: 14px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">ObjectAnimator</span></a></div>
</td><td style="border-bottom: solid #dddddd 1px; border-left: solid #dddddd 1px; border-right: solid #dddddd 1px; border-top: solid #dddddd 1px; padding: 4px 12px 4px 12px; vertical-align: top;"><div dir="ltr" style="line-height: 1.680000032697403; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<a href="http://developer.android.com/reference/android/animation/ObjectAnimator.html#ofInt(java.lang.Object,%20java.lang.String,%20int...)" style="text-decoration: none;"><span style="background-color: #f7f7f7; color: #039be5; font-family: "roboto"; font-size: 14px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">ofInt</span></a><span style="background-color: #f7f7f7; color: #333333; font-family: "roboto"; font-size: 14px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">(</span><a href="http://developer.android.com/reference/java/lang/Object.html" style="text-decoration: none;"><span style="background-color: #f7f7f7; color: #039be5; font-family: "roboto"; font-size: 14px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Object</span></a><span style="background-color: #f7f7f7; color: #333333; font-family: "roboto"; font-size: 14px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> target, </span><a href="http://developer.android.com/reference/java/lang/String.html" style="text-decoration: none;"><span style="background-color: #f7f7f7; color: #039be5; font-family: "roboto"; font-size: 14px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">String</span></a><span style="background-color: #f7f7f7; color: #333333; font-family: "roboto"; font-size: 14px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> propertyName, int... values)</span></div>
<div dir="ltr" style="line-height: 1.680000032697403; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: #f7f7f7; color: #333333; font-family: "roboto"; font-size: 14px; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Constructs and returns an ObjectAnimator that animates between int values.</span></div>
</td></tr>
</tbody></table>
</div>
</div>
<div style="font-family: 'Helvetica Neue';">
</div>
</div>
<br />
<div>
</div>
<div>
</div>
<div>
<span style="color: rgba(0 , 0 , 0 , 0.682353); font-family: "roboto" , sans-serif; white-space: normal;">This subclass of </span><code style="-webkit-font-smoothing: subpixel-antialiased; background-color: #f7f7f7; color: #006600; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13px; font-stretch: normal; padding: 3px 5px; white-space: normal;"><a href="http://developer.android.com/reference/android/animation/ValueAnimator.html" style="color: #039be5; text-decoration: none;">ValueAnimator</a></code><span style="color: rgba(0 , 0 , 0 , 0.682353); font-family: "roboto" , sans-serif; white-space: normal;"> provides support for animating properties on target objects. The constructors of this class take parameters to define the target object that will be animated as well as the name of the property that will be animated. Appropriate set/get functions are then determined internally and the animation will call these functions as necessary to animate the property.</span></div>
<div>
<span style="font-family: "roboto" , sans-serif;"><span style="color: rgba(0 , 0 , 0 , 0.682353);"><br />
</span></span></div>
<div>
<h5 style="color: rgba(0, 0, 0, 0.682353); font-family: Roboto, sans-serif; font-size: 1em; white-space: normal;">
Parameters<br />
</h5>
<table style="border-collapse: collapse; border-spacing: 0px; border: 0px; color: rgba(0, 0, 0, 0.682353); font-family: Roboto, sans-serif; font-size: 14px; width: 883px;"><tbody>
<tr><th style="background-color: transparent; border: none; color: inherit; font-style: italic; font-weight: normal; padding: 2px 10px; vertical-align: top;">target</th><td style="background-color: transparent; border: none; padding: 2px 10px; vertical-align: top; width: 87.6557191392978%;">The object whose property is to be animated. This object should have a public method on it called <code style="-webkit-font-smoothing: subpixel-antialiased; background-color: #f7f7f7; color: #006600; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13px; font-stretch: normal; padding: 3px 5px;">setName()</code>, where <code style="-webkit-font-smoothing: subpixel-antialiased; background-color: #f7f7f7; color: #006600; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13px; font-stretch: normal; padding: 3px 5px;">name</code> is the value of the <code style="-webkit-font-smoothing: subpixel-antialiased; background-color: #f7f7f7; color: #006600; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 13px; font-stretch: normal; padding: 3px 5px;">propertyName</code> parameter.</td> </tr>
<tr><th style="background-color: transparent; border: none; color: inherit; font-style: italic; font-weight: normal; padding: 2px 10px; vertical-align: top;">propertyName</th><td style="background-color: transparent; border: none; padding: 2px 10px; vertical-align: top;">The name of the property being animated.</td> </tr>
<tr><th style="background-color: transparent; border: none; color: inherit; font-style: italic; font-weight: normal; padding: 2px 10px; vertical-align: top;">values</th><td style="background-color: transparent; border: none; padding: 2px 10px; vertical-align: top;">A set of values that the animation will animate between over time.</td> </tr>
</tbody></table>
</div>
<div>
<span style="font-family: "roboto" , sans-serif;"><span style="color: rgba(0 , 0 , 0 , 0.682353);"><br />
</span></span></div>
<div>
<span style="font-family: "roboto" , sans-serif;"><span style="color: rgba(0 , 0 , 0 , 0.682353);"><br />
</span></span></div>
<div>
<span style="font-family: "roboto" , sans-serif;"><span style="color: rgba(0 , 0 , 0 , 0.682353);"><br />
</span></span></div>
<div>
<span style="font-family: "roboto" , sans-serif;"><span style="color: rgba(0 , 0 , 0 , 0.682353);">So, here is MainActivity.java code:</span></span></div>
<div>
<span style="font-family: "roboto" , sans-serif;"><span style="color: rgba(0 , 0 , 0 , 0.682353);"><br />
</span></span></div>
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">MainActivity</span> <span style="color: #008800; font-weight: bold;">extends</span> AppCompatActivity <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #008800; font-weight: bold;">final</span> <span style="color: #333399; font-weight: bold;">int</span> UPDATE_RETRY_PROGRESS_BAR <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">1001</span><span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">static</span> <span style="color: #008800; font-weight: bold;">final</span> <span style="color: #333399; font-weight: bold;">int</span> MAX_PROGRESS <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">500</span><span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">private</span> Handler mRetryHandler<span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">private</span> ObjectAnimator mRetryObjectAnimator<span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">private</span> ProgressBar mRetryProgressBar<span style="color: #333333;">;</span>
<span style="color: #555555; font-weight: bold;">@Override</span>
<span style="color: #008800; font-weight: bold;">protected</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">onCreate</span><span style="color: #333333;">(</span>Bundle savedInstanceState<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">super</span><span style="color: #333333;">.</span><span style="color: #0000cc;">onCreate</span><span style="color: #333333;">(</span>savedInstanceState<span style="color: #333333;">);</span>
setContentView<span style="color: #333333;">(</span>R<span style="color: #333333;">.</span><span style="color: #0000cc;">layout</span><span style="color: #333333;">.</span><span style="color: #0000cc;">activity_main</span><span style="color: #333333;">);</span>
mRetryProgressBar <span style="color: #333333;">=</span> <span style="color: #333333;">(</span>ProgressBar<span style="color: #333333;">)</span> findViewById<span style="color: #333333;">(</span>R<span style="color: #333333;">.</span><span style="color: #0000cc;">id</span><span style="color: #333333;">.</span><span style="color: #0000cc;">progress_bar_retry</span><span style="color: #333333;">);</span>
mRetryHandler <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> RetryHandler<span style="color: #333333;">();</span>
<span style="color: #333399; font-weight: bold;">int</span> timeFromServer <span style="color: #333333;">=</span> <span style="color: #0000dd; font-weight: bold;">60</span><span style="color: #333333;">;</span>
Message msg <span style="color: #333333;">=</span> mRetryHandler<span style="color: #333333;">.</span><span style="color: #0000cc;">obtainMessage</span><span style="color: #333333;">(</span>UPDATE_RETRY_PROGRESS_BAR<span style="color: #333333;">,</span> timeFromServer<span style="color: #333333;">,</span> <span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">);</span>
mRetryHandler<span style="color: #333333;">.</span><span style="color: #0000cc;">sendMessage</span><span style="color: #333333;">(</span>msg<span style="color: #333333;">);</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">RetryHandler</span> <span style="color: #008800; font-weight: bold;">extends</span> Handler <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">private</span> LinearInterpolator mInterpolator<span style="color: #333333;">;</span>
<span style="color: #555555; font-weight: bold;">@Override</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">handleMessage</span><span style="color: #333333;">(</span>Message msg<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">super</span><span style="color: #333333;">.</span><span style="color: #0000cc;">handleMessage</span><span style="color: #333333;">(</span>msg<span style="color: #333333;">);</span>
<span style="color: #008800; font-weight: bold;">switch</span> <span style="color: #333333;">(</span>msg<span style="color: #333333;">.</span><span style="color: #0000cc;">what</span><span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">case</span> <span style="color: #997700; font-weight: bold;">UPDATE_RETRY_PROGRESS_BAR:</span>
<span style="color: #333399; font-weight: bold;">int</span> timeDuration <span style="color: #333333;">=</span> msg<span style="color: #333333;">.</span><span style="color: #0000cc;">arg1</span><span style="color: #333333;">;</span>
<span style="color: #888888;">// for smooth progress bar update.</span>
mRetryObjectAnimator <span style="color: #333333;">=</span>
ObjectAnimator<span style="color: #333333;">.</span><span style="color: #0000cc;">ofInt</span><span style="color: #333333;">(</span>mRetryProgressBar<span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"progress"</span><span style="color: #333333;">,</span> MAX_PROGRESS<span style="color: #333333;">);</span>
mRetryObjectAnimator<span style="color: #333333;">.</span><span style="color: #0000cc;">setDuration</span><span style="color: #333333;">(</span>timeDuration <span style="color: #333333;">*</span> <span style="color: #0000dd; font-weight: bold;">1000</span><span style="color: #333333;">);</span>
<span style="color: #008800; font-weight: bold;">if</span> <span style="color: #333333;">(</span>mInterpolator <span style="color: #333333;">==</span> <span style="color: #008800; font-weight: bold;">null</span><span style="color: #333333;">)</span> mInterpolator <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> LinearInterpolator<span style="color: #333333;">();</span>
mRetryObjectAnimator<span style="color: #333333;">.</span><span style="color: #0000cc;">setInterpolator</span><span style="color: #333333;">(</span>mInterpolator<span style="color: #333333;">);</span>
mRetryObjectAnimator<span style="color: #333333;">.</span><span style="color: #0000cc;">start</span><span style="color: #333333;">();</span>
mRetryObjectAnimator<span style="color: #333333;">.</span><span style="color: #0000cc;">addListener</span><span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">new</span> Animator<span style="color: #333333;">.</span><span style="color: #0000cc;">AnimatorListener</span><span style="color: #333333;">()</span> <span style="color: #333333;">{</span>
<span style="color: #555555; font-weight: bold;">@Override</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">onAnimationStart</span><span style="color: #333333;">(</span>Animator animation<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #333333;">}</span>
<span style="color: #555555; font-weight: bold;">@Override</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">onAnimationEnd</span><span style="color: #333333;">(</span>Animator animation<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
Toast<span style="color: #333333;">.</span><span style="color: #0000cc;">makeText</span><span style="color: #333333;">(</span>MainActivity<span style="color: #333333;">.</span><span style="color: #0000cc;">this</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"Your timer has finished"</span><span style="color: #333333;">,</span> Toast<span style="color: #333333;">.</span><span style="color: #0000cc;">LENGTH_SHORT</span><span style="color: #333333;">).</span><span style="color: #0000cc;">show</span><span style="color: #333333;">();</span>
<span style="color: #333333;">}</span>
<span style="color: #555555; font-weight: bold;">@Override</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">onAnimationCancel</span><span style="color: #333333;">(</span>Animator animation<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #333333;">}</span>
<span style="color: #555555; font-weight: bold;">@Override</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">onAnimationRepeat</span><span style="color: #333333;">(</span>Animator animation<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">});</span>
<span style="color: #008800; font-weight: bold;">break</span><span style="color: #333333;">;</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<br />
<br />
Demo:<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dwc9kepzxxif8MnXcrqQ7cndgcr4Eqme0mEA20_0zE5Ln0PTNcpRiyucpsc6d6TEMATUElX-0cMJPqxi-csIg' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div>
<br />
<br />
<br />
Reference:<br />
<a href="http://developer.android.com/reference/android/animation/ObjectAnimator.html" style="background-color: white; color: #771100; font-family: 'Helvetica Neue'; line-height: 19.6000003814697px; text-decoration: none;">http://developer.android.com/reference/android/animation/ObjectAnimator.html</a><br />
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
</div>
</div>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/02050057953923357165noreply@blogger.com3tag:blogger.com,1999:blog-6733382339931334370.post-40790780975646961292015-12-30T10:36:00.001-08:002016-02-28T02:21:39.554-08:00Understanding Android Activity and Fragment Lifecycle<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: left;">
<span style="background-color: white; color: rgba(0 , 0 , 0 , 0.682353); font-family: "roboto" , sans-serif; font-size: 16px; line-height: 24px;">Android activity lifecycle is pretty simple to understand if you understand the different states an activity goes through when it starts and when it tears down.</span></div>
<div style="text-align: left;">
<span style="background-color: white; color: rgba(0 , 0 , 0 , 0.682353); font-family: "roboto" , sans-serif; font-size: 16px; line-height: 24px;"><br />
</span></div>
<div style="text-align: left;">
<span style="background-color: white; color: rgba(0 , 0 , 0 , 0.682353); font-family: "roboto" , sans-serif; font-size: 16px; line-height: 24px;"><b>An activity has six states:</b></span></div>
<div style="text-align: left;">
</div>
<ol style="text-align: left;">
<li><span style="font-family: "roboto" , sans-serif;"><span style="line-height: 24px;">Created</span></span></li>
<li><span style="font-family: "roboto" , sans-serif;"><span style="line-height: 24px;">Started</span></span></li>
<li><span style="font-family: "roboto" , sans-serif;"><span style="line-height: 24px;">Resumed</span></span></li>
<li><span style="font-family: "roboto" , sans-serif;"><span style="line-height: 24px;">Paused</span></span></li>
<li><span style="font-family: "roboto" , sans-serif;"><span style="line-height: 24px;">Stopped</span></span></li>
<li><span style="font-family: "roboto" , sans-serif;"><span style="line-height: 24px;">Destroyed</span></span></li>
</ol>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://developer.android.com/images/training/basics/basic-lifecycle.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://developer.android.com/images/training/basics/basic-lifecycle.png" height="283" width="640" /></a></div>
<span style="background-color: white; color: rgba(0 , 0 , 0 , 0.682353); font-family: "roboto" , sans-serif; font-size: 16px; line-height: 24px;"><br />
</span> <span style="background-color: white; color: rgba(0 , 0 , 0 , 0.682353); font-family: "roboto" , sans-serif; font-size: 16px; line-height: 24px;">And there are seven callback methods used by the activity to move between different states:</span><br />
<div>
<div dir="rtl" style="text-align: right;">
<br /></div>
<div>
<ul style="text-align: left;">
<li><span style="background-color: white; color: rgba(0 , 0 , 0 , 0.682353); font-family: "roboto" , sans-serif; font-size: 16px; line-height: 24px;">onCreate() : This is the first callback android activity receives, when you start an activity. Here, you build and wire up your UI, initialize your global variables etc. Once that's done, your activity has been created.</span></li>
</ul>
<ul style="text-align: left;">
<li>onStart() : This is called when the activity is becoming visible to the user.</li>
</ul>
<ul style="text-align: left;">
<li>onResume() : This is called when the activity will start interacting with the user. Here, at this point, the activity is in the foreground and the user can interact with it. The resumed state is sometimes referred to as the "running" state.</li>
</ul>
<ul style="text-align: left;">
<li>onPause() : This callback starts when the current activity is partially obscured by another activity or a dialog. This is typically used to commit unsaved changes to persistent data, stop animations, remove runnables and other things that may be consuming CPU, etc. The paused activity does not receive user input and cannot execute any code.</li>
</ul>
<ul style="text-align: left;">
<li>onStop() : This is called when the activity is no longer visible to the user and goes in the background, because another activity has been resumed and is covering this one. This may happen either because a new activity is being started, an existing one is being brought in front of this one, or this one is being destroyed. While stopped, the activity instance and all its state information such as member variables is retained, but it cannot execute any code.</li>
</ul>
<ul style="text-align: left;">
<li>onDestroy() : This is the final callback android activity receives, before it is destroyed. It can happen either because activity is finishing(someone called finish() on it) or because the system is temporarily destroying this instance of the activity to save space. Most apps don't need to implement this method because local class references are destroyed with the activity and your activity should perform most cleanup during onPause() and onStop(). However, if your activity includes background threads that you created during onCreate() or other long-running resources that could potentially leak memory if not properly closed, you should kill them during onDestroy(). </li>
</ul>
<div>
<span style="color: rgba(0 , 0 , 0 , 0.682352941176471); font-family: "roboto" , sans-serif;"><span style="background-color: white; font-size: 14px; line-height: 24px;"> </span></span>So, that's sum up the basic activity lifecycle.<br />
<br />
<b> Callbacks that are executed in following scenarios:</b><br />
1)<span style="font-family: "helvetica neue"; font-size: 14px;">When Activity starts and becomes visible:</span><br />
<span style="font-family: "helvetica neue"; font-size: 14px;"> onCreate()->onStart()->onResume()</span><br />
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
</div>
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
2)When phone/device rotates:</div>
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
onPause()->onStop()->onDestroy()->onCreate()->onStart()->onResume()</div>
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
</div>
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
3)When you press home button (activity goes in background, becomes invisible):</div>
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
onPause()->onStop()</div>
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
<br clear="none" /></div>
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
4)When you choose your app from recent apps(your activity comes again to foreground):</div>
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
onRestart()->onStart()->onResume()<br />
<br />
5)<span style="background-color: white; color: #222426; font-family: "arial" , "helvetica neue" , "helvetica" , sans-serif; font-size: 15px; line-height: 19.5px;">When you press the </span><strong style="background-color: white; border: 0px; color: #222426; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 15px; line-height: 19.5px; margin: 0px; padding: 0px;">back button on your activity</strong><span style="background-color: white; color: #222426; font-family: "arial" , "helvetica neue" , "helvetica" , sans-serif; font-size: 15px; line-height: 19.5px;">:</span></div>
onBackPressed()->finish()->onPause()->onStop()->onDestroy()<br />
<br />
6)When you<b> add a fragment </b>to your activity using add():<br />
<span style="background-color: white; font-family: "menlo"; font-size: 9pt;">Fragment fragmentA = FragmentA.</span><span style="font-family: "menlo"; font-size: 9pt; font-style: italic;">newInstance</span><span style="background-color: white; font-family: "menlo"; font-size: 9pt;">(</span><span style="color: green; font-family: "menlo"; font-size: 9pt; font-weight: bold;">"hello"</span><span style="background-color: white; font-family: "menlo"; font-size: 9pt;">, </span><span style="color: green; font-family: "menlo"; font-size: 9pt; font-weight: bold;">"frag A"</span><span style="background-color: white; font-family: "menlo"; font-size: 9pt;">);</span><br />
<pre style="background-color: white; font-family: Menlo; font-size: 9pt;"> FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.<span style="color: #660e7a; font-style: italic; font-weight: bold;">container</span>, fragmentA)
.addToBackStack(<span style="color: navy; font-weight: bold;">null</span>)
.commit();</pre>
<pre style="background-color: white; font-family: Menlo; font-size: 9pt;"> </pre>
<pre style="background-color: white; font-family: Menlo; font-size: 9pt;"> Callbacks:</pre>
<pre style="background-color: white; font-family: Menlo; font-size: 9pt;"> FragmentA: newInstance()
FragmentA: FragmentA()
FragmentA: onAttach()
FragmentA: onCreate()
FragmentA: onCreateView()
FragmentA: onViewCreated()
FragmentA: onActivityCreated()
FragmentA: onStart()
FragmentA: onResume()</pre>
<pre style="background-color: white; font-family: Menlo; font-size: 9pt;"></pre>
<pre style="background-color: white; font-family: Menlo; font-size: 9pt;"> <span style="background-color: transparent; font-family: "helvetica neue"; font-size: 15px;">What addToBackStack(null/String) means:--</span></pre>
<br />
<div style="font-family: 'Helvetica Neue'; font-size: 14px;">
<ul style="text-align: left;">
<li><span style="font-size: 15px;">It means</span> <b><span style="font-size: 15px;">adding this transaction(operation : add</span> <span style="font-size: 15px;">fragment A to the container)</span><span style="font-size: 15px;"> to the Back Stack</span></b><span style="font-size: 15px;">.</span><span style="background-color: white; color: rgba(0 , 0 , 0 , 0.682353); font-family: "roboto" , sans-serif;">This means that the transaction will be remembered after it is committed(as added in back stack), and will reverse its operation when later popped off the stack.</span></li>
<li><b style="color: #222222; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px;">If you want to navigate to the previous fragment add it to backstack. </b></li>
</ul>
</div>
<br />
7)When you press home button on a fragment that is added to an activity :<br />
MainActivity: onPause()<br />
FragmentA: onPause()<br />
MainActivity: onStop()<br />
FragmentA: onStop()<br />
<br />
<br />
8)When you choose your app from recent apps(your fragment comes again to foreground):<br />
MainActivity: onRestart()<br />
MainActivity: onStart()<br />
FragmentA: onStart()<br />
MainActivity: onResume()<br />
FragmentA: onResume()<br />
<br />
9)When you press <b>back button on your fragment:</b><br />
<b> </b>MainActivity: onBackPressed()<br />
FragmentA: onPause()<br />
FragmentA: onStop()<br />
FragmentA: onDestroy()<br />
FragmentA: onDetach()<br />
<br />
<div style="font-family: 'Helvetica Neue'; text-align: justify;">
<span style="font-size: 15px;"> </span><span style="font-family: "arial"; font-size: 15.3333333333333px; line-height: 1.38; white-space: pre-wrap;"> Back button pressed on FragmentA:--</span></div>
<span id="docs-internal-guid-8b3b47c4-dc5f-16fc-5607-a95aba7856f8"></span><br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
</div>
<span id="docs-internal-guid-8b3b47c4-dc5f-16fc-5607-a95aba7856f8"> </span><br />
<ul><span id="docs-internal-guid-8b3b47c4-dc5f-16fc-5607-a95aba7856f8">
<li><span style="font-family: "arial"; font-size: 15.3333333333333px; line-height: 1.38; white-space: pre-wrap;">And so when you press back button on the FragmentA, then MainActivity onBackPressed() will call fm.popBackStack() and the top back stack entry(transaction) will be popped from the stack. </span></li>
<li><span style="font-family: "arial"; font-size: 15.3333333333333px; white-space: pre-wrap;">And when the transaction will be popped out from the stack, its operation will be reversed(</span>operation :<span style="font-family: "arial"; font-size: 15.3333333333333px; white-space: pre-wrap;"> remove fragment A from the container). And so, the fragment will be removed and destroyed.</span></li>
</span></ul>
<span id="docs-internal-guid-8b3b47c4-dc5f-16fc-5607-a95aba7856f8"> </span><br />
<div style="font-family: 'Helvetica Neue'; font-size: 14px; text-align: justify;">
<br /></div>
10)When you remove a fragment from an activity using remove():<br />
<span style="background-color: white; font-family: "menlo"; font-size: 9pt;">FragmentManager fm = getSupportFragmentManager();</span><br />
<pre style="background-color: white; font-family: Menlo; font-size: 9pt;"> Fragment fragA = fm.findFragmentById(R.id.<span style="color: #660e7a; font-style: italic; font-weight: bold;">container</span>);
<span style="color: navy; font-weight: bold;">if </span>(fragA == <span style="color: navy; font-weight: bold;">null</span>) {
<span style="color: navy; font-weight: bold;">return</span>;
}
<span style="color: grey; font-style: italic;"> // Using popBackStack function to remove fragment A from main activity</span><span style="color: grey; font-style: italic;"> </span></pre>
<pre style="background-color: white; font-family: Menlo; font-size: 9pt;"><span style="color: grey; font-style: italic;"> // if (fm.getBackStackEntryCount() > 0) {</span><span style="color: grey; font-style: italic;"> </span></pre>
<pre style="background-color: white; font-family: Menlo; font-size: 9pt;"><span style="color: grey; font-style: italic;"> // fm.popBackStack();</span><span style="color: grey; font-style: italic;"> </span></pre>
<pre style="background-color: white; font-family: Menlo; font-size: 9pt;"><span style="color: grey; font-style: italic;"> // }</span><span style="color: grey; font-style: italic;"> </span></pre>
<pre style="background-color: white; font-family: Menlo; font-size: 9pt;"><span style="color: navy; font-weight: bold;"> if </span>(fragA <span style="color: navy; font-weight: bold;">instanceof </span>FragmentA) {
fm.beginTransaction().remove(fragA).commit();
}</pre>
<pre style="background-color: white; font-family: Menlo; font-size: 9pt;"></pre>
<pre style="background-color: white; font-family: Menlo; font-size: 9pt;"> Callbacks:--</pre>
<pre style="background-color: white; font-family: Menlo; font-size: 9pt;"> FragmentA: onPause()
FragmentA: onStop()</pre>
<pre style="background-color: white; font-family: menlo; font-size: 9pt; text-align: justify;"></pre>
<pre style="background-color: white; font-family: menlo; font-size: 9pt; text-align: justify;"> </pre>
<pre style="background-color: white; font-family: menlo; text-align: justify;"><span style="font-size: 9pt;"> </span><span style="font-size: 9pt;">11)</span><span style="font-family: "arial"; line-height: 1.38; white-space: pre-wrap;">Now, suppose we have another fragment B to be added in that same container where fragment A has been added in the MainActivity's container.</span></pre>
<span id="docs-internal-guid-3f31f65c-2759-41df-3409-49139640e423"><br /></span>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span id="docs-internal-guid-3f31f65c-2759-41df-3409-49139640e423"><span style="background-color: white; color: navy; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;"> case </span><a href="http://r.id/" style="text-decoration: none;"><span style="background-color: white; color: #1155cc; font-family: "arial"; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">R.id</span></a><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">.</span><span style="background-color: white; color: #660e7a; font-family: "arial"; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">btn_add_fragment_A</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">:</span></span></div>
<span id="docs-internal-guid-3f31f65c-2759-41df-3409-49139640e423"> </span><br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span id="docs-internal-guid-3f31f65c-2759-41df-3409-49139640e423"><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> <span style="font-size: x-small;"> </span>FragmentA fragmentA = FragmentA.</span><span style="background-color: white; font-family: "arial"; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">newInstance</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">(</span><span style="background-color: white; color: green; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">"hello"</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="background-color: white; color: green; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">"frag A"</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">);</span></span></div>
<span id="docs-internal-guid-3f31f65c-2759-41df-3409-49139640e423"> </span><br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span id="docs-internal-guid-3f31f65c-2759-41df-3409-49139640e423"><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> Log.</span><span style="background-color: white; font-family: "arial"; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">d</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">(</span><span style="background-color: white; color: #660e7a; font-family: "arial"; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">TAG</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="background-color: white; color: green; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">"getting fragmentManager inside btn_add_fragment_A click"</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">);</span></span></div>
<span id="docs-internal-guid-3f31f65c-2759-41df-3409-49139640e423"> <div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> fragmentManager = getSupportFragmentManager();</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> fragmentManager.beginTransaction()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> .replace(R.id.</span><span style="background-color: white; color: #660e7a; font-family: "arial"; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">container</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">, fragmentA)</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> .addToBackStack(</span><span style="background-color: white; color: navy; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">null</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">)</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> .commit();</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: navy; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">break</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">;</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;"> Callbacks:-</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"><span style="font-size: x-small;"> </span>FragmentA: newInstance()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentA: FragmentA()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> MainActivity: getting fragmentManager inside btn_add_fragment_A click</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentA: onAttach()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentA: onCreate()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentA: onCreateView()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentA: onViewCreated()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentA: onActivityCreated()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentA: onStart()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentA: onResume()</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; color: navy; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;"> case </span><a href="http://r.id/" style="text-decoration: none;"><span style="background-color: white; color: #1155cc; font-family: "arial"; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">R.id</span></a><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">.</span><span style="background-color: white; color: #660e7a; font-family: "arial"; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">btn_add_fragment_B</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: #660e7a; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">fragmentB </span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">= FragmentB.</span><span style="background-color: white; font-family: "arial"; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">newInstance</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">(</span><span style="background-color: white; color: green; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">"hello"</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="background-color: white; color: green; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">"frag B"</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">);</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> Log.</span><span style="background-color: white; font-family: "arial"; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">d</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">(</span><span style="background-color: white; color: #660e7a; font-family: "arial"; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">TAG</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="background-color: white; color: green; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">"getting fragmentManager inside btn_add_fragment_B click"</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">);</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> fragmentManager = getSupportFragmentManager();</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> fragmentManager.beginTransaction()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> .replace(R.id.</span><span style="background-color: white; color: #660e7a; font-family: "arial"; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">container</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="background-color: white; color: #660e7a; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">fragmentB</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">)</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> .addToBackStack(</span><span style="background-color: white; color: navy; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">null</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">)</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> .commit();</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: navy; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">break</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">;</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;"> Callbacks:- </span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentB: newInstance()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentB: FragmentB()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> MainActivity: getting fragmentManager inside btn_add_fragment_B click</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;"> FragmentA: onPause()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;"> FragmentA: onStop()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentB: onAttach()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentB: onCreate()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentB: onCreateView()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentB: onViewCreated()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentB: onActivityCreated()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentB: onStart()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentB: onResume()</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> Note : When fragment B is added, FragmentA</span><span style="background-color: white; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">’</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">s onPause() and onStop() is called but not onDetach() & onDestroy() because fragment A’s view is just removed from container and fragment A is not getting destroyed like it does on back press. Fragment B’s view is added to the container now.</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; color: navy; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;"> case </span><a href="http://r.id/" style="text-decoration: none;"><span style="background-color: white; color: #1155cc; font-family: "arial"; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">R.id</span></a><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">.</span><span style="background-color: white; color: #660e7a; font-family: "arial"; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">btn_remove_fragment_B</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">:</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> Log.</span><span style="background-color: white; font-family: "arial"; font-style: italic; vertical-align: baseline; white-space: pre-wrap;">d</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">(</span><span style="background-color: white; color: #660e7a; font-family: "arial"; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">TAG</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="background-color: white; color: green; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">"getting fragmentManager inside btn_remove_fragment_B click"</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">);</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> fragmentManager = getSupportFragmentManager();</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> fragmentManager.popBackStack();</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; color: navy; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">break</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">;</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> Added fragment A => .replace(R.id.</span><span style="background-color: white; color: #660e7a; font-family: "arial"; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">container</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">, fragmentA) => addToBackStack(</span><span style="background-color: white; color: navy; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">null</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">)</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> Added fragment B => .replace(R.id.</span><span style="background-color: white; color: #660e7a; font-family: "arial"; font-style: italic; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">container</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">, </span><span style="background-color: white; color: #660e7a; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">fragmentB</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">) => addToBackStack(</span><span style="background-color: white; color: navy; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">null</span><span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;">)</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> Remove fragment B => fragmentManager.popBackStack();</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> MainActivity: getting fragmentManager inside btn_remove_fragment_B click</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentB: onPause()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentB: onStop()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentB: onDestroy()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentB: onDetach()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: white; font-family: "arial"; font-weight: 700; vertical-align: baseline; white-space: pre-wrap;">FragmentA: onCreateView()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentA: onViewCreated()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentA: onActivityCreated()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentA: onStart()</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> FragmentA: onResume()</span></div>
<br /><div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> Explanation: Why while removing and destroying fragment B using popBackStack(), fragment A view was created again and resumed?</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> </span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-align: justify;">
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"> Ans: When you added fragment B, you used replace() and addToBackStack(), so all the fragments were removed from the container, and fragment B was added to the container. And, also this transaction was recorded in the Back stack. So, when fm.popBackStack() is called after fragment B has been added, first the transaction is popped out from the back stack and so the operations reverted itself, therefore fragment b is removed from the container and destroyed and all other fragments are added, for our case fragment A's view is added to the container. Also noted that fragment A's onAttach & onCreate() is not called because it has already been created & attached to the MainActivity earlier.</span><br />
<span style="background-color: white; font-family: "arial"; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
</span><br />
<pre style="background-color: white; font-family: menlo; font-size: 9pt; text-align: justify;"></pre>
References:<br />
<a href="http://developer.android.com/training/basics/activity-lifecycle/starting.html">http://developer.android.com/training/basics/activity-lifecycle/starting.html</a><br />
<a href="http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle">http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle</a><br />
<a href="http://developer.android.com/training/basics/activity-lifecycle/stopping.html">http://developer.android.com/training/basics/activity-lifecycle/stopping.html</a><br />
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<span style="color: rgba(0 , 0 , 0 , 0.682352941176471); font-family: "roboto" , sans-serif;"><span style="line-height: 24px;"><br />
</span></span></div>
</div>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/02050057953923357165noreply@blogger.com0tag:blogger.com,1999:blog-6733382339931334370.post-25270688173287357802015-06-13T05:01:00.002-07:002015-08-31T13:36:32.600-07:00Sending an image from an android app to a webserver<div dir="ltr" style="text-align: left;" trbidi="on">
<h2 style="text-align: left;">
</h2>
<div>
<br /></div>
<div>
I thought to start with this topic because when I first started programming for android, this problem took a lot of time, so I thought to share this piece with all of you.<br />
<br />
I have used httpmime-4.1 jar in the android application to enable sending of the images.<br />
<br />
It requires just three steps.</div>
<div>
<br /></div>
<div>
First, create a new android application and paste the below code in your activity_main.xml.<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .2em .2em .2em .2em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #557799;"><?xml version="1.0" encoding="utf-8"?></span>
<span style="color: #007700;"><LinearLayout</span> <span style="color: #0000cc;">xmlns:android=</span><span style="background-color: #fff0f0;">"http://schemas.android.com/apk/res/android"</span>
<span style="color: #0000cc;">android:layout_width=</span><span style="background-color: #fff0f0;">"match_parent"</span>
<span style="color: #0000cc;">android:layout_height=</span><span style="background-color: #fff0f0;">"match_parent"</span>
<span style="color: #0000cc;">android:orientation=</span><span style="background-color: #fff0f0;">"vertical"</span> <span style="color: #007700;">></span>
<span style="color: #007700;"><ImageView</span>
<span style="color: #0000cc;">android:id=</span><span style="background-color: #fff0f0;">"@+id/iv_image"</span>
<span style="color: #0000cc;">android:layout_width=</span><span style="background-color: #fff0f0;">"wrap_content"</span>
<span style="color: #0000cc;">android:layout_height=</span><span style="background-color: #fff0f0;">"350dp"</span>
<span style="color: #0000cc;">android:scaleType=</span><span style="background-color: #fff0f0;">"centerCrop"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><ProgressBar</span>
<span style="color: #0000cc;">android:id=</span><span style="background-color: #fff0f0;">"@+id/pb_load"</span>
<span style="color: #0000cc;">style=</span><span style="background-color: #fff0f0;">"?android:attr/progressBarStyleLarge"</span>
<span style="color: #0000cc;">android:layout_width=</span><span style="background-color: #fff0f0;">"wrap_content"</span>
<span style="color: #0000cc;">android:layout_height=</span><span style="background-color: #fff0f0;">"wrap_content"</span>
<span style="color: #0000cc;">android:layout_gravity=</span><span style="background-color: #fff0f0;">"center"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"><Button</span>
<span style="color: #0000cc;">android:id=</span><span style="background-color: #fff0f0;">"@+id/btn_upload"</span>
<span style="color: #0000cc;">android:layout_width=</span><span style="background-color: #fff0f0;">"180dp"</span>
<span style="color: #0000cc;">android:layout_height=</span><span style="background-color: #fff0f0;">"wrap_content"</span>
<span style="color: #0000cc;">android:layout_gravity=</span><span style="background-color: #fff0f0;">"center"</span>
<span style="color: #0000cc;">android:layout_marginTop=</span><span style="background-color: #fff0f0;">"8dp"</span>
<span style="color: #0000cc;">android:text=</span><span style="background-color: #fff0f0;">"@string/upload"</span>
<span style="color: #0000cc;">android:textSize=</span><span style="background-color: #fff0f0;">"20sp"</span> <span style="color: #007700;">/></span>
<span style="color: #007700;"></LinearLayout></span>
</pre>
</div>
Second, use the below code in your MainActivity.java<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .1em .1em .1em .1em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"> <span style="color: #008800; font-weight: bold;">public</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">MainActivity</span> <span style="color: #008800; font-weight: bold;">extends</span> Activity <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">private</span> Bitmap bitmap<span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">private</span> ImageView imageView<span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">private</span> Button uploadButton<span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">private</span> ProgressBar spinner<span style="color: #333333;">;</span>
<span style="color: #555555; font-weight: bold;">@Override</span>
<span style="color: #008800; font-weight: bold;">protected</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">onCreate</span><span style="color: #333333;">(</span>Bundle savedInstanceState<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">super</span><span style="color: #333333;">.</span><span style="color: #0000cc;">onCreate</span><span style="color: #333333;">(</span>savedInstanceState<span style="color: #333333;">);</span>
setContentView<span style="color: #333333;">(</span>R<span style="color: #333333;">.</span><span style="color: #0000cc;">layout</span><span style="color: #333333;">.</span><span style="color: #0000cc;">activity_main</span><span style="color: #333333;">);</span>
spinner <span style="color: #333333;">=</span> <span style="color: #333333;">(</span>ProgressBar<span style="color: #333333;">)</span> findViewById<span style="color: #333333;">(</span>R<span style="color: #333333;">.</span><span style="color: #0000cc;">id</span><span style="color: #333333;">.</span><span style="color: #0000cc;">pb_load</span><span style="color: #333333;">);</span>
spinner<span style="color: #333333;">.</span><span style="color: #0000cc;">setVisibility</span><span style="color: #333333;">(</span>View<span style="color: #333333;">.</span><span style="color: #0000cc;">GONE</span><span style="color: #333333;">);</span>
InputStream is <span style="color: #333333;">=</span> getResources<span style="color: #333333;">().</span><span style="color: #0000cc;">openRawResource</span><span style="color: #333333;">(</span>R<span style="color: #333333;">.</span><span style="color: #0000cc;">drawable</span><span style="color: #333333;">.</span><span style="color: #0000cc;">cat</span><span style="color: #333333;">);</span>
bitmap <span style="color: #333333;">=</span> BitmapFactory<span style="color: #333333;">.</span><span style="color: #0000cc;">decodeStream</span><span style="color: #333333;">(</span>is<span style="color: #333333;">);</span> <span style="color: #888888;">// This gets the image </span>
<span style="color: #888888;">// bitmap = BitmapFactory </span>
<span style="color: #888888;">// .decodeFile("/storage/emulated/0/DCIM/Camera/IMG_02.jpg"); </span>
imageView <span style="color: #333333;">=</span> <span style="color: #333333;">(</span>ImageView<span style="color: #333333;">)</span> findViewById<span style="color: #333333;">(</span>R<span style="color: #333333;">.</span><span style="color: #0000cc;">id</span><span style="color: #333333;">.</span><span style="color: #0000cc;">iv_image</span><span style="color: #333333;">);</span>
imageView<span style="color: #333333;">.</span><span style="color: #0000cc;">setImageBitmap</span><span style="color: #333333;">(</span>bitmap<span style="color: #333333;">);</span>
uploadButton <span style="color: #333333;">=</span> <span style="color: #333333;">(</span>Button<span style="color: #333333;">)</span> findViewById<span style="color: #333333;">(</span>R<span style="color: #333333;">.</span><span style="color: #0000cc;">id</span><span style="color: #333333;">.</span><span style="color: #0000cc;">btn_upload</span><span style="color: #333333;">);</span>
<span style="color: #888888;">// CompressFormat set up to JPG, you can change to PNG or whatever you </span>
<span style="color: #888888;">// want; </span>
<span style="color: #888888;">// To send compressed image through the network,Write a compressed </span>
<span style="color: #888888;">// version of the </span>
<span style="color: #888888;">// bitmap to the specified ByteArray OutputStream. </span>
ByteArrayOutputStream bos <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> ByteArrayOutputStream<span style="color: #333333;">();</span>
bitmap<span style="color: #333333;">.</span><span style="color: #0000cc;">compress</span><span style="color: #333333;">(</span>Bitmap<span style="color: #333333;">.</span><span style="color: #0000cc;">CompressFormat</span><span style="color: #333333;">.</span><span style="color: #0000cc;">JPEG</span><span style="color: #333333;">,</span> <span style="color: #0000dd; font-weight: bold;">60</span><span style="color: #333333;">,</span> bos<span style="color: #333333;">);</span>
<span style="color: #008800; font-weight: bold;">final</span> <span style="color: #333399; font-weight: bold;">byte</span><span style="color: #333333;">[]</span> data <span style="color: #333333;">=</span> bos<span style="color: #333333;">.</span><span style="color: #0000cc;">toByteArray</span><span style="color: #333333;">();</span>
uploadButton<span style="color: #333333;">.</span><span style="color: #0000cc;">setOnClickListener</span><span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">new</span> View<span style="color: #333333;">.</span><span style="color: #0000cc;">OnClickListener</span><span style="color: #333333;">()</span> <span style="color: #333333;">{</span>
<span style="color: #555555; font-weight: bold;">@Override</span>
<span style="color: #008800; font-weight: bold;">public</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">onClick</span><span style="color: #333333;">(</span>View v<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #888888;">// Create a media file name </span>
String timeStamp <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> SimpleDateFormat<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"yyyyMMdd_HHmmss"</span><span style="color: #333333;">,</span>
Locale<span style="color: #333333;">.</span><span style="color: #0000cc;">ENGLISH</span><span style="color: #333333;">).</span><span style="color: #0000cc;">format</span><span style="color: #333333;">(</span><span style="color: #008800; font-weight: bold;">new</span> Date<span style="color: #333333;">());</span>
<span style="color: #888888;">// Creates a new ByteArrayBody with byte array content and file </span>
<span style="color: #888888;">// name </span>
ByteArrayBody bdb <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> ByteArrayBody<span style="color: #333333;">(</span>data<span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">"temp_"</span> <span style="color: #333333;">+</span> timeStamp <span style="color: #333333;">+</span> <span style="background-color: #fff0f0;">".jpg"</span><span style="color: #333333;">);</span>
<span style="color: #008800; font-weight: bold;">new</span> <span style="color: #0066bb; font-weight: bold;">SendImageTask</span><span style="color: #333333;">().</span><span style="color: #0000cc;">execute</span><span style="color: #333333;">(</span>bdb<span style="color: #333333;">);</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">});</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">private</span> <span style="color: #008800; font-weight: bold;">class</span> <span style="color: #bb0066; font-weight: bold;">SendImageTask</span> <span style="color: #008800; font-weight: bold;">extends</span> AsyncTask <span style="color: #333333;"><</span> ByteArrayBody<span style="color: #333333;">,</span> Void<span style="color: #333333;">,</span> String <span style="color: #333333;">></span> <span style="color: #333333;">{</span>
<span style="color: #555555; font-weight: bold;">@Override</span>
<span style="color: #008800; font-weight: bold;">protected</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">onPreExecute</span><span style="color: #333333;">()</span> <span style="color: #333333;">{</span>
<span style="color: #888888;">// To show the progress circle while uploading image </span>
spinner<span style="color: #333333;">.</span><span style="color: #0000cc;">setVisibility</span><span style="color: #333333;">(</span>View<span style="color: #333333;">.</span><span style="color: #0000cc;">VISIBLE</span><span style="color: #333333;">);</span>
uploadButton<span style="color: #333333;">.</span><span style="color: #0000cc;">setVisibility</span><span style="color: #333333;">(</span>View<span style="color: #333333;">.</span><span style="color: #0000cc;">GONE</span><span style="color: #333333;">);</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">protected</span> String <span style="color: #0066bb; font-weight: bold;">doInBackground</span><span style="color: #333333;">(</span>ByteArrayBody<span style="color: #333333;">...</span><span style="color: #0000cc;">params</span><span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
String responseBody<span style="color: #333333;">;</span>
<span style="color: #008800; font-weight: bold;">try</span> <span style="color: #333333;">{</span>
HttpClient httpClient <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> DefaultHttpClient<span style="color: #333333;">();</span>
HttpContext localContext <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> BasicHttpContext<span style="color: #333333;">();</span>
<span style="color: #888888;">// here, change it to your api ; </span>
HttpPost httpPost <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> HttpPost<span style="color: #333333;">(</span>
<span style="background-color: #fff0f0;">"http://192.168.1.114:8080/upload"</span><span style="color: #333333;">);</span>
MultipartEntity entity <span style="color: #333333;">=</span> <span style="color: #008800; font-weight: bold;">new</span> MultipartEntity<span style="color: #333333;">(</span>
HttpMultipartMode<span style="color: #333333;">.</span><span style="color: #0000cc;">BROWSER_COMPATIBLE</span><span style="color: #333333;">);</span>
<span style="color: #888888;">// sending a String param; </span>
entity<span style="color: #333333;">.</span><span style="color: #0000cc;">addPart</span><span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"myParam"</span><span style="color: #333333;">,</span> <span style="color: #008800; font-weight: bold;">new</span> StringBody<span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"myValue"</span><span style="color: #333333;">));</span>
<span style="color: #888888;">// sending an Image; </span>
entity<span style="color: #333333;">.</span><span style="color: #0000cc;">addPart</span><span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"myImage"</span><span style="color: #333333;">,</span> params<span style="color: #333333;">[</span><span style="color: #0000dd; font-weight: bold;">0</span><span style="color: #333333;">]);</span>
httpPost<span style="color: #333333;">.</span><span style="color: #0000cc;">setEntity</span><span style="color: #333333;">(</span>entity<span style="color: #333333;">);</span>
HttpResponse response <span style="color: #333333;">=</span> httpClient<span style="color: #333333;">.</span><span style="color: #0000cc;">execute</span><span style="color: #333333;">(</span>httpPost<span style="color: #333333;">,</span>
localContext<span style="color: #333333;">);</span>
<span style="color: #333399; font-weight: bold;">int</span> httpStatusCode <span style="color: #333333;">=</span> response<span style="color: #333333;">.</span><span style="color: #0000cc;">getStatusLine</span><span style="color: #333333;">().</span><span style="color: #0000cc;">getStatusCode</span><span style="color: #333333;">();</span>
Log<span style="color: #333333;">.</span><span style="color: #0000cc;">d</span><span style="color: #333333;">(</span><span style="background-color: #fff0f0;">" http status: "</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">""</span> <span style="color: #333333;">+</span> httpStatusCode<span style="color: #333333;">);</span>
<span style="color: #008800; font-weight: bold;">if</span> <span style="color: #333333;">(</span>HttpStatus<span style="color: #333333;">.</span><span style="color: #0000cc;">SC_OK</span> <span style="color: #333333;">==</span> httpStatusCode<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
responseBody <span style="color: #333333;">=</span> EntityUtils<span style="color: #333333;">.</span><span style="color: #0000cc;">toString</span><span style="color: #333333;">(</span>response<span style="color: #333333;">.</span><span style="color: #0000cc;">getEntity</span><span style="color: #333333;">());</span>
<span style="color: #008800; font-weight: bold;">return</span> responseBody<span style="color: #333333;">;</span>
<span style="color: #333333;">}</span> <span style="color: #008800; font-weight: bold;">else</span> <span style="color: #333333;">{</span>
Log<span style="color: #333333;">.</span><span style="color: #0000cc;">d</span><span style="color: #333333;">(</span><span style="background-color: #fff0f0;">"unhandled httpStatusCode: "</span><span style="color: #333333;">,</span> <span style="background-color: #fff0f0;">""</span> <span style="color: #333333;">+</span> httpStatusCode<span style="color: #333333;">);</span>
<span style="color: #888888;">// Closes the connection. </span>
<span style="color: #888888;">// Returns a content stream of the entity. </span>
response<span style="color: #333333;">.</span><span style="color: #0000cc;">getEntity</span><span style="color: #333333;">().</span><span style="color: #0000cc;">getContent</span><span style="color: #333333;">().</span><span style="color: #0000cc;">close</span><span style="color: #333333;">();</span>
<span style="color: #008800; font-weight: bold;">throw</span> <span style="color: #008800; font-weight: bold;">new</span> <span style="color: #0066bb; font-weight: bold;">IOException</span><span style="color: #333333;">(</span>response<span style="color: #333333;">.</span><span style="color: #0000cc;">getStatusLine</span><span style="color: #333333;">()</span>
<span style="color: #333333;">.</span><span style="color: #0000cc;">getReasonPhrase</span><span style="color: #333333;">());</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span> <span style="color: #008800; font-weight: bold;">catch</span> <span style="color: #333333;">(</span>ClientProtocolException e<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> e<span style="color: #333333;">.</span><span style="color: #0000cc;">getMessage</span><span style="color: #333333;">().</span><span style="color: #0000cc;">toString</span><span style="color: #333333;">();</span>
<span style="color: #333333;">}</span> <span style="color: #008800; font-weight: bold;">catch</span> <span style="color: #333333;">(</span>IOException e<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
<span style="color: #008800; font-weight: bold;">return</span> e<span style="color: #333333;">.</span><span style="color: #0000cc;">getMessage</span><span style="color: #333333;">().</span><span style="color: #0000cc;">toString</span><span style="color: #333333;">();</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
<span style="color: #008800; font-weight: bold;">protected</span> <span style="color: #333399; font-weight: bold;">void</span> <span style="color: #0066bb; font-weight: bold;">onPostExecute</span><span style="color: #333333;">(</span>String result<span style="color: #333333;">)</span> <span style="color: #333333;">{</span>
spinner<span style="color: #333333;">.</span><span style="color: #0000cc;">setVisibility</span><span style="color: #333333;">(</span>View<span style="color: #333333;">.</span><span style="color: #0000cc;">GONE</span><span style="color: #333333;">);</span>
uploadButton<span style="color: #333333;">.</span><span style="color: #0000cc;">setVisibility</span><span style="color: #333333;">(</span>View<span style="color: #333333;">.</span><span style="color: #0000cc;">VISIBLE</span><span style="color: #333333;">);</span>
Toast<span style="color: #333333;">.</span><span style="color: #0000cc;">makeText</span><span style="color: #333333;">(</span>getApplicationContext<span style="color: #333333;">(),</span> <span style="background-color: #fff0f0;">"Output: "</span> <span style="color: #333333;">+</span> result<span style="color: #333333;">,</span>
Toast<span style="color: #333333;">.</span><span style="color: #0000cc;">LENGTH_SHORT</span><span style="color: #333333;">).</span><span style="color: #0000cc;">show</span><span style="color: #333333;">();</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
<span style="color: #333333;">}</span>
</pre>
</div>
<br />
Your android application is ready to send image.<br />
<br />
Now, in step three, write the script to run in your server or localhost to accept and save the image and expose that API to your android application.<br />
<br />
Below is a python script using bottle framework :<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #ffffff; border-width: .2em .2em .2em .2em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<pre style="line-height: 125%; margin: 0;"><span style="color: #008800; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">bottle</span> <span style="color: #008800; font-weight: bold;">import</span> get, post, request,run,os <span style="color: #888888;"># or route</span>
<span style="color: #008800; font-weight: bold;">def</span> <span style="color: #0066bb; font-weight: bold;">get_save_path_for_category</span>():
<span style="color: #008800; font-weight: bold;">return</span> <span style="background-color: #fff0f0;">"/home/uploadhere"</span>
<span style="color: #555555; font-weight: bold;">@get</span>(<span style="background-color: #fff0f0;">'/upload'</span>) <span style="color: #888888;">#</span>
<span style="color: #008800; font-weight: bold;">def</span> <span style="color: #0066bb; font-weight: bold;">login</span>():
<span style="color: #008800; font-weight: bold;">return</span> <span style="background-color: #fff0f0;">'''</span>
<span style="background-color: #fff0f0;"> <form action="/upload" method="post" enctype="multipart/form-data"></span>
<span style="background-color: #fff0f0;"> Category: <input type="text" name="category" /></span>
<span style="background-color: #fff0f0;"> Select a file: <input type="file" name="myImage" /></span>
<span style="background-color: #fff0f0;"> <input type="submit" value="Start upload" /></span>
<span style="background-color: #fff0f0;"> </form></span>
<span style="background-color: #fff0f0;"> '''</span>
<span style="color: #555555; font-weight: bold;">@post</span>(<span style="background-color: #fff0f0;">'/upload'</span>) <span style="color: #888888;"># or @route('/upload', method='POST')</span>
<span style="color: #008800; font-weight: bold;">def</span> <span style="color: #0066bb; font-weight: bold;">do_upload</span>():
<span style="color: #888888;">#category = request.forms.get('category')</span>
upload <span style="color: #333333;">=</span> request<span style="color: #333333;">.</span>files<span style="color: #333333;">.</span>get(<span style="background-color: #fff0f0;">'myImage'</span>)
name, ext <span style="color: #333333;">=</span> os<span style="color: #333333;">.</span>path<span style="color: #333333;">.</span>splitext(upload<span style="color: #333333;">.</span>filename)
<span style="color: #008800; font-weight: bold;">if</span> ext <span style="color: black; font-weight: bold;">not</span> <span style="color: black; font-weight: bold;">in</span> (<span style="background-color: #fff0f0;">'.png'</span>,<span style="background-color: #fff0f0;">'.jpg'</span>,<span style="background-color: #fff0f0;">'.jpeg'</span>):
<span style="color: #008800; font-weight: bold;">return</span> <span style="background-color: #fff0f0;">'File extension not allowed.'</span>
save_path <span style="color: #333333;">=</span> get_save_path_for_category()
<span style="color: #008800; font-weight: bold;">if</span> <span style="color: black; font-weight: bold;">not</span> os<span style="color: #333333;">.</span>path<span style="color: #333333;">.</span>exists(save_path):
os<span style="color: #333333;">.</span>makedirs(save_path)
upload<span style="color: #333333;">.</span>save(save_path,overwrite<span style="color: #333333;">=</span><span style="color: #007020;">True</span>) <span style="color: #888888;"># appends upload.filename automatically</span>
<span style="color: #008800; font-weight: bold;">return</span> <span style="background-color: #fff0f0;">"File successfully saved to '{0}'."</span><span style="color: #333333;">.</span>format(save_path)
run(host<span style="color: #333333;">=</span><span style="background-color: #fff0f0;">'192.168.1.114'</span>, port<span style="color: #333333;">=</span><span style="color: #0000dd; font-weight: bold;">8080</span>, debug<span style="color: #333333;">=</span><span style="color: #007020;">True</span>)
</pre>
</div>
<div>
<br /></div>
You are done here.<br />
<br />
<br /></div>
</div>
Anonymoushttp://www.blogger.com/profile/02050057953923357165noreply@blogger.com0