tag:blogger.com,1999:blog-51223518600527525042024-03-12T20:57:17.336-07:00Cubicware Dev BlogA place to document lessons learned during development
<a href="http://cubicware.com">Download my Android apps from Cubicware.com</a>Anonymoushttp://www.blogger.com/profile/08185169088111086060noreply@blogger.comBlogger9125tag:blogger.com,1999:blog-5122351860052752504.post-56700406180103235922010-03-06T12:49:00.000-08:002010-03-06T12:55:02.515-08:00Fixing CPANEL hacked filesBefore I switched to a VPS at linode.com I ran a CPanel server which apparently had some kind of vulnerability which managed to infect every file on the server with a malicious link to 'constellation.ws' I found this clean up method which saved me a lot of time, so I thought I would archive the solution here.<br /><br /><code># grep -rl constellations.ws * | sed 's/ /\ /g' | xargs sed -i 's/<iframe src="http:\/\/www.constellations.ws\/index.php" width=1 height=1 frameborder=0 scrolling=NO><\/iframe>//g'</code>Anonymoushttp://www.blogger.com/profile/08185169088111086060noreply@blogger.com0tag:blogger.com,1999:blog-5122351860052752504.post-6588721572136525062009-02-11T23:14:00.000-08:002009-02-11T23:23:22.604-08:00X Y motionAndroid's onTouchEvent was giving me some difficulties. I want to increment and decrement my countdown timer based on touch screen input. The user should be able to touch the screen anywhere and move their finger left, right, up or down, and the values should change in a logical way. I discovered I had to introduce a certain scaling factor in order to prevent the tiny increments and decrements from canceling each other out effectively. The code I came up with computes the delta in X and Y coordinates and only increments or decrements the countdown timer values if the delta is more than a certain amount, in the example the value is 5. You could change this to make the system more or less sensitive. This effectively "understands" the intent of the user's gesture.<br /><br />Here is my onTouchEvent, it should be fairly self explanatory.<br /><pre class="prettyprint"><br /> @Override<br /> public boolean onTouchEvent(MotionEvent event) {<br /> float mvX;<br /> float mvY;<br /> boolean chg;<br /> switch (event.getAction())<br /> {<br /> case MotionEvent.ACTION_DOWN: <br /> startY = event.getY();<br /> startX = event.getX(); <br /> break;<br /> case MotionEvent.ACTION_MOVE: <br /> endY = event.getY();<br /> endX = event.getX(); <br /> break; <br /> case MotionEvent.ACTION_UP: <br /> endY = event.getY();<br /> endX = event.getX(); <br /> break;<br /> default:<br /> return false;<br /> }<br /> chg = false;<br /> mvY = endY - startY;<br /> if(mvY > 5) { <br /> mySecondsTotal += 1;<br /> chg = true;<br /> }<br /> if(mvY < -5) {<br /> mySecondsTotal -= 1;<br /> chg = true; <br /> }<br /> mvX = endX - startX;<br /> if(mvX > 5) { <br /> mySecondsTotal += 1;<br /> chg = true;<br /> }<br /> if(mvX < -5) {<br /> mySecondsTotal -= 1;<br /> chg = true; <br /> }<br /> if (chg == false)<br /> return true; <br /> startY = event.getY();<br /> startX = event.getX(); <br /> if (mySecondsTotal < 0)<br /> mySecondsTotal = 0;<br /> Message m = new Message();<br /> m.what = timer.GUIUPDATEIDENTIFIER; <br /> this.myYogaViewUpdateHandler.sendMessage(m); <br /> return true; <br /> }<br /></pre>Anonymoushttp://www.blogger.com/profile/08185169088111086060noreply@blogger.com0tag:blogger.com,1999:blog-5122351860052752504.post-81262207636328414512009-02-09T22:31:00.000-08:002009-02-09T22:51:34.655-08:00Using a RadioGroupSet up your RadioGroup and RadioButtons in your xml layout:<br /><br /><pre class="prettyprint"><br /><radiogroup id="@+id/group1" layout_width="fill_parent" layout_height="wrap_content" orientation="horizontal"><br /><radiobutton id="@+id/radio1" text="Bell" layout_width="wrap_content" layout_height="wrap_content"><br /></radiobutton><br /><radiobutton id="@+id/radio2" text="Crystal" layout_width="wrap_content" layout_height="wrap_content"><br /></radiobutton><br /><radiobutton id="@+id/radio3" text="Gong" layout_width="wrap_content" layout_height="wrap_content"><br /></radiobutton><br /></radiogroup><br /></pre><br /><br />Save your preferences<br /><br /><pre class="prettyprint"><br />int chime = chimes.getCheckedRadioButtonId();<br /></pre><br /><br />At first nothing is selected and getCheckedRadioButtonId will return a value of -1, so you might want to test for this condition when getting your saved preferences. Otherwise you'll get the Unique ID of the checked Radio Button which you need to test using R.id.<your button><br /><br /><pre class="prettyprint"><br />int chime = prefs.getInt(PREF_CHIME, R.id.radio1);<br />if (chime < 1)<br /> chime = R.id.radio1;<br />chimes.check(chime);<br /></pre><br /><br />Handle the options:<br /><br /><pre class="prettyprint"><br />int chime = prefs.getInt(preferences.PREF_CHIME, R.raw.bell); <br />switch(chime){ <br /> case R.id.radio1: {<br /> mp = MediaPlayer.create(timer.this, R.raw.bell);<br /> break;<br /> }<br /> case R.id.radio2: {<br /> mp = MediaPlayer.create(timer.this, R.raw.crystal);<br /> break;<br /> }<br /> case R.id.radio3: {<br /> mp = MediaPlayer.create(timer.this, R.raw.gong);<br /> break;<br /> }<br /> default:<br /> mp = MediaPlayer.create(timer.this, R.raw.bell);<br /> break; <br /> }<br /> try {<br /> mp.prepare();<br /> } catch (IllegalStateException e) {<br /> // TODO Auto-generated catch block<br /> e.printStackTrace();<br /> } catch (IOException e) {<br /> // TODO Auto-generated catch block<br /> e.printStackTrace();<br />} <br /></pre>Anonymoushttp://www.blogger.com/profile/08185169088111086060noreply@blogger.com0tag:blogger.com,1999:blog-5122351860052752504.post-10160793733745519442009-01-31T13:42:00.000-08:002009-01-31T13:51:29.643-08:00T-Mobile 3G ProblemsTurns out that when you download an Adroid APK file from a web page and you're on the T-Mobile 3G network you don't always get the whole APK file. You might need to switch to a Wireless network connection to get a good download.<br /><br />If you're trying to download a third party APK file like the ones I develop and you get an odd error that the package you're trying to install is replacing an existing package and this is followed by an installation failed message, you could be seeing this problem.<br /><br />Some reports indicate you might also be able to get around this by switching to 2G mode, but I haven't tried it.<br /><br /><a href="http://groups.google.com/group/android-beginners/browse_thread/thread/4f82b29159a341fe">Here is another resource</a><br /><br />Way to go T-Mobile!Anonymoushttp://www.blogger.com/profile/08185169088111086060noreply@blogger.com0tag:blogger.com,1999:blog-5122351860052752504.post-9092378224707003782009-01-31T03:14:00.000-08:002009-01-31T16:22:09.883-08:00Webkit About boxThis is kind of overkill for an About dialog, but the neat thing is you can click on the URL and go right to the web page. Hitting the back button returns to your application so it is very smooth<br /><br /><pre class="prettyprint"><br />public class about extends Activity {<br />WebView aboutText;<br />@Override<br />public void onCreate(Bundle icicle) {<br /> super.onCreate(icicle);<br /> setContentView(R.layout.about);<br /> aboutText = (WebView)findViewById(R.id.about_text);<br /> String str = "<I>Yoga Timer</I><HR/>Version 1.4<BR/>" +<br /> "<P>Patterns multiply the starting value to set separate durations for the four parts of the breath: <UL>" +<br /> "<LI>Inhalation (Pooraka)<LI>Retention (Abhyantar Kumbhaka)<LI>Exhalation (Rechaka)<LI>Suspension (Bahya Kumbhaka)</UL>" +<br /> "<P>Check for new versions here <A href=http://cubicware.com/>CUBICWARE.COM</A>";<br /> aboutText.loadData(str, "text/html", "utf-8"); <br /> Button okButton = (Button) findViewById(R.id.okButton);<br /> okButton.setOnClickListener(new View.OnClickListener() {<br /> public void onClick(View view) {<br /> finish();<br /> }<br /> }); <br />}<br />}<br /></pre>Anonymoushttp://www.blogger.com/profile/08185169088111086060noreply@blogger.com0tag:blogger.com,1999:blog-5122351860052752504.post-51284962463723488912009-01-31T03:09:00.001-08:002009-01-31T03:25:08.310-08:00Android notificationsThis is a work in progress. I don't think the light notification is working yet.<br /><br /><pre class="prettyprint"><br />if (notifyVibrate){<br /> Notification notification = new Notification(); <br /> notification.vibrate = new long[] { 100, 250, 100, 500};<br /> nm.notify(NOTIFY_ID, notification); <br />}<br />if (notifyLight) { <br /> Notification notification = new Notification();<br /> notification.ledARGB = 0xFFFF5171;<br /> notification.ledOnMS = 100;<br /> notification.ledOffMS = 100; <br /> notification.flags = Notification.FLAG_SHOW_LIGHTS;<br /> nm.notify(NOTIFY_ID, notification);<br />}<br />if (notifyToast) {<br /> Toast toast = Toast.makeText(timer.this , R.string.notification_text, Toast.LENGTH_SHORT);<br /> toast.setGravity(Gravity.CENTER, 0, 0);<br /> toast.show(); <br />}<br />if (notifySound) {<br /> mp.play(timer.this, Settings.System.DEFAULT_NOTIFICATION_URI, false, AudioManager.STREAM_ALARM); <br />}<br /></pre>Anonymoushttp://www.blogger.com/profile/08185169088111086060noreply@blogger.com0tag:blogger.com,1999:blog-5122351860052752504.post-61038986021787078442009-01-31T02:53:00.000-08:002009-01-31T14:14:04.818-08:00Signing Android packages using Eclipse external tools commands.Here is how I got this to work. You might be able to integrate it into Eclipse better but I couldn't because I needed to export to a folder outside of my Eclipse workspace. Might be able to do it into your workspace but I didn't try to figure that out.<br /><br />First you will need to create your <span style="font-family: courier new;">android.keystore</span> using keytool. The easiest way to do this is find the keytool and open a command line session to the directory it is in and then generate your certificate from the command line. It's pretty straightforward.<br /><br />Create a bat file that looks like the one below. <br /><br /><pre class="prettyprint">@echo off<br />@echo Signing "%1"<br />C:\SUN\SDK\JDK\bin\jarsigner -verbose -keystore android.keystore "%1" android<br />if errorlevel 1 goto ERROR<br />C:\SUN\SDK\JDK\bin\jarsigner -verify "%1"<br />if errorlevel 1 goto ERROR<br />goto DONE<br />:ERROR<br />@pause<br />:DONE<br />@echo on<br /></pre><br /><br />I created a folder called Deploy someone in my Documents hierarchy and copied this bat file and <span style="font-family: courier new;">android.keystore</span> into that folder.<br /><br />When you want to deploy your application, highlight your Package Name in Eclipse and right click. Select Android Tools/Export Unsigned Package and export into your Deploy directory you created above.<br /><br />Now open a CMD prompt and find your Deploy folder. Run sign.bat <yourpackage><span style="font-family: courier new;"><packagename>.apk</span><br /><br />Now you're ready to upload your signed application to your web space for people to install from. <br /><br />You can also configure Eclipse to run this bat file as an external program. Just go to Run/External Tools/External Tools Configurations and create a new Program. Call it Sign Android Package or whatever you want, and in the location field point to your bat file. On my system this looks like this<br /><br /><span style="font-family: courier new;">K:\Users\John\Documents\deploy\sign.bat</span><br /><br />Set the working directory to the deploy folder<br /><br /><span style="font-family: courier new;">K:\Users\John\Documents\deploy</span><br /><br />For the Argment specify your package name with the apk extension:<br /><br /><span style="font-family: courier new;">${project_name}.apk</span><br /><br />That's it! Now you can sign your package. Just remember to Export the unsigned package each time you want to deploy your application, and then run this external command to sign it.<br /><br />Android phones are easy to install applications on, you just click on the file and download it but see my note concerning potential problems downloading package files with T-Mobile's 3G network. Search for the 3g label in this blog.<br /></yourpackage>Anonymoushttp://www.blogger.com/profile/08185169088111086060noreply@blogger.com3tag:blogger.com,1999:blog-5122351860052752504.post-23548610710226898832009-01-31T02:44:00.000-08:002009-01-31T03:07:33.832-08:00Code highlighting on bloggerI found this <a href="http://lukabloga.blogspot.com/2008/10/to-test-new-highlighting.html">here </a> but thought I'd document it in case it disappears.<br /><br /><pre class="prettyprint"><span class="pun"><span class="pun"><</span></span><span class="tag"><span class="tag">link</span></span><span class="pln"><span class="pln"> </span></span><span class="atn"><span class="atn">href</span></span><span class="pun"><span class="pun">=</span></span><span class="atv"><span class="atv">"http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.css"</span></span><span class="pln"><span class="pln"> </span></span><span class="atn"><span class="atn">type</span></span><span class="pun"><span class="pun">=</span></span><span class="atv"><span class="atv">"text/css"</span></span><span class="pln"><span class="pln"> </span></span><span class="atn"><span class="atn">rel</span></span><span class="pun"><span class="pun">=</span></span><span class="atv"><span class="atv">"stylesheet"</span></span><span class="pln"><span class="pln"> </span></span><span class="pun"><span class="pun">/></span></span><span class="pln"><span class="pln"><br /></span></span><span class="pun"><span class="pun"><</span></span><span class="tag"><span class="tag">script</span></span><span class="pln"><span class="pln"> </span></span><span class="atn"><span class="atn">type</span></span><span class="pun"><span class="pun">=</span></span><span class="atv"><span class="atv">"text/javascript"</span></span><span class="pln"><span class="pln"> </span></span><span class="atn"><span class="atn">src</span></span><span class="pun"><span class="pun">=</span></span><span class="atv"><span class="atv">"http://google-code-prettify.googlecode.com/svn/trunk/src/prettify.js"</span></span><span class="pun"><span class="pun">></span><span class="pln"> </span></span><span class="pln"> </span><span class="pun"><span class="pun"><</span></span><span class="pun"><span class="pun">/</span></span><span class="tag"><span class="tag">script</span></span><span class="pun"><span class="pun">></span></span><span class="pln"><br /></span></pre><br /><pre class="prettyprint"><span><span class="pun"><</span></span><span class="pln">body onload</span><span class="pun">=</span><span class="str">'prettyPrint()'</span><span><span class="pun">></span></span><span class="pln"><br /><br /><br /></span><span><span class="pun"><</span></span><span class="tag">pre</span><span class="pln"> </span><span class="atn">class</span><span class="pun">=</span><span class="atv">"prettyprint"</span><span><span class="pun">></span></span><span class="pln"><br />... # Your code goes here<br /></span><span class="pun"><span class="pun"><</span></span><span class="pun"><span class="pun">/</span></span><span class="tag">pre</span><span><span class="pun">></span></span><span class="pln"><br /></span><br /></pre>Anonymoushttp://www.blogger.com/profile/08185169088111086060noreply@blogger.com0tag:blogger.com,1999:blog-5122351860052752504.post-11599284094409840242009-01-31T01:15:00.000-08:002009-01-31T01:20:15.793-08:00Android alertdialog from a menu selectionHow to pop up a dialog from a menu selection<br /><pre class="prettyprint"><br /> @Override<br /> public boolean onOptionsItemSelected(MenuItem item) {<br /> switch(item.getItemId()) {<br /> case (MENU_ABOUT): { <br /> new AlertDialog.Builder(this)<br /> .setTitle("About Mala Counter")<br /> .setMessage("Version 1.0 from Cubicware.com")<br /> .setPositiveButton(android.R.string.ok, null)<br /> .show();<br /> return true;<br /> }<br /> }<br /> return false;<br /> } <br /></pre>Anonymoushttp://www.blogger.com/profile/08185169088111086060noreply@blogger.com0