Best android questions in March 2012

Can We Install an APK From a ContentProvider?

20 votes

I am working on a library to allow apps to self-update, for those that are being distributed outside of the Android Market.

My original plan was to include code that would download the APK file to internal storage, and then install it from there via a ContentProvider and a content:// Uri. However, when I tried that, the installer system dumped a "Skipping dir: " warning to LogCat and failed to actually install it. Once I switched to downloading the APK to external storage and using a file:// Uri with the ACTION_VIEW installer Intent, it worked.

The "Skipping dir:" message seems to be logged by parsePackage() in PackageParser, which seems to assume that it is working with a File. That would suggest that we cannot use content:// Uri values.

Has anyone successfully used ACTION_VIEW on a application/vnd.android.package-archive Intent with a content:// Uri? If so, was there some specific trick in setting up the ContentProvider that made it work?

Thanks!

I would assume this is not possible, as the Java API doesn't seem to allow it. ContentProvider's openFile() returns a ParcelFileDescriptor, from which you can obtain a java.io.FileDescriptor. You can then use this FileDescriptor to open either a FileInputStream or a FileOutputStream. Unfortunately, you can't use it to open a RandomAccessFile (despite the fact that RandomAccessFile works on descriptors just the same as the others, the constructor you'd need is just missing from the API).

As APK files are ZIP files, which must be read out of order (you have to seek to the end to find the file directory), I assume the implementation of installation will require a RandomAccessFile, so it would not have been possible to support the case you're trying to implement.

Gson NoClassDefFoundError after ADT and SDK Tools update to v17

17 votes

Today I updated my ADT and SDK Tools to v17 and my projects using Google's gson jar library started to throw NoClassDefFoundError. Here's the logcat output:

03-22 12:30:58.941: E/AndroidRuntime(21672): FATAL EXCEPTION: main 03-22 12:30:58.941: E/AndroidRuntime(21672): java.lang.NoClassDefFoundError: com.google.gson.Gson 03-22 12:30:58.941: E/AndroidRuntime(21672): at com.matriksdata.conn.XRequestHandler.connect(XRequestHandler.java:35) 03-22 12:30:58.941: E/AndroidRuntime(21672): at com.matriksdata.conn.XRequestHandler.makeRequest(XRequestHandler.java: 29) 03-22 12:30:58.941: E/AndroidRuntime(21672): at com.matriksdata.bavul.XBaseWithConnectionActivity.makeRequest(XBaseWithConnectionActivity.java: 46) 03-22 12:30:58.941: E/AndroidRuntime(21672): at com.matriksdata.ui.login.SplashScreenActivity.onCreate(SplashScreenActivity.java: 36) 03-22 12:30:58.941: E/AndroidRuntime(21672): at android.app.Activity.performCreate(Activity.java:4465) 03-22 12:30:58.941: E/AndroidRuntime(21672): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java: 1049) 03-22 12:30:58.941: E/AndroidRuntime(21672): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java: 1919) 03-22 12:30:58.941: E/AndroidRuntime(21672): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java: 1980) 03-22 12:30:58.941: E/AndroidRuntime(21672): at android.app.ActivityThread.access$600(ActivityThread.java:122) 03-22 12:30:58.941: E/AndroidRuntime(21672): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1146) 03-22 12:30:58.941: E/AndroidRuntime(21672): at android.os.Handler.dispatchMessage(Handler.java:99) 03-22 12:30:58.941: E/AndroidRuntime(21672): at android.os.Looper.loop(Looper.java:137) 03-22 12:30:58.941: E/AndroidRuntime(21672): at android.app.ActivityThread.main(ActivityThread.java:4340) 03-22 12:30:58.941: E/AndroidRuntime(21672): at java.lang.reflect.Method.invokeNative(Native Method) 03-22 12:30:58.941: E/AndroidRuntime(21672): at java.lang.reflect.Method.invoke(Method.java:511) 03-22 12:30:58.941: E/AndroidRuntime(21672): at com.android.internal.os.ZygoteInit $MethodAndArgsCaller.run(ZygoteInit.java:784) 03-22 12:30:58.941: E/AndroidRuntime(21672): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 03-22 12:30:58.941: E/AndroidRuntime(21672): at dalvik.system.NativeStart.main(Native Method)

any ideas?

I faced a similar problem today.

This fixed it for me:

  • Remove all Android Library projects and external jars from the build path.
  • Create a folder named 'libs' in your project.
  • Place all external .jars in that folder, the ADT should now place them under 'Android Dependencies'.
  • Re-import all your previous Android Library projects the normal way.

The issue is that external jars are not placed in the 'libs' folder by default when using Properties - Java Build Path- Add External Jar, instead they are placed under 'Referenced Libraries' instead of 'Android Dependencies' and this causes the NoClassDefFoundError.

Please, check Dealing with dependencies in Android projects for more details.

Is it possible to program Android to act as physical USB keyboard?

16 votes

