Search This Blog

Showing posts with label troubleshooting. Show all posts
Showing posts with label troubleshooting. Show all posts

27 April 2017

Screen flashing after upgrade

I finally got around to upgrading this (now old) machine from 16.04 -> 17.10 over the last couple days.  After fighting with DKMS it's finally booting and working... except the screen keeps flashing.

Why am I facing this reportedly fixed bug?

I managed to fix it by going into the NVidia X Server Settings and turning off this flag:

As soon as I unchecked that, everything was fine.

22 April 2016

Ubuntu upgrade - left mouse click failure

I let Ubuntu upgrade to 16.04 today.  Afterwards, the mouse would move, right-click worked, and left-click worked in some apps. Most notably it did not work on the system menu/notification bar.  Doesn't even work on the login UI.

I knew this happened last time too, but couldn't remember why.  I finally figured it out.

In Firefox, go into Settings, turn off chat. Reboot (I know, shouldn't have to do that, but I had to).  Now,  mouse works.  Go back in and turn it back on, and it's still fine.

13 April 2016

Unable to connect ADB to CM10

As an Android developer, I have a ton of spare devices running various versions of Android.  One of them is the original Samsung Galaxy Note running CM10 so that I can test backward compat with 4.x.

Unfortunately, I have been unable to connect to it via adb/mtp/mass_storage for quite some time.  adb via wifi works, but is dog slow when running connectedCheck.

Luckily, I figured out how to fix it yesterday (and thus the reason I am leaving this post so I can find it in a years time when I forget yet again).

It's completely incompatible with USB hubs.  While all my other devices are plugged in through a single hub so that I can test on multiple devices, this CM10 device requires that I plug it in directly.  Once I did that, it started working normally.

Why didn't I think of that earlier?  Did I mention that none of the other devices have this problem?  Just the CM10 device.

28 October 2015

USB3 hub disconnecting - dropping adb connection


I'm probably jumping the gun, but I am hopeful.

I was having a problem where my new OctoFire hub was disconnecting quite often -- especially if using something like Android ScreenMonitor.

I think it is fixed.  I found the suggestion to disable the autosuspend here.

Edit the /etc/default/grub file and append to the GRUB_CMDLINE_LINUX_DEFAULT line:
usbcore.autosuspend=-1
Then run:
sudo update-grub
sudo reboot

11 July 2013

Changing the Wallpaper to Scaled in Ubuntu 13.04

After upgrading to Ubuntu 13.04, I lost the ability to scale the desktop background.  At first, I tried just saving the image at a different size, but it kept cropping it in ways I didn't like.

Solution was pretty simple (though it should have still been available in the UI):

gsettings set org.gnome.desktop.background picture-options "scaled"

03 June 2013

Unable to open MTP device '[usb:003,021]'

Recently I upgraded my Samsung Galaxy Note to JellyBean. Around the same time, I also upgraded both the desktop and laptop to Raring Ringtail.  When connecting the device to the dev boxes, the laptop continued to work. The desktop however would give me a never ending loop of popups like this one:
Unable to open MTP device '[usb:003,021]'

While trying to resolve it, I found this fix about the ASUS Transformer...

I followed the same instructions with a few slight tweaks...

/etc/udev/rules.d/51-android.rules:
# MTP Settings added by Malachi
# From dmesg:
# [  166.765498] usb 3-4: reset high-speed USB device number 20 using ehci-pci
# [  166.845468] usb 3-4: USB disconnect, device number 20
# [  167.084889] usb 3-4: new high-speed USB device number 21 using ehci-pci
# [  167.219607] usb 3-4: New USB device found, idVendor=04e8, idProduct=6860
# [  167.219609] usb 3-4: New USB device strings: Mfr=2, Product=3, SerialNumber=4
# [  167.219611] usb 3-4: Product: SAMSUNG-SGH-I717
# [  167.219613] usb 3-4: Manufacturer: samsung
# [  167.219614] usb 3-4: SerialNumber: 2a4c2c04
ENV{ID_MODEL}=="SAMSUNG-SGH-I717", ENV{ID_MODEL_ID}=="6860", ACTION=="add", RUN+="/usr/bin/sudo -b -u malachi /usr/bin/go-mtpfs -allow-other=true /media/SGH-I717"
ENV{ID_MODEL}=="SAMSUNG-SGH-I717", ENV{ID_MODEL_ID}=="6860", ACTION=="remove", RUN+="/bin/umount /media/SGH-I717"

in /etc/fstab:
DeviceFs(SAMSUNG-SGH-I717)    /media/SGH-I717   fuse.DeviceFs(SAMSUNG-SGH-I717)    allow_other,rw,user,noauto    0    0

Now, when I connect, I get about 50 popups but then ADB works again.

24 March 2013

ia32-libs

Android is full of 32-bit tools and dependencies.
Running on x64 can be problematic unless you install ia32-libs.
Unfortunately, Ubuntu has been having issues installing it lately.

After 2 days, I finally found the solution here:

sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install ia32-libs

After that, everything installs fine.

13 May 2012

LMDE upgrade broke me

While not strictly an Android issue, I figured I would post this here since it it related to my previously mentioned build box.

Every time LMDE upgrades, it breaks my packages.  At the very least, it breaks the nvidia driver (I should probably switch to source-based) but this last time, it auto uninstalled almost everything NVidia/Gnome/X11/Mate/Cinnamon/etc.

You might be asking, "Why didn't you read the release notes that said to not upgrade yet?"

Well, to be honest, I was used to the simplicity of the daily non-breaking Ubuntu updates.  This new Debian tri-weekly breaking rolling update is a new beast to get used to. I put rolling update in italic because I don't understand how updating more packages less often is 'rolling'.

Anyways, I spent the last 3 days trying to fix my box.  It would boot fine - into a command line... but I really prefer to use Firefox/Chrome/Opera over links to do my web searching.

I am sure these instructions are not the correct way to do things.  You might even say it could be a bad idea to get into someones head.  But since that was the only thing I tried that allowed me to start booting into X again, here we go.

STEP 1:
First off, I determined something I thought should be installed.  I don't know what the process in my head is for that, other than just selecting some random names I thought out to be there.  For example 'gdm'.

STEP 2:
Secondly, I need to find out the correct name for it. IE: it's 'gdm3' not 'gdm'. For this, I did:
apt search gdm
and found the one that looked right (in this case 'gdm3').

STEP 3:
Then, I needed to know whether it was actually installed yet or not -- and at which revision. For that I did:
apt-cache policy gdm3

This showed that it was not currently installed!  Well that doesn't sound right.

STEP 4:
If step 3 showed the correct (updated) candidate:
apt install gdm3
If it fails to install, it might list some unmet dependency.  If so, I start over at STEP 3 (or STEP 2 if that doesn't work) using that dependency as the new name to test.

STEP 5:
If STEP 3 showed the wrong (or no) candidate, I looked at the numbers [priority] at the beginning of each URL.  It might show something like '500' for the one you want to install but '*** 700' for the one you have installed or it wants installed.  Look at the URL for the one with the higher unwanted priority.

STEP 6:
edit /etc/apt/sources.list and comment out the URL from STEP 5
apt update
apt dist-upgrade
Go to STEP 3.


Like I said, these are probably not a good template to follow; however, next time instead of wasting 3 days trying to fix an upgrade I'll start here.

14 April 2012

Unknown Host Exception

I spent an hour trying to figure out why my little 1-page test app was throwing an UnknownHostException but the browser was working. To make matters worse, there was a red herring in that I could not ping from adb shell.

Turns out it was a stupid ommission. If you are having this problem, don't forget to add this to your AndroidManifest:

<uses-permission android:name="android.permission.INTERNET"/>

23 January 2012

Reverse USB Tethering

I decided to give reverse usb tethering a shot. I don't know which devices easily support this, but I assume you have to be root. In my particular case, I was using an ICS device.  These steps could easily screw up your existing cell routing - so make sure your willing to risk it.

Step 0: Make sure the device is booted and connected via USB

Step 1: Enable tethering on the device side
  • Go to Settings
  • Under the Wireless & Networks, click on More
  • Click on Tethering & portable hotspot
  • Enable USB Tethering
Step 2: Get the IP Address of the device
malachi@onyx:~$ adb shell
root@android:/ # netcfg
lo       UP                                   127.0.0.1/8   0x00000049 00:00:00:00:00:00
dummy0   DOWN                                   0.0.0.0/0   0x00000082 62:bc:02:e1:d5:ea
rmnet0   DOWN                                   0.0.0.0/0   0x00000000 00:00:00:00:00:00
rmnet1   DOWN                                   0.0.0.0/0   0x00000000 00:00:00:00:00:00
rmnet2   DOWN                                   0.0.0.0/0   0x00000000 00:00:00:00:00:00
rmnet3   DOWN                                   0.0.0.0/0   0x00000000 00:00:00:00:00:00
rmnet4   DOWN                                   0.0.0.0/0   0x00000000 00:00:00:00:00:00
rmnet5   DOWN                                   0.0.0.0/0   0x00000000 00:00:00:00:00:00
rmnet6   DOWN                                   0.0.0.0/0   0x00000000 00:00:00:00:00:00
rmnet7   DOWN                                   0.0.0.0/0   0x00000000 00:00:00:00:00:00
sit0     DOWN                                   0.0.0.0/0   0x00000080 00:00:00:00:00:00
rndis0   UP                              192.168.42.129/24  0x00001043 da:02:11:22:14:af
Step 3: Get the matching IP Address of the workstation
malachi@onyx:~$ ifconfig -a usb0
usb0      Link encap:Ethernet  HWaddr e2:31:b5:d7:f3:7b 
          inet addr:192.168.42.74  Bcast:192.168.42.255  Mask:255.255.255.0
          inet6 addr: fe80::e031:b5ff:fed7:f37b/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1990 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1188 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:181334 (181.3 KB)  TX bytes:657452 (657.4 KB)
Step 4: Ping the device from the workstation
malachi@onyx:~$ ping 192.168.42.129
PING 192.168.42.129 (192.168.42.129) 56(84) bytes of data.
64 bytes from 192.168.42.129: icmp_req=1 ttl=64 time=1.01 ms
64 bytes from 192.168.42.129: icmp_req=2 ttl=64 time=0.605 ms

Step 5: Ping the workstation from the device
root@android:/ # ping 192.168.42.74
PING 192.168.42.74 (192.168.42.74) 56(84) bytes of data.
64 bytes from 192.168.42.74: icmp_seq=1 ttl=64 time=0.427 ms
64 bytes from 192.168.42.74: icmp_seq=2 ttl=64 time=0.397 ms
Step 6: Add workstation as the default gateway for the device
root@android:/ # route add default gw 192.168.42.74 dev rndis0
Step 7: Get a list of DNS servers from the workstation
malachi@onyx:~$ cat /etc/resolv.conf
nameserver 172.29.224.11
nameserver 8.8.8.8
Step 8: Add them to the device
root@android:/ # setprop net.dns1 172.29.224.11
root@android:/ # setprop net.dns2 8.8.8.8
Step 9: Setup forwarding from usb0 to eth1 on the workstation
[ most people probably use eth0. Just use ifconfig to check which one is active]

malachi@onyx:~$ sudo su - root
[sudo] password for malachi:
root@onyx:~# echo 1 > /proc/sys/net/ipv4/ip_forward
root@onyx:~# exit
malachi@onyx:~$ sudo iptables --flush -t nat
malachi@onyx:~$ sudo iptables --table nat --append POSTROUTING --out-interface eth1 -j MASQUERADE
malachi@onyx:~$ sudo iptables --append FORWARD --in-interface usb0 -j ACCEPT
Step 10: ping google ;)

malachi@onyx:~$ adb shell
root@android:/ # ping google.com
PING google.com (74.125.127.99) 56(84) bytes of data.
64 bytes from pz-in-f99.1e100.net (74.125.127.99): icmp_seq=1 ttl=51 time=11.8 ms
64 bytes from pz-in-f99.1e100.net (74.125.127.99): icmp_seq=2 ttl=51 time=11.9 ms
And finally, check things like the Browser...






24 August 2011

IntelliJ IDEA and the Android Source tree

It can be quite annoying to develop in the Android source tree if you don't have your IDE properly configured.  I thought I'd share a few notes from my testing IDEA with the repo sync'd tree...

  • When initially making your project, make sure it is a fresh checkout or do a 'make clean'.  Otherwise, all the *_intermediates turn into separate modules.

  • When it auto-detects the Android Facets, uncheck them all. If the Android Facet is setup, you will resolve classes to android-x.jar instead of your module source.
    • It can also auto-generate gen/ directories which cause duplicate R.java clases during builds if the Android Facet is chosen.

  • Since we are not using the Android Facets, the R.java files become a problem.  To correct this, create a new module (and make it a dependency of any module needing the resolution):
Content Root: out/target/common/R
Module File Location: anywhere BUT out/*
  • You probably are not going to be working on every single module unless you work with Cyanogen.  Right click on a module and add it to your favorites.  In the top of the dock, click the pull down and choose to view your favorites.

  • Build from the command line.  You might be able to do it from within the IDE, but I haven't tried that.

Thank you to the JetBrains support team; and a special thanks to Serge Baranov who put up with me long enough to get some of these issues resolved.

05 March 2011

adb does not have permission to access my Atrix?

The Atrix does not have the option to allow installing from unknown (ie: non-Market) locations.  As such, I was unsure what I would see when I tried to install APKs from the command line...

malachi@onyx:~$ adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
????????????    no permissions
Not good... but, surely there is a way around that...?

Turns out it is quite simple really....





1. Stop the existing ADB server.
malachi@onyx:~$ adb kill-server

2. Start adb's server as root.  You could try sudo adb instead, but I didn't...
malachi@onyx:~$ sudo su - root
root@onyx:~# adb start-server
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
root@onyx:~# exit
logout

3. Run adb again... this time, with root running the server, it will work.
malachi@onyx:~$ adb devices
List of devices attached
TA20704PWJ    device

25 July 2010

ClassNotFoundException: org.eoti.MyAuthenticationService in loader dalvik.system.PathClassLoader

I came across an annoying thing today...  I install my app and use it.  I close it and reopen it a few times.  I use other things then come back and use it.  Everything is working fine.

Then I reboot.  Now, every time it tries to use the authentication mechanism, it force closes.  On the phone, it doesn't give any details at all in logCat.  On the emulator, I can't replicate it.

Or can I?  I go into Manage Applications and force close the app.  Launch it and voila, same thing.

Specifically, Account Manager's blockingGetAuthToken is trying to load the authentication class (which it used not more than 30 seconds ago) and I get this:
(slightly cleaned up stack)
W/dalvikvm(  550): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
E/AndroidRuntime(  550): FATAL EXCEPTION: main
E/AndroidRuntime(  550): java.lang.RuntimeException: Unable to instantiate service org.eoti.MyAuthenticationService: java.lang.ClassNotFoundException: org.eoti.MyAuthenticationService in loader dalvik.system.PathClassLoader[/data/app/org.eoti.test-1.apk]
E/AndroidRuntime(  550):        at android.app.ActivityThread.handleCreateService(ActivityThread.java:2943)
E/AndroidRuntime(  550):        at android.app.ActivityThread.access$3300(ActivityThread.java:125)
E/AndroidRuntime(  550):        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2087)
E/AndroidRuntime(  550):        at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(  550):        at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime(  550):        at android.app.ActivityThread.main(ActivityThread.java:4627)
E/AndroidRuntime(  550):        at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(  550):        at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime(  550):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
E/AndroidRuntime(  550):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
E/AndroidRuntime(  550):        at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(  550): Caused by: java.lang.ClassNotFoundException: org.eoti.MyAuthenticationService in loader dalvik.system.PathClassLoader[/data/app/org.eoti.test-1.apk]
E/AndroidRuntime(  550):        at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243)
E/AndroidRuntime(  550):        at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
E/AndroidRuntime(  550):        at java.lang.ClassLoader.loadClass(ClassLoader.java:532)
E/AndroidRuntime(  550):        at android.app.ActivityThread.handleCreateService(ActivityThread.java:2940)
E/AndroidRuntime(  550):        ... 10 more
I/Process (  550): Sending signal. PID: 550 SIG: 9
I/ActivityManager(   59): Process org.eoti.test:main (pid 550) has died.

Ok... so it is able to load the classes... until a reboot (or force close)... and then it can't find them anymore?  If anyone has any thoughts on the matter, I'd be keen to hear them...

18 July 2010

Intent Filters

Let's start with a basic app:

F:\work> mvn archetype:generate -DarchetypeCatalog=http://kallisti.eoti.org:8081/content/repositories/snapshots/archetype-catalog.xml
2: http://kallisti.eoti.org:8081/content/repositories/snapshots/archetype-catalog.xml -> galatea-archetype (null)
Choose a number: : 2
groupId: org.eoti.android.tutorial.intent
artifactId: IntentTest
version: 1.0-SNAPSHOT
package: org.eoti.android.tutorial.intent

F:\work> cd IntentTest
F:\work\IntentTest> mvn clean install


Add this into your IntentTestActivity:
    public void customClickHandler1(View target)
    {
        startActivity(new  Intent(Intent.ACTION_VIEW, Uri.parse("custom1://localhost/param1/param2")));
    }
   
Add this into the end of your LinearLayout in main.xml:
    <Button
        android:text="Click Me #1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:onClick="customClickHandler1" />

Following this methodology, we can have custom methods rather than multiple if/else.


Create a new activity:
package org.eoti.android.tutorial.intent;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class SubActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sub);
        ((TextView)findViewById(R.id.text)).setText(getClass().getSimpleName() + " loaded: " + getIntent().getData());
    }
}



And create the res\layout\sub.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/text"
        />
</LinearLayout>


And add it to the AndroidManifest.xml:
        <activity android:name=".SubActivity">
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:scheme="custom1" android:host="localhost" android:pathPattern="/param1/.*" />
            </intent-filter>
        </activity>


Redeploy (mvn clean install)

Ok, that all works well... let's try having different path prefixes...

Add another button:
Update main.xml:
    <Button
        android:text="Click Me #2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:onClick="customClickHandler2" />

Update IntentTestActivity:
    public void customClickHandler2(View target)
    {
        startActivity(new  Intent(Intent.ACTION_VIEW, Uri.parse("custom1://localhost/paramA/paramB")));
    }

Create SubActivity2:
package org.eoti.android.tutorial.intent;

import android.os.Bundle;

public class SubActivity2 extends SubActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}

Update AndroidManifest.xml:
        <activity android:name=".SubActivity2">
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:scheme="custom1" android:host="localhost" android:pathPattern="/paramA/.*" />
            </intent-filter>
        </activity>

Redeploy (mvn clean install)... Now, we can launch either one by the first part of the URL...  what about something at the end?


Make a new activity:
package org.eoti.android.tutorial.intent;

import android.os.Bundle;

public class SubActivity3 extends SubActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}

        <activity android:name=".SubActivity3">
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:scheme="custom1" android:host="localhost" android:pathPattern="/paramA/.*/paramC" />
            </intent-filter>
        </activity>

    <Button
        android:text="Click Me #3"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:onClick="customClickHandler3" />

    public void customClickHandler3(View target)
    {
        startActivity(new  Intent(Intent.ACTION_VIEW, Uri.parse("custom1://localhost/paramA/paramB/paramC")));
    }

Redeploy (mvn clean install)... what happens?  #1 and #2 work; but #3 asks you how you want to handle it (the picker is making you choose between #2 and #3).  That's because the 3rd url matches both intent-filters.  How do we fix that?

We don't have access to the full regex library (almost none of it really), so the simplest way is to make it behave more like files and directories...

Let's make "/paramA/paramB" more like a directory by appending a slash (ie: "/paramA/paramB/")
    public void customClickHandler2(View target)
    {
        startActivity(new  Intent(Intent.ACTION_VIEW, Uri.parse("custom1://localhost/paramA/paramB/")));
    }

        <activity android:name=".SubActivity2">
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:scheme="custom1" android:host="localhost" android:pathPattern="/paramA/.*/" />
            </intent-filter>
        </activity>

Redeploy (mvn clean install). Now what happens? All three of them now launch.  We have a gotcha here though.  Try this:

    <Button
        android:text="Broken"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:onClick="customClickHandler4" />

    public void customClickHandler4(View target)
    {
        startActivity(new  Intent(Intent.ACTION_VIEW, Uri.parse("custom1://localhost/paramA/paramB")));
    }

Redeploy (mvn clean install) and you will see that clicking the "Broken" button will cause a stack trace:
E/AndroidRuntime( 1278): Caused by: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=custom1://localhost/paramA/paramB }
E/AndroidRuntime( 1278):        at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1408)
E/AndroidRuntime( 1278):        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1378)
E/AndroidRuntime( 1278):        at android.app.Activity.startActivityForResult(Activity.java:2817)
E/AndroidRuntime( 1278):        at android.app.Activity.startActivity(Activity.java:2923)
E/AndroidRuntime( 1278):        ... 15 more
W/ActivityManager(   61):   Force finishing activity org.eoti.android.tutorial.intent/.IntentTestActivity

