<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mac OS X Linux Tech</title>
	<atom:link href="https://installingcats.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://installingcats.com</link>
	<description></description>
	<lastBuildDate>Sat, 09 Sep 2023 19:02:58 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.4.1</generator>
	<item>
		<title>Edge Browser Bing Chat GPT over 100% GPU Usage</title>
		<link>https://installingcats.com/2023/09/09/edge-browser-bing-chatgpt-over-100-gpu-usage/</link>
					<comments>https://installingcats.com/2023/09/09/edge-browser-bing-chatgpt-over-100-gpu-usage/#respond</comments>
		
		<dc:creator><![CDATA[ben]]></dc:creator>
		<pubDate>Sat, 09 Sep 2023 19:02:15 +0000</pubDate>
				<category><![CDATA[fixes]]></category>
		<category><![CDATA[AI]]></category>
		<guid isPermaLink="false">https://installingcats.com/?p=700</guid>

					<description><![CDATA[Bing Chat (GPT-4) on Microsoft Edge Browser is using over 100% GPU usage on a MacBook Pro 2020 laptop (154% in my case) causing the fans to spin up to a high RPM. Switching to another tab on Edge, not showing the Bing Chat tab, GPU usage drops down to single digits for Microsoft Edge [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Bing Chat (GPT-4) on Microsoft Edge Browser is using over 100% GPU usage on a MacBook Pro 2020 laptop (154% in my case) causing the fans to spin up to a high RPM.</p>



<p>Switching to another tab on Edge, not showing the Bing Chat tab, GPU usage drops down to single digits for Microsoft Edge Helper (GPU) in Activity Monitor.</p>



<p>It turns out, the <strong>Edge&#8217;s Appearance theme of &#8220;Light&#8221; was the problem</strong>, <strong>causing the massive GPU usage on the Bing Chat tab of MS Edge browser</strong>. (No other tabs show this problem of high GPU usage.)  Once I switched Bing Chat to use &#8220;Dark&#8221; appearance, the GPU usage returned down to single digits while browsing Bing Chat on Microsoft Edge browser.  See the screenshot below to see the settings (and press the hamburger menu icon button on the top right hand corner to see the below menu).</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="503" height="1024" src="https://installingcats.com/wp-content/uploads/2023/09/bing-chat-gpu-usage-503x1024.png" alt="" class="wp-image-702" srcset="https://installingcats.com/wp-content/uploads/2023/09/bing-chat-gpu-usage-503x1024.png 503w, https://installingcats.com/wp-content/uploads/2023/09/bing-chat-gpu-usage-147x300.png 147w, https://installingcats.com/wp-content/uploads/2023/09/bing-chat-gpu-usage.png 740w" sizes="(max-width: 503px) 100vw, 503px" /></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://installingcats.com/2023/09/09/edge-browser-bing-chatgpt-over-100-gpu-usage/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Epson EF-12 Dolby Digital / DTS output on ARC</title>
		<link>https://installingcats.com/2022/03/03/epson-ef-12-dolby-digital-dts-output-arc/</link>
		
		<dc:creator><![CDATA[ben]]></dc:creator>
		<pubDate>Thu, 03 Mar 2022 16:01:00 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<guid isPermaLink="false">http://installingcats.com/?p=584</guid>

					<description><![CDATA[The Epson EF-12 laser projector (Android TV) can output / passthrough 5.1 digital surround sound to your A/V home theater receiver over its HDMI2 ARC connection for both Dolby Digital AC3 and DTS movies &#38; media using Kodi player, but with some big caveats. First, the settings in Kodi player to output 5.1 digital surround sound [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>The <a href="https://amzn.to/3vwdV7h">Epson EF-12 laser projector</a> (Android TV) can output / passthrough 5.1 digital surround sound to your A/V home theater receiver over its HDMI2 ARC connection for both Dolby Digital AC3 <em>and</em> DTS movies &amp; media using Kodi player, but with some big caveats.</p>
<p><a href="https://www.amazon.com/Epson-EpiqVision-EF12-Streaming-Brightness/dp/B08GL4QSFH?crid=36MRZ10MGH1MU&amp;keywords=epson+ef-12&amp;qid=1646288076&amp;sprefix=epson+ef-12%2Caps%2C115&amp;sr=8-3&amp;linkCode=li3&amp;tag=zbookclub-20&amp;linkId=8bcfad6a8d7af9226faabf223b333d98&amp;language=en_US&amp;ref_=as_li_ss_il" target="_blank" rel="noopener"><img decoding="async" src="//ws-na.amazon-adsystem.com/widgets/q?_encoding=UTF8&amp;ASIN=B08GL4QSFH&amp;Format=_SL250_&amp;ID=AsinImage&amp;MarketPlace=US&amp;ServiceVersion=20070822&amp;WS=1&amp;tag=zbookclub-20&amp;language=en_US" border="0" /></a><img decoding="async" style="border: none !important; margin: 0px !important;" src="https://ir-na.amazon-adsystem.com/e/ir?t=zbookclub-20&amp;language=en_US&amp;l=li3&amp;o=1&amp;a=B08GL4QSFH" alt="" width="1" height="1" border="0" /></p>
<p>First, <strong>the settings in Kodi player</strong> to output 5.1 digital surround sound to your AV Receiver over HDMI ARC:</p>
<ol>
<li>In System &gt; Settings, turn on Expert Mode (Bottom Left Corner)</li>
<li>In Audio section:
<ol>
<li>Audio output device: AudioTrack (IEC), Kodi IEC packer (recommended)</li>
<li>Number of channels: 2.0</li>
<li>Output configuration: Optimized</li>
<li>scroll down to <strong>Audio Passthrough</strong> section&#8230;</li>
<li>Allow passthrough: ON (switch button to the right)</li>
<li>Passthrough output device: AudioTrack (RAW), Android IEC packer</li>
<li>Dolby Digital (AC3) capable receiver: ON</li>
<li>&#8211; Enable Dolby Digital (AC3) transcoding: ON</li>
<li>Dolby Digital Plus (E-AC3) capable receiver: OFF</li>
<li>DTS capable receiver: OFF</li>
</ol>
</li>
</ol>
<p><img decoding="async" class="alignnone size-full wp-image-587" src="https://installingcats.com/wp-content/uploads/2022/03/kodi-audio-decoder-epson-android-tv-1.jpg" alt="" width="852" height="463" /></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-588" src="https://installingcats.com/wp-content/uploads/2022/03/kodi-passthrough-epson-android-tv-1.jpg" alt="" width="862" height="483" /></p>
<h2>Getting Epson EF-12 to output Digital Surround Sound</h2>
<p>To get 5.1 digital surround sound to an AV receiver over ARC from an Epson EF-12 Android TV, the above settings were what I needed to use.</p>
<p>Below are the caveats &amp; explanations of why the these settings work.</p>
<p>According to Kodi engineers, <a href="https://forum.kodi.tv/showthread.php?tid=359627&amp;pid=3001000#pid3001000">HDMI ARC can only output two channels of audio data</a>. That&#8217;s why we set &#8220;Number of channels&#8221; to 2.0.</p>
<p>If Output configuration is not &#8220;Optimized&#8221;, only two track stereo will be passed through.</p>
<p>By default, the Passthrough output device is Kodi IEC packer.  This will not work.  It must be set to AudioTrack (RAW), Android IEC packer as Android is mixing down the audio data into 2 channels for output over ARC, which only supports 2 audio channels.  This doesn&#8217;t mean we&#8217;re only sending Left and Right audio channels.  It just means we&#8217;re sending the <strong>encoded bitstream</strong> of 5-channel Dolby Digital data over one of <strong>these two channels</strong>.</p>
<p>&#8220;Dolby Digital (AC3) capable receiver&#8221; tells Kodi to output raw encoded Dolby Digital bitstream and that the device (your AV receiver) on the other end will perform the decoding.</p>
<p>&#8220;Enable Dolby Digital (AC3) transcoding&#8221;  will transcode DTS sound data into Dolby Digital AC3 for transport over the ARC audio channels.  Kodi, on Epson Android TV systems, does not currently support raw DTS audio data over ARC (as of Kodi 19.3 Matrix).  This is why we need Dolby Digital transcoding ON: we&#8217;re <strong>converting DTS into Dolby Digital AC3 5.1 signal</strong>.</p>
<p>&#8220;DTS capable receiver&#8221; OFF will <em>force transcoding</em> of DTS streams into DD AC3 streams since Kodi on Epson Android TV does not support DTS passthrough over ARC at this time.</p>
<p>So the big caveat with all this is: DTS cannot be directly output / passthrough as-is to your DTS receiver.  It must be transcoded from DTS into Dolby Digital.  It&#8217;ll still be 5.1 digital surround at least.</p>
<p>Also, Kodi on this Epson Android TV hardware cannot output anything but basic Dolby Digital AC3 5.1.  So no DTS HD, Dolby True HD, no E-AC3 nor Atmos.  Just basic Dolby Digital AC3 5.1.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Android Genymotion Mock Location Google Play</title>
		<link>https://installingcats.com/2015/11/26/android-genymotion-mock-location-google-play/</link>
		
		<dc:creator><![CDATA[ben]]></dc:creator>
		<pubDate>Thu, 26 Nov 2015 16:55:37 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Google Play]]></category>
		<category><![CDATA[GPS]]></category>
		<category><![CDATA[location]]></category>
		<category><![CDATA[mock]]></category>
		<guid isPermaLink="false">http://installingcats.com/?p=522</guid>

					<description><![CDATA[To get Android Genymotion Mock Location Google Play fused location provider working in an emulator these are the necessary components and steps.  (For Genymotion 2.5.x emulator versions) Download: Genymotion ARM Translation v1.1 Google Apps / Play Store for a Genymotion emulator running SDK 5.1 (API Level 22) Steps Install these two zipped APK archive files by [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>To get Android Genymotion Mock Location Google Play fused location provider working in an emulator these are the necessary components and steps.  (For Genymotion 2.5.x emulator versions)</p>
<p>Download:</p>
<ul>
<li><a href="https://www.androidfilehost.com/?fid=23252070760974384">Genymotion ARM Translation v1.1</a></li>
<li><a href="https://www.androidfilehost.com/?fid=96039337900114811">Google Apps / Play Store</a> for a Genymotion emulator running SDK 5.1 (API Level 22)</li>
</ul>
<p>Steps</p>
<ol>
<li>Install these two zipped APK archive files by dragging the zip files directly onto your running Genymotion Emulator in order.  Start first with ARM Translation v1.1.  It will ask for confirmation.  Click OK.<br />
<img loading="lazy" decoding="async" class="alignnone size-large wp-image-523" src="https://installingcats.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-26-at-4.51.05-PM-1-969x1024.png" alt="Install genymotion ARM Translation v1.1" width="665" height="703" srcset="https://installingcats.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-26-at-4.51.05-PM-1-969x1024.png 969w, https://installingcats.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-26-at-4.51.05-PM-1-284x300.png 284w, https://installingcats.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-26-at-4.51.05-PM-1-768x811.png 768w, https://installingcats.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-26-at-4.51.05-PM-1.png 1132w" sizes="(max-width: 665px) 100vw, 665px" /></li>
<li>After the APK file is unpacked and installed, genymotion emulator will ask to restart.  To restart your genymotion emulator, in a command prompt on your computer, issue an emulator reboot command: adb reboot.  The emulator will reboot several times. For me: 4 times it will cycle before settling down and showing the home screen.</li>
<li>Repeat with the Google Apps Play Store file (gapps-5.1-xxxxx) file &#8211;  drag and drop, confirm install, adb reboot.  This should only cycle off/on your emulator once, unlike the ARM Translation APK you installed earlier.</li>
<li>Click on the Home button (center white circle with dots at bottom) and find Google Play Store.  Click it to start Google Play.  It may ask to update.  If so, update it.<br />
<img loading="lazy" decoding="async" class="alignnone wp-image-524 size-medium" src="https://installingcats.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-26-at-5.07.27-PM-1-238x300.png" alt="genymotion-playstore-installed" width="238" height="300" srcset="https://installingcats.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-26-at-5.07.27-PM-1-238x300.png 238w, https://installingcats.com/wp-content/uploads/2015/11/Screen-Shot-2015-11-26-at-5.07.27-PM-1.png 688w" sizes="(max-width: 238px) 100vw, 238px" /></li>
<li>Open Google Play. It will ask for a Google account.  Feel free to create a new one or use one you already have.  Supply its password.  Accept Terms of Service and Privacy Policy.  Google Play Services may pop up a dialog saying it has stopped.  Google Play setup will continue though.  Setup payment info if you like.  I didn&#8217;t and chose Remind me later.  After that you&#8217;ll be shown the Play Store home page.<br />
<img loading="lazy" decoding="async" class="alignnone wp-image-531 size-medium" src="https://installingcats.com/wp-content/uploads/2015/11/google_play_setup_account-1-188x300.png" alt="google_play_setup_account" width="188" height="300" srcset="https://installingcats.com/wp-content/uploads/2015/11/google_play_setup_account-1-188x300.png 188w, https://installingcats.com/wp-content/uploads/2015/11/google_play_setup_account-1-641x1024.png 641w, https://installingcats.com/wp-content/uploads/2015/11/google_play_setup_account-1-768x1226.png 768w, https://installingcats.com/wp-content/uploads/2015/11/google_play_setup_account-1-962x1536.png 962w, https://installingcats.com/wp-content/uploads/2015/11/google_play_setup_account-1.png 1200w" sizes="(max-width: 188px) 100vw, 188px" /></li>
<li>Google Play Store in Genymotion crashes repeatedly after install on a Genymotion emulator.  To fix the Google Play Store crashes on Genymotion emulator, open the Settings application in Android (gear icon), scroll down and click on Apps.  Click on Google Play Store.  Click on Clear Cache and Clear Data.  Click OK on any dialogs that come up.<br />
<img loading="lazy" decoding="async" class="alignnone wp-image-530 size-medium" src="https://installingcats.com/wp-content/uploads/2015/11/genymotion_settings-1-259x300.png" alt="genymotion_settings" width="259" height="300" srcset="https://installingcats.com/wp-content/uploads/2015/11/genymotion_settings-1-259x300.png 259w, https://installingcats.com/wp-content/uploads/2015/11/genymotion_settings-1.png 602w" sizes="(max-width: 259px) 100vw, 259px" /><br />
<img loading="lazy" decoding="async" class="alignnone wp-image-529 size-medium" src="https://installingcats.com/wp-content/uploads/2015/11/settings_apps_downloaded-1-300x139.png" alt="settings_apps_downloaded" width="300" height="139" srcset="https://installingcats.com/wp-content/uploads/2015/11/settings_apps_downloaded-1-300x139.png 300w, https://installingcats.com/wp-content/uploads/2015/11/settings_apps_downloaded-1-1024x475.png 1024w, https://installingcats.com/wp-content/uploads/2015/11/settings_apps_downloaded-1-768x356.png 768w, https://installingcats.com/wp-content/uploads/2015/11/settings_apps_downloaded-1.png 1082w" sizes="(max-width: 300px) 100vw, 300px" /><br />
<img loading="lazy" decoding="async" class="alignnone wp-image-528 size-medium" src="https://installingcats.com/wp-content/uploads/2015/11/settings_apps_clear_cache_clear_data-1-207x300.png" alt="settings_apps_clear_cache_clear_data" width="207" height="300" srcset="https://installingcats.com/wp-content/uploads/2015/11/settings_apps_clear_cache_clear_data-1-207x300.png 207w, https://installingcats.com/wp-content/uploads/2015/11/settings_apps_clear_cache_clear_data-1-708x1024.png 708w, https://installingcats.com/wp-content/uploads/2015/11/settings_apps_clear_cache_clear_data-1-768x1111.png 768w, https://installingcats.com/wp-content/uploads/2015/11/settings_apps_clear_cache_clear_data-1-1061x1536.png 1061w, https://installingcats.com/wp-content/uploads/2015/11/settings_apps_clear_cache_clear_data-1.png 1118w" sizes="(max-width: 207px) 100vw, 207px" /></p>
<ol>
<li>Restart Google Play</li>
<li>Accept Terms and Conditions again</li>
<li>You may or may not have to log in again.  If you get an error regarding you must be logged in when trying to search for Maps, click on the three horizontal bars at the top left of the Google Play home screen to slide out the left tray and click My Account.  Log in if asked to do so.  For me it auto-logged me in from cached credentials.<br />
<img loading="lazy" decoding="async" class="alignnone wp-image-525 size-medium" src="https://installingcats.com/wp-content/uploads/2015/11/google_play_my_account-1-221x300.png" alt="google_play_my_account" width="221" height="300" srcset="https://installingcats.com/wp-content/uploads/2015/11/google_play_my_account-1-221x300.png 221w, https://installingcats.com/wp-content/uploads/2015/11/google_play_my_account-1-753x1024.png 753w, https://installingcats.com/wp-content/uploads/2015/11/google_play_my_account-1-768x1044.png 768w, https://installingcats.com/wp-content/uploads/2015/11/google_play_my_account-1.png 1090w" sizes="(max-width: 221px) 100vw, 221px" /></li>
<li>Back in Google Play, text search for maps.  Google Play should not crash.</li>
</ol>
</li>
<li>Install Google Maps.<br />
<img loading="lazy" decoding="async" class="alignnone wp-image-526 size-medium" src="https://installingcats.com/wp-content/uploads/2015/11/google_play_store_google_maps-1-300x271.png" alt="google_play_store_google_maps" width="300" height="271" srcset="https://installingcats.com/wp-content/uploads/2015/11/google_play_store_google_maps-1-300x271.png 300w, https://installingcats.com/wp-content/uploads/2015/11/google_play_store_google_maps-1-1024x926.png 1024w, https://installingcats.com/wp-content/uploads/2015/11/google_play_store_google_maps-1-768x695.png 768w, https://installingcats.com/wp-content/uploads/2015/11/google_play_store_google_maps-1.png 1194w" sizes="(max-width: 300px) 100vw, 300px" /></li>
<li>In Google Play, find and install a mock location provider such as Mock Locations or Fake GPS.  Mock Locations (fake GPS path), which allows you to draw out a path which you can &#8220;drive&#8221; or &#8220;walk&#8221; at your desired speed between locations of your choice.  I find this quite useful when using GoogleApiClient fused provider where requestLocationUpdates is returning Location objects repeatedly over a period.  Very helpful when you&#8217;re testing Entering and Exiting GeoFences<br />
<img loading="lazy" decoding="async" class="alignnone size-medium wp-image-534" src="https://installingcats.com/wp-content/uploads/2015/11/mock_location-1-207x300.png" alt="mock_location" width="207" height="300" srcset="https://installingcats.com/wp-content/uploads/2015/11/mock_location-1-207x300.png 207w, https://installingcats.com/wp-content/uploads/2015/11/mock_location-1-708x1024.png 708w, https://installingcats.com/wp-content/uploads/2015/11/mock_location-1-768x1111.png 768w, https://installingcats.com/wp-content/uploads/2015/11/mock_location-1-1062x1536.png 1062w, https://installingcats.com/wp-content/uploads/2015/11/mock_location-1.png 1174w" sizes="(max-width: 207px) 100vw, 207px" /></li>
<li>Don&#8217;t forgot to turn on High Accuracy mode in Settings -&gt; Location -&gt; Mode -&gt; High accuracy, which allows GoogleAPIClient Location Services fused location provider to work properly.  I didn&#8217;t have much luck running Google Play Services Location Provider with GPS (Device) only Location setting.<br />
<img loading="lazy" decoding="async" class="alignnone size-medium wp-image-538" src="https://installingcats.com/wp-content/uploads/2015/11/location_mode-1-300x259.png" alt="location_mode" width="300" height="259" srcset="https://installingcats.com/wp-content/uploads/2015/11/location_mode-1-300x259.png 300w, https://installingcats.com/wp-content/uploads/2015/11/location_mode-1-1024x884.png 1024w, https://installingcats.com/wp-content/uploads/2015/11/location_mode-1-768x663.png 768w, https://installingcats.com/wp-content/uploads/2015/11/location_mode-1.png 1168w" sizes="(max-width: 300px) 100vw, 300px" /></li>
<li>And finally Dev Tools (application on Genymotion) -&gt; Developer Options -&gt; Allow Mock Locations needs to be On.<br />
<img loading="lazy" decoding="async" class="alignnone size-medium wp-image-544" src="https://installingcats.com/wp-content/uploads/2015/11/dev_options_app_icon_highlighted-1-219x300.png" alt="dev_options_app_icon_highlighted" width="219" height="300" srcset="https://installingcats.com/wp-content/uploads/2015/11/dev_options_app_icon_highlighted-1-219x300.png 219w, https://installingcats.com/wp-content/uploads/2015/11/dev_options_app_icon_highlighted-1-746x1024.png 746w, https://installingcats.com/wp-content/uploads/2015/11/dev_options_app_icon_highlighted-1-768x1053.png 768w, https://installingcats.com/wp-content/uploads/2015/11/dev_options_app_icon_highlighted-1.png 920w" sizes="(max-width: 219px) 100vw, 219px" /><br />
<img loading="lazy" decoding="async" class="alignnone size-medium wp-image-541" src="https://installingcats.com/wp-content/uploads/2015/11/dev_options_mock_locations-1-300x172.png" alt="dev_options_mock_locations" width="300" height="172" srcset="https://installingcats.com/wp-content/uploads/2015/11/dev_options_mock_locations-1-300x172.png 300w, https://installingcats.com/wp-content/uploads/2015/11/dev_options_mock_locations-1-1024x588.png 1024w, https://installingcats.com/wp-content/uploads/2015/11/dev_options_mock_locations-1-768x441.png 768w, https://installingcats.com/wp-content/uploads/2015/11/dev_options_mock_locations-1.png 1192w" sizes="(max-width: 300px) 100vw, 300px" /></li>
</ol>
<p>&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Spring Boot SSL with Android Retrofit</title>
		<link>https://installingcats.com/2015/11/08/spring-boot-ssl-android-retrofit/</link>
		
		<dc:creator><![CDATA[ben]]></dc:creator>
		<pubDate>Sun, 08 Nov 2015 06:55:29 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[spring security]]></category>
		<category><![CDATA[ssl]]></category>
		<guid isPermaLink="false">http://installingcats.com/?p=519</guid>

					<description><![CDATA[To setup Spring Boot SSL with Android Retrofit connecting on HTTPS 443: In Spring Boot &#60;your project&#62;/src/main/resources/application.properties &#8211; add the following values (not the &#8220;1.&#8221; which is just WordPress ordered list numbering) security.require-ssl=true server.port=8443 server.ssl.key-store=src/main/resources/private/keystore server.ssl.key-store-password=changeit server.ssl.key-password=changeit create and add an SSL key to the location specified by server.ssl.key-store. Note: the SSL certificate file is [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>To setup Spring Boot SSL with Android Retrofit connecting on HTTPS 443:</p>
<p>In Spring Boot</p>
<ol>
<li>&lt;your project&gt;/src/main/resources/application.properties &#8211; add the following values (not the &#8220;1.&#8221; which is just WordPress ordered list numbering)
<ol>
<li><code>security.require-ssl=true<br />
server.port=8443<br />
server.ssl.key-store=src/main/resources/private/keystore<br />
server.ssl.key-store-password=changeit<br />
server.ssl.key-password=changeit</code></li>
</ol>
</li>
<li><a href="https://www.drissamri.be/blog/java/enable-https-in-spring-boot/" target="_blank" rel="noopener">create and add an SSL key</a> to the location specified by server.ssl.key-store. Note: the SSL certificate file is actually named &#8220;keystore&#8221;.  That&#8217;s not a directory.</li>
<li>Restart your Spring server and you should be able to make httpS connections on port 8443</li>
</ol>
<p>In Android Retrofit</p>
<ul>
<li>Add an OkHttp compile dependency to build.gradle</li>
</ul>
<p><code>compile 'com.squareup.okhttp:okhttp:2.5.0'</code></p>
<ul>
<li>Create a class that returns an OkHttp client that doesn&#8217;t validate trust certificates (written by Jules White of Vanderbuilt)</li>
</ul>
<p><code><br />
public class UnsafeHttpsClient {</code></p>
<p>public static OkHttpClient getUnsafeOkHttpClient() {<br />
try {<br />
// Create a trust manager that does not validate certificate chains<br />
final TrustManager[] trustAllCerts = new TrustManager[] {<br />
new X509TrustManager() {</p>
<p>@Override<br />
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {<br />
}</p>
<p>@Override<br />
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {<br />
}</p>
<p>@Override<br />
public java.security.cert.X509Certificate[] getAcceptedIssuers() {<br />
return null;<br />
}<br />
}<br />
};</p>
<p>// Install the all-trusting trust manager<br />
final SSLContext sslContext = SSLContext.getInstance(&#8220;SSL&#8221;);<br />
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());<br />
// Create an ssl socket factory with our all-trusting manager<br />
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();</p>
<p>OkHttpClient okHttpClient = new OkHttpClient();<br />
okHttpClient.setSslSocketFactory(sslSocketFactory);<br />
okHttpClient.setHostnameVerifier(new HostnameVerifier() {<br />
@Override<br />
public boolean verify(String hostname, SSLSession session) {<br />
return true;<br />
}<br />
});</p>
<p>return okHttpClient;<br />
} catch (Exception e) {<br />
throw new RuntimeException(e);<br />
}<br />
}<br />
}</p>
<ul>
<li>Update your Retrofit rest adapter with this unsafe OkHttp client</li>
</ul>
<p><code> return new RestAdapter<br />
.Builder()<br />
.setEndpoint(server)<br />
.setLogLevel(logLevel)<br />
.setLog(new AndroidLog(debugTag))<br />
.setConverter(new GsonConverter(myGsonDateAdapter()))<br />
.setClient(new OkClient(UnsafeHttpsClient.getUnsafeOkHttpClient()))<br />
.build()<br />
.create(WebProxy.class);</code></p>
<p>In the above example,</p>
<ul>
<li>WebProxy is the API interface class.</li>
<li>server is obviously the Spring server, should be https and at whatever port specified in Spring&#8217;s application.properties</li>
<li>debugTag is optional text to prefix Retrofit calls in Android&#8217;s console log</li>
<li>Converter is not required</li>
</ul>
<p>Other tools that might help debug</p>
<ul>
<li><a href="https://www.getpostman.com/" target="_blank" rel="noopener">Postman</a> &#8211; if you can make an https/8443 GET request to your Spring server, you know Spring is setup properly</li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Android Studio Permanently Change Debug Configuration for Working Directory $MODULE_DIR$ and app:assembleDebugUnitTest</title>
		<link>https://installingcats.com/2015/10/25/android-studio-permanently-change-debug-configuration-working-directory-module_dir-appassembledebugunittest/</link>
		
		<dc:creator><![CDATA[ben]]></dc:creator>
		<pubDate>Sun, 25 Oct 2015 12:38:42 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[instructions]]></category>
		<category><![CDATA[Unit Tests]]></category>
		<guid isPermaLink="false">http://installingcats.com/?p=512</guid>

					<description><![CDATA[On Mac OS X, Android Studio&#8217;s default debug Unit Test build configuration generally doesn&#8217;t run with default settings complaining that: AndroidManifest.xml not found or not a file; it should point to your project&#8217;s AndroidManifest.xml To fix this error you need to edit your debug configuration to set Working Directory as $MODULE_DIR$ and it makes builds [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>On Mac OS X, Android Studio&#8217;s default debug Unit Test build configuration generally doesn&#8217;t run with default settings complaining that:</p>
<p>AndroidManifest.xml not found or not a file; it should point to your project&#8217;s AndroidManifest.xml</p>
<p>To fix this error you need to edit your debug configuration to set Working Directory as $MODULE_DIR$ and it makes builds faster to set Before Launch as gradle :app:assembleDebugUnitTest</p>
<p>To set these Debug build configuration settings permanently go to Android Studio Menu -&gt; Run -&gt; Edit Configurations&#8230; -&gt; click on the little wrench and cog icon to Edit Defaults, JUnit should be selected if you&#8217;re currently on a Unit Test and change the working Directory to $MODULE_DIR$ and Before Launch: Gradle-aware Make and choosing :app:assembleDebugUnitTest. Remove the plain-jane &#8220;Make&#8221; from the list as well.</p>
<p><a href="https://installingcats.com/wp-content/uploads/2015/10/android-studio-menu-edit-configurations-1.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-514" src="https://installingcats.com/wp-content/uploads/2015/10/android-studio-menu-edit-configurations-1-1024x548.png" alt="android-studio-menu-edit-configurations" width="665" height="356" srcset="https://installingcats.com/wp-content/uploads/2015/10/android-studio-menu-edit-configurations-1-1024x548.png 1024w, https://installingcats.com/wp-content/uploads/2015/10/android-studio-menu-edit-configurations-1-300x161.png 300w, https://installingcats.com/wp-content/uploads/2015/10/android-studio-menu-edit-configurations-1-768x411.png 768w, https://installingcats.com/wp-content/uploads/2015/10/android-studio-menu-edit-configurations-1.png 1417w" sizes="(max-width: 665px) 100vw, 665px" /></a><br />
<a href="https://installingcats.com/wp-content/uploads/2015/10/android-studio-debug-edit-configuration-screen-1.png"><img loading="lazy" decoding="async" class="alignnone size-large wp-image-513" src="https://installingcats.com/wp-content/uploads/2015/10/android-studio-debug-edit-configuration-screen-1-1024x641.png" alt="android-studio-debug-edit-configuration-screen" width="665" height="416" srcset="https://installingcats.com/wp-content/uploads/2015/10/android-studio-debug-edit-configuration-screen-1-1024x641.png 1024w, https://installingcats.com/wp-content/uploads/2015/10/android-studio-debug-edit-configuration-screen-1-300x188.png 300w, https://installingcats.com/wp-content/uploads/2015/10/android-studio-debug-edit-configuration-screen-1-768x481.png 768w, https://installingcats.com/wp-content/uploads/2015/10/android-studio-debug-edit-configuration-screen-1-1536x961.png 1536w, https://installingcats.com/wp-content/uploads/2015/10/android-studio-debug-edit-configuration-screen-1-2048x1282.png 2048w" sizes="(max-width: 665px) 100vw, 665px" /></a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Android AsyncTask return result</title>
		<link>https://installingcats.com/2015/10/24/android-asynctask-return-result/</link>
		
		<dc:creator><![CDATA[ben]]></dc:creator>
		<pubDate>Sat, 24 Oct 2015 21:43:03 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[observer pattern]]></category>
		<guid isPermaLink="false">http://installingcats.com/?p=504</guid>

					<description><![CDATA[To get Android AsyncTask to return a result use a callback method (Observer pattern) by following these steps. Define a constructor for our async class which extends AsyncTask (we&#8217;re required to subclass/extend AsyncTask for use). Let&#8217;s call our AsyncTask class MyAsyncTask. Constructor parameter takes a class which will handle the AsyncTask result.  Usually an Activity or Fragment, [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>To get Android AsyncTask to return a result use a callback method (Observer pattern) by following these steps.</p>
<ol>
<li>Define a constructor for our async class which extends AsyncTask (we&#8217;re required to subclass/extend AsyncTask for use). Let&#8217;s call our AsyncTask class MyAsyncTask.</li>
<li>Constructor parameter takes a class which will handle the AsyncTask result.  Usually an Activity or Fragment, but could be a Robolectric Unit Test class for example.</li>
<li>Declare a member variable/private field to hold the handling Activity/Fragment/Test. We&#8217;ll call it ResultListener.  The constructor will assign its parameter input to this member variable.</li>
<li>Declare an Interface within  MyAsyncTask. Let&#8217;s call it ResultListener</li>
<li>ResultListener defines a single method that our handling class must implement.  Let&#8217;s name the method handleAsyncResult and in this case it&#8217;s going to take a single boolean as an input parameter.</li>
<li>In onPostExecute, call our listener class handler method, supplying a value to the input parameter as appropriate for the outcome of doInBackground.</li>
</ol>
<p>Here&#8217;s a concrete example of an Android AsyncTask returning a result:</p>
<p>&nbsp;</p>
<pre>public class MyAsyncTask&lt;T&gt; extends AsyncTask&lt;T, Void, Boolean&gt; {
    private final String TAG = this.getClass().getName();
    ResultListener listener;

    public interface ResultListener {
        void handleAsyncResult(boolean result);
    }

    WebProxy proxy;

    public MyAsyncTask(ResultListener listener) {
        this.listener = listener;
    }

    @Override
    protected Boolean doInBackground(T... params) {
        // do interesting long running things here, Network, database, etc.
        Log.i(TAG, String.format("doInBack: sending %s via Retrofit", params.getClass().getName()));
        return true;
    }

    @Override
    protected void onPostExecute(Boolean success) {
        listener.handleAsyncResult(success);
    }
}
</pre>
<p>As a bonus this AsyncTask uses a Type parameter &lt;T&gt; as input, so it can handle different input types for the AsyncTask.execute(input). This will make your AsyncTask more reusable and easy to extend for future use.</p>
<p>When MyAsyncTask completes doInBackground, it will pass a boolean to onPostExecute which we&#8217;re going to send along to our handling class through listener.handleAsyncResult(success).</p>
<p>Within our handling class (supplied to our AsyncTask constructor) we&#8217;ll need to do two things:</p>
<ol>
<li>Make our class implement our Interface by adding  &#8220;implements MyAsyncTask.ResultListener&#8221; after the class name.</li>
<li>Define a method within our handling class with a signature that matches MyAsyncTask.ResultListener.</li>
</ol>
<p>Here&#8217;s an example for our implementing class:</p>
<pre>public class Test implements MyAsyncTask.ResultListener {
private boolean asyncResult;

@Override
public void handleAsyncResult(boolean result) {
    asyncResult = result;
}


@Test
public void firstAsyncTest() throws Exception {
    MyAsyncTask&lt;Checkin&gt; myTask = new MyAsyncTask&lt;&gt;(this);
    myTask.execute(someArrayOfTypeT);
    assertThat(asyncResult).isTrue();
}

}</pre>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Retrofit error 415 400 object with Date field Fix @JsonFormat annotation</title>
		<link>https://installingcats.com/2015/10/22/retrofit-error-415-400-object-date-field/</link>
		
		<dc:creator><![CDATA[ben]]></dc:creator>
		<pubDate>Thu, 22 Oct 2015 21:36:13 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[jackson]]></category>
		<category><![CDATA[retrofit]]></category>
		<guid isPermaLink="false">http://installingcats.com/?p=500</guid>

					<description><![CDATA[Retrofit error 415 or error 400 on an object with a Date field can be fixed by using @JsonFormat annotation with the proper date pattern format specified in the annotation. java.util.Date toString() (for my locale/region) returns a string date format of MMM dd, yyyy hh:mm:ss aa Example: Oct 22, 2015 11:09:55 PM For Retrofit / [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Retrofit error 415 or error 400 on an object with a Date field can be fixed by using @JsonFormat annotation with the proper date pattern format specified in the annotation.</p>
<p>java.util.Date toString() (for my locale/region) returns a string date format of MMM dd, yyyy hh:mm:ss aa</p>
<p>Example: Oct 22, 2015 11:09:55 PM</p>
<p>For Retrofit / Jackson to serialize / deserialize a date (java.util.Date) properly, you must annotate your Date fields with the corresponding date pattern:</p>
<pre>@JsonFormat(shape= JsonFormat.Shape.STRING, pattern = "MMM dd, yyyy hh:mm:ss aa")</pre>
<p>Pay special attention to the uppercase / lowercase lettering of each date part.  Two digit date of month must be LOWERCASE (i.e. &#8220;dd&#8221; not &#8220;DD&#8221;).  Otherwise it will be interpreted as a <em>date of year</em> which can be three digits.  (I was getting bizarre JSON serialization JSON deserialization results such as Oct 22 becoming Dec 362 by having the wrong case on my date part of the date format (i.e. &#8220;DD&#8221;.)</p>
<p>For the full list of date format parts that Jackson (fasterxml) uses see:</p>
<p><a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/text/SimpleDateFormat.html" target="_blank" rel="noopener">http://docs.oracle.com/javase/1.5.0/docs/api/java/text/SimpleDateFormat.html</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>H2 Web Console to In Memory Database &#8211; Spring Boot</title>
		<link>https://installingcats.com/2015/10/21/h2-web-console-memory-database-spring-boot/</link>
		
		<dc:creator><![CDATA[ben]]></dc:creator>
		<pubDate>Wed, 21 Oct 2015 18:04:52 +0000</pubDate>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[h2]]></category>
		<guid isPermaLink="false">http://installingcats.com/?p=496</guid>

					<description><![CDATA[To get an H2 Database Web Console accessing an in-memory database running on Spring Boot: Register H2&#8217;s WebServlet (with UrlMapping /console/*) to your Spring project in a Configuration annotated class. Restart your Application. Open a web page to http://localhost:8080/console/ Be sure you&#8217;re accessing the correct database JDBC URL (default would be jdbc:h2:mem:testdb) (Credit: Spring Framework Guru) &#160; import org.h2.server.web.WebServlet; [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>To get an H2 Database Web Console accessing an in-memory database running on Spring Boot:</p>
<ol>
<li>Register H2&#8217;s WebServlet (with UrlMapping /console/*) to your Spring project in a Configuration annotated class. Restart your Application.</li>
<li>Open a web page to http://localhost:8080/console/</li>
<li>Be sure you&#8217;re accessing the correct database JDBC URL (default would be <strong>jdbc:h2:mem:testdb</strong>)</li>
</ol>
<p>(Credit: <a href="https://springframework.guru/using-the-h2-database-console-in-spring-boot-with-spring-security/" target="_blank" rel="noopener">Spring Framework Guru</a>)</p>
<p>&nbsp;</p>
<pre>
import org.h2.server.web.WebServlet;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;</pre>
<pre>@Configuration
public class H2ConsoleWebConfiguration {
 @Bean
 ServletRegistrationBean h2servletRegistration() {
 ServletRegistrationBean registrationBean = new ServletRegistrationBean(new WebServlet());
 registrationBean.addUrlMappings("/console/*");
 return registrationBean;
 }
}</pre>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Robolectric reference</title>
		<link>https://installingcats.com/2015/10/19/robolectric-reference/</link>
		
		<dc:creator><![CDATA[ben]]></dc:creator>
		<pubDate>Mon, 19 Oct 2015 14:02:03 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[robolectric]]></category>
		<guid isPermaLink="false">http://installingcats.com/?p=493</guid>

					<description><![CDATA[Robolectric Android testing Fragments and more private ReminderManagerFragment startReminderManagerFragment() { final ReminderManagerFragment fragment = new ReminderManagerFragment(); SupportFragmentTestUtil.startVisibleFragment(fragment); return fragment; } @Test public void reminderManagerTest() throws Exception { // by default there should be 3 Reminder rows ReminderManagerFragment fragment = startReminderManagerFragment(); assertThat(fragment).isNotNull(); Button addButton = (Button) fragment.getView().findViewById(R.id.reminder_add_button); assertThat(addButton).isNotNull(); List&#60;Reminder&#62; reminders = getReminders(TestValues.BillyUser); assertThat(reminders.size()).isEqualTo(3); // add a [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Robolectric Android testing Fragments and more</p>
<pre>private ReminderManagerFragment startReminderManagerFragment() {
    final ReminderManagerFragment fragment = new ReminderManagerFragment();
    SupportFragmentTestUtil.startVisibleFragment(fragment);
    return fragment;
}</pre>
<pre></pre>
<pre>@Test
public void reminderManagerTest() throws Exception {
    // by default there should be 3 Reminder rows
    ReminderManagerFragment fragment = startReminderManagerFragment();
    assertThat(fragment).isNotNull();
    Button addButton = (Button) fragment.getView().findViewById(R.id.reminder_add_button);
    assertThat(addButton).isNotNull();

    List&lt;Reminder&gt; reminders = getReminders(TestValues.BillyUser);
    assertThat(reminders.size()).isEqualTo(3);

    // add a reminder, assert reminders = 4
    addButton.performClick();

    //assertThat(reminders.size()).isEqualTo(4);
    TimePickerFragment pickerFragment =
            (TimePickerFragment) fragment.getFragmentManager()
                    .findFragmentByTag(ReminderManagerFragment.TIME_DIALOG);
    assertThat(pickerFragment).isNotNull();

    reminders = getReminders(TestValues.BillyUser);
    assertThat(reminders.size()).isEqualTo(4);

    AlertDialog pickerDialog = (AlertDialog) pickerFragment.getDialog();

    assertThat(pickerDialog).isNotNull();
    assertThat(pickerDialog.getButton(AlertDialog.BUTTON_POSITIVE)).isNotNull();

    Button pickerOKButton = (Button) pickerDialog.getButton(AlertDialog.BUTTON_POSITIVE);
    pickerOKButton.performClick();

    // check that an alarm was set
    ShadowAlarmManager shadowAlarmManager = shadowOf(AlarmFactory.getAlarmManager(mCtx));
    // shadow AlarmManager should return 0 alarms
    List&lt;ShadowAlarmManager.ScheduledAlarm&gt; shadowAlarms = shadowAlarmManager.getScheduledAlarms();
    Log.i(TAG, "alarms currently set: " + shadowAlarms.size());
    assertThat(shadowAlarms.size()).isGreaterThan(0);</pre>
<p>&nbsp;</p>
<p>Try changing TimePicker Hour and Minutes and resubmit AlertDialog (TimePickerDialog), they key method being ((TimePickerDialog) pickerDialog).updateTime(hh,mm);</p>
<pre>// try adding a second reminder &amp; alarm
addButton.performClick();

pickerFragment =
        (TimePickerFragment) fragment.getFragmentManager()
                .findFragmentByTag(ReminderManagerFragment.TIME_DIALOG);

assertThat(pickerFragment).isNotNull();

reminders = getReminders(TestValues.BillyUser);
assertThat(reminders.size()).isEqualTo(5);

pickerDialog = (AlertDialog) pickerFragment.getDialog();


assertThat(pickerDialog).isNotNull();

((TimePickerDialog) pickerDialog).updateTime(18, 30);

pickerOKButton = (Button) pickerDialog.getButton(AlertDialog.BUTTON_POSITIVE);
pickerOKButton.performClick();

shadowAlarms = shadowAlarmManager.getScheduledAlarms();
for (ShadowAlarmManager.ScheduledAlarm sAlarm :
        shadowAlarms) {
    Log.i(TAG, Dates.getBasicDate(new Date(sAlarm.triggerAtTime)) + " " +
            sAlarm.operation.toString());
}
Log.i(TAG, "alarms currently set: " + shadowAlarms.size());
assertThat(shadowAlarms.size()).isGreaterThan(1);</pre>
<p>More to come</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PendingIntent requestCode getBroadcast useless doesn&#8217;t work</title>
		<link>https://installingcats.com/2015/10/18/pendingintent-requestcode-getbroadcast-useless-doesnt-work/</link>
		
		<dc:creator><![CDATA[ben]]></dc:creator>
		<pubDate>Sun, 18 Oct 2015 15:31:52 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<guid isPermaLink="false">http://installingcats.com/?p=485</guid>

					<description><![CDATA[Android PendingIntent requestcode on getBroadcast() method is useless.  It won&#8217;t be used at all for making a unique PendingIntent. Use other fields such as Data (Intent.setData(&#8220;someStringPerhapsInteger.valueOf(RequestCode)&#8221;)) to make your PendingIntent unique for use with AlarmManager for Notifications for example. http://stackoverflow.com/a/33203752/2301224]]></description>
										<content:encoded><![CDATA[<p>Android PendingIntent requestcode on getBroadcast() method is useless.  It won&#8217;t be used at all for making a unique PendingIntent.</p>
<p>Use other fields such as Data (Intent.setData(&#8220;someStringPerhapsInteger.valueOf(RequestCode)&#8221;)) to make your PendingIntent unique for use with AlarmManager for Notifications for example.</p>
<p><a href="http://stackoverflow.com/a/33203752/2301224" target="_blank" rel="noopener">http://stackoverflow.com/a/33203752/2301224</a></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/

Page Caching using disk: enhanced (Page is feed) 
Lazy Loading (feed)

Served from: installingcats.com @ 2023-11-19 07:27:31 by W3 Total Cache
-->