What I really want to know is whether it is a hardware problem, or a software problem. Could I plug my android phone into a computer via USB and have it act as a hardware keyboard. I do not want to install anything on the computer, I want android to behave like the standard hardware.


Edit: Clarification I want to write a program/library for android that enables the device to fully emulate an ordinary keyboard, so that the operating system reports it as a standard keyboard device, and it would work in the BIOS or anywhere else that a keyboard works.

In my opinion this is barely possible.

Your Computer identifies any USB device with the USB device descriptor or the usb interface descriptor. To be able to use your android device as a keyboard, you would have to change these. Actually i think these are saved on a ROM in the device, so you would have to change hardware. The device needs to identifiy itself with the host even if its only charging in turned off state (has to tell usb host about the power consumption, otherwise only a few mA max). For me this points into the direction, that you would have to change hardware

"Easiest" way would proabably be assemble an adapter containing a usb host chip with a µC that converts the received data (which you still had to send via usb) to ps/2 or usb-client signals that u send to the computer.

In my opinion the easiest way would be: Buy one of these Keyboards you can roll and put them in your bag too.

How can I get the same undefined ProgressBar as ICS with 2 rotating circles?

15 votes

I am currently writing an open source project that aims to port the famous Holo theme to previous versions of Android (since 1,6!!!)

Everything works fine and I am really proud of my work, but the problem I am facing now is to get the ProgressBar totally looking like the ICS one.

I used the same xml code than Android source: (progress_medium_holo.xml)

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <rotate
             android:drawable="@drawable/spinner_48_outer_holo"
             android:pivotX="50%"
             android:pivotY="50%"
             android:fromDegrees="0"
             android:toDegrees="1080" />
    </item>
    <item>
        <rotate
             android:drawable="@drawable/spinner_48_inner_holo"
             android:pivotX="50%"
             android:pivotY="50%"
             android:fromDegrees="720"
             android:toDegrees="0" />
    </item>
</layer-list>

With same png:

spinner_76_outer_holo.png and spinner_76_inner_holo.png

enter image description here white pic => enter image description here

But unfortunately, I only get one circle...

If you don't understand what I mean, you can try this app on a pre-ICS device:

https://play.google.com/store/apps/details?id=com.WazaBe.HoloDemo

FULL SOURCE IS HERE: https://github.com/ChristopheVersieux/HoloEverywhere

Thank a lot for your help

enter image description here

Just found the answer here!

http://stackoverflow.com/a/8697806/327402

Very usefull post!

There is indeed a platform limitation, although it's not what you might think. The issue is that pre-API11, RotateDrawable had some crude code in it to require that the animation rotate clockwise by checking if toDegrees was greater than fromDegrees; if not, the two were forced equal to each other. If you modified your example to have the second item move in a forward direction (from 0 to 720, or even -720 to 0), both images would animate fine on all platforms; though I realize that defeats the purpose of what you're aiming for.

Take a look at the cached version Google Codesearch has of RotateDrawable.inflate(), which is the 2.3 version of the method used to turn the XML into the object, and you'll see what I mean.

RotateDrawable.java ...the offending code is around line 235...

    float fromDegrees = a.getFloat(
            com.android.internal.R.styleable.RotateDrawable_fromDegrees, 0.0f);
    float toDegrees = a.getFloat(
            com.android.internal.R.styleable.RotateDrawable_toDegrees, 360.0f);

    toDegrees = Math.max(fromDegrees, toDegrees); //<--There's the culprit

This takes an XML block like the second item that you have there, and turns it into a RotateDrawable that ends up with the same value for fromDegrees and toDegrees (in your case, 720), causing the image to simply stand still. You can visible test this by setting the start value to some value not a multiple of 360 (like 765). You'll see that the image still does not animate, but is rotated to the initial coordinate.

This awkward check was removed in the Honeycomb/ICS sources, which is why you can do backwards rotation on those platforms. Also, it doesn't look like there is a way to set these values from Java code, so a custom RotateDrawableCompat may be in your future :)

HTH

Android vibration intensity and damage

14 votes

I realize this is not strictly a code question, but I guess it belongs here anyway. If not, my apologies in advance.

Being as there's no inbuilt way to change the vibration intensity for the droid in code I'm using a kind of PWM control (switching the vibrator on and off at high frequency gives me a kind of control over vibration intensity). Right now I'm using a 20ms period (for example, with a 50% duty cycle the vibrator is on for 10ms and off for 10ms and it kind of feels like half power).

My question is, can some damage occurr to the vibrator motor using this kind of control?

Thanks!

I'm no engineer, but we're in luck because there is one sitting next to me. Apparently there's a kind of life cycle to things that relates in some ways to altering the state and in some other ways to duration of use so yes doing what you're talking about will stress the device in one way by trying to get something to go from 0% to 100% and back again very rapidly, but relieve some stress by only having it on half the time. Overall, what you're talking about doing shouldn't do any harm that would shorten the Android's life span as long as this pattern isn't intended to run for very long. I would definitely suggest getting in touch with someone who knows the mechanical part of the device more intimately because every device is different and general knowledge doesn't always translate into spot-on specific knowledge.