This is because we now require a slash to be on the end (or 'paramC').

Let's try one more thing:

    <Button
        android:text="Wrong"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:onClick="customClickHandler5" />

    public void customClickHandler5(View target)
    {
        startActivity(new  Intent(Intent.ACTION_VIEW, Uri.parse("custom1://localhost/paramA/paramB/paramC/paramD/")));
    }

Redeploy (mvn clean install).  What happens?  Why doesn't it match "/paramA/.*/" from SubActivity2?  My only guess is that the "everything" in ".*" excludes the "/"?

So end result?  If you are willing to carefully layout your Uris and be limited to ".*" or literals (rather than say '[0-9]+') then this solution MIGHT be cleaner than creating an intent hub to process the strings and start your activities...  too bad we don't have access to true Java regex functionality.

07 July 2010

Error reporting via email

Let's start with a basic app:
C:\work> mvn archetype:generate -DarchetypeCatalog=http://kallisti.eoti.org:8081/content/repositories/snapshots/archetype-catalog.xml
2: http://kallisti.eoti.org:8081/content/repositories/snapshots/archetype-catalog.xml -> galatea-archetype (null)
Choose a number:  (1/2/3): 2
Confirm properties configuration:
groupId: org.eoti.android.errors
artifactId: ErrorTest
version: 1.0-SNAPSHOT
package: org.eoti.android.errors
C:\work> cd ErrorTest
C:\work\ErrorTest> mvn clean install

Insert this into the end of your onCreate method:
[* NOTE: Make sure to change to your email address if you want to see it actually work ]
        try{
            throw new IOException("This is an error");
        } catch (IOException e) {
            Log.e(TAG, "Standard Error Logging", e);

            // Derived from http://thinkandroid.wordpress.com/2010/01/25/debugging-applications-by-emailing-error-reports/
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
            emailIntent.setType("plain/text");
            emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"malachid@gmail.com"});
            emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "[" + getClass().getSimpleName() + "] ERROR REPORT");
            emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, sw.toString());
            startActivity(Intent.createChooser(emailIntent, "Send error report..."));
        }

Redeploy (mvn clean install).and run it.  You should soon have an email show the stack trace.

12 May 2010

Installing TTS voice data into Emulator

I have a couple different test environments... one of them was able to use voice out of the box... the other, however, could not.  Sure, maybe I screwed something up... end result though was that when attempting to install the voice data (via Settings | Text-to-Speech) it crashed due to there not being a Market application in my emulator...

So what to do?

If you go to the TTS download page, you can download the com.svox.langpack.installer_1.0.1.apk.  At that point, simply do 'adb install com.svox.langpack.installer_1.0.1.apk' and it will install!