Android : How to get and set(Change) ID3 tag(metadata) of audio files?

12 votes

I am working to change ID3 tag, metadata of audio files of particular.

Like:

Artist Title Album etc.

And the core point,. that edited ID3 tags should be shown only into my app.

Looking for a valuable suggestion.

Thanks.

I think this is what you are looking for MyID3 library to set and get tags for media file.

Download this jar file MyID3_for_android and add it to your project's build path. here is the sample code. here pathdata is the file path of the audio file.

 File src = new File(pathdata);
            MusicMetadataSet src_set = null;
            try {
                src_set = new MyID3().read(src);
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } // read metadata

            if (src_set == null) // perhaps no metadata
            {
                Log.i("NULL", "NULL");
            }
            else
            {
            try{
            IMusicMetadata metadata = src_set.getSimplified();
            String artist = metadata.getArtist();  
            String album = metadata.getAlbum();  
            String song_title = metadata.getSongTitle(); 
            Number track_number = metadata.getTrackNumber(); 
            Log.i("artist", artist);
            Log.i("album", album);
            }catch (Exception e) {
                e.printStackTrace();
            }
            File dst = new File(pathdata);
            MusicMetadata meta = new MusicMetadata("name");
            meta.setAlbum("Chirag");
            meta.setArtist("CS");
            try {
                new MyID3().write(src, dst, src_set, meta);
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ID3WriteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }  // write updated metadata

Happy Coding :)

error installing java on ubuntu 10 64bit

9 votes

EDIT

I added this note to explain why I keep this question here. I added "Android" as keyword and I'd like to know whether someone else has tried to download the code and how it is possible to work around this problem. I fear that if I ask Ubuntu they would suggest me to use OpenJDK but the question is: did someone use that SDK to build Android code?

ORIGINAL

Sometime ago I downloaded the android source code on Ubuntu 10 64bit. I had problems but at the end I managed to get everything working. Now I'm trying to do it again on a fresh install of the same Ubuntu version but I'm having a problem.

Although I followed the instruction here I keep having the error:

Package sun-java6-jdk is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source E: Package sun-java6-jdk has no installation candidate

Googling gives you a lot of results that all give you the same solution:

sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"   
sudo apt-get update
sudo apt-get install sun-java6-jdk

I did it but it didn't work.

I'm running Ubuntu on a VM under VMWare.

I have also tried to add another source:

sudo add-apt-repository "deb-src http://archive.canonical.com/ubuntu lucid partner

but it didn't help

Maybe the answer is here:

Answer in SuperUser

but it is weird that on the Android portal there isn't any mention of it

Ubuntu 10.04 Lucid Lynx has Java 6 packages available, but you should activate partner packages first of all to download it from repositories. To do it, edit file /etc/apt/sources.list with command:

gksudo gedit /etc/apt/sources.list

and uncomment these lines:

deb http://archive.canonical.com/ubuntu lucid partner
deb-src http://archive.canonical.com/ubuntu lucid partner

then you can update repositories and install Java 6 packages with:

sudo apt-get update
sudo apt-get install sun-java6-jdk

You don't need to add third-party repositories.

VerifyError in android test-project build tools v17

9 votes

Since installing v17 of the android build tools I am getting a VerifyError in my test project.

A short description of my project structure:

All jar files exist in my main projects libs folder

The test-project is a project that resides inside my main project

All Instrumentation tests exist in the same package as my activities.

I have one jar that is only needed for the test projects in my libs folder in the test project

Has anyone seen this? Its happening on all my projects since updating. Running the test produces an InstrumentationException: java.lang.VerifyError

x...@android.com made a temporary fix for an issue I reported: http://code.google.com/p/android/issues/detail?id=27608.

You can try to see if the new anttasks.jar file can fix your problem.

It fixed mine. NoClassDefFoundError when running Instrumentation test with ant

Unable to parse response error while uploading screenshots on google play (Android Market)

7 votes

I just signed up with Market and uploaded my app. On the next screen, it is asking me to upload assets. After i choose screen shots for the app and hit upload, it gives me an error saying "Unable to parse response. If you have a browser extension or add-on installedwhich changes the JSON response, please disable and refresh this page."

I tried using Firefox, Chrome and IE but i am getting the same error.

On the Home page, it says

"Your Registration to Google Play is still being processed.
You can upload applications to Google Play but you cannot publish until your registration is completed.".

I guess this error has something to do with my registration as it is still in the pending stage. I dont know what do they want me to do in order to complete the registration.

If someone has faced this problem and was able to fix it, your help will be highly appreciated.

Apparently the error is gone today. I sent them couple of emails and they replied back saying they have approved my registration. I guess its not them but it got fixed as the payment cleared from the credit card. If you have this issue, send them an email or wait till the charge is cleared off in the credit card.