Authorgoalstudio

How to quick create QR-code for your Android application

Sometimes you need QR-code to be posted somewhere to promote your Android application. You can use a lot of online tools to create such image, but from my point of view the fastest way is to use Google Chart API for this.
What do you need is to create URL-request to Google Chart API with correct parameters:

1. The main part is URL:

http://chart.apis.google.com/chart?cht=qr

where cht=qr is the first parameter saying that we need QR-code.

2. Then adding image size, for example 200×200 pixels:

http://chart.apis.google.com/chart?cht=qr&chs=200x200

3. At last you should add label to be encoded in QR-code, and you need to have direct link to Android Market with your application. To do this you need to create market:// scheme url:

market://details?id=com.your.packagename

where “com.your.packagename” is the main package name of your application. Now add it to the full charts url:

http://chart.apis.google.com/chart?cht=qr&chs=200x200&chl=market://details?id=com.yota.screentest

The result of it is the QR-code image that you can add as src to img html tag:

HTC Legend & Desire Grayscale Reproduction Issue

It was reported by Phandroid that all or some of HTC Legend and Desire Android smartphones have poor grayscale reproduction.

Now you can quick check your HTC device does it have this grayscale issue or not using small tool from Android Market – Screen Test.
Originally application was created to help in dead pixels finding. Current release has some extra useful screens to test your device and now includes grayscale gradient to be sure that your HTC Legend or Desire phone is fine.

You can download application from Android Market by searching “Screen Test” or just scan QR-code below.

ScreenTest QR Code

And don’t forget to comment on this or original Phandroid post to clarify is this is the issue for all HTC Legend phones or not.

Android 2.2 Froyo new APIs

Just a reference list of classes. Make sure you haven’t missed some of them like AndroidHttpClient or HeterogeneousExpandableList.

http://developer.android.com/sdk/api_diff/8/changes.html

Completely new packages:

New classes

android.app

Continue reading

Metal Android

It’s just great! Share passion to the Droids:)

source: http://vkontakte.ru/album-15955496_105624045

Google Android secret_code for testing

Found today a post

  1. Go to phone app
  2. Dial *#*#4636#*#*
  3. See secret test menu:)

*#*#4636#*#*

I’ve looked deep into platform code. Here’s are the code from Phone.git

    static boolean handleSecretCode(Context context, String input) {
        // Secret codes are in the form *#*#<code>#*#*
        int len = input.length();
        if (len > 8 && input.startsWith("*#*#") && input.endsWith("#*#*")) {
            Intent intent = new Intent(Intents.SECRET_CODE_ACTION,
                    Uri.parse("android_secret_code://" + input.substring(4, len - 4)));
            context.sendBroadcast(intent);
            return true;
        }

        return false;
    }

So, let’s search for Intent filters:

Settings.git

        <receiver android:name="TestingSettingsBroadcastReceiver">
            <intent-filter>
                 <action android:name="android.provider.Telephony.SECRET_CODE" />
                 <data android:scheme="android_secret_code" android:host="4636" />
            </intent-filter>
       </receiver>

CalendarProvider.git (this one works only on >2.0)

        <receiver android:name="TestingSettingsBroadcastReceiver">
            <intent-filter>
                 <action android:name="android.provider.Telephony.SECRET_CODE" />
                 <data android:scheme="android_secret_code" android:host="225" />
            </intent-filter>
       </receiver>

VoiceDialer.git

      <!--  Voice Dialer Logging Enabled, *#*#VDL1#*#* -->
      <intent-filter>
        <action android:name="android.provider.Telephony.SECRET_CODE" />
        <data android:scheme="android_secret_code" android:host="8351" />
      </intent-filter>

      <!--  Voice Dialer Logging Disabled, *#*#VDL0#*#* -->
      <intent-filter>
        <action android:name="android.provider.Telephony.SECRET_CODE" />
        <data android:scheme="android_secret_code" android:host="8350" />
      </intent-filter>

You can add your own codes!:)

//DL

Add Headset button support to your Android application

It’s relatively easy to add headset button support to your application. For example you want to play/pause media playback in your super media player.

But here are a few moments that you should take into consideration:

    1. You should register your broadcast receiver inside your application (not in manifest file). Otherwise Google Music player will catch your broadcast and aboard it. http://android.git.kernel.org/?p=platform/packages/apps/Music.git;a=blob;f=src/com/android/music/MediaButtonIntentReceiver.java
    2. Your IntentFilter priority should be higher that other media players priorities in your phone:) That’s kind of tricky thing.

      The code snippet will look like:

      MediaButtonIntentReceiver mMediaButtonReceiver = new MediaButtonIntentReceiver();
      IntentFilter mediaFilter = new IntentFilter(Intent.ACTION_MEDIA_BUTTON);
      mediaFilter.setPriority(MEDIA_BUTTON_INTENT_EMPIRICAL_PRIORITY_VALUE);
      registerReceiver(mMediaButtonReceiver, mediaFilter);
      

      And MediaButtonIntentReceiver.java

      public class MediaButtonIntentReceiver extends BroadcastReceiver {
      
          public MediaButtonIntentReceiver() {
              super();
          }
      
          @Override
          public void onReceive(Context context, Intent intent) {
              String intentAction = intent.getAction();
              if (!Intent.ACTION_MEDIA_BUTTON.equals(intentAction)) {
                  return;
              }
              KeyEvent event = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
              if (event == null) {
                  return;
              }
              int action = event.getAction();
              if (action == KeyEvent.ACTION_DOWN) {
      	    // do something
              }
              abortBroadcast();
          }
      }
      
      1. Don’t forget to unregister your broadcast receiver
      2. Add “android.permission.BLUETOOTH” permission if you want to support bluetooth headset

      // DL

      Quick way to extract AMR-audio from Android 3GP files

      If you need to record audio from microphone of your Android-device to a file, it is better to use MediaRecorder;. On the current Android platforms (we can be sure for 1.6, 1.5 and earlier versions) you can record only to 3GPP AMR-NB file, but not to the raw AMR. If you will try to use MediaRecorder.OutputFormat.RAW_AMR you will get native error that will not come to Java layer. We’re pretty sure that it will be fixed in the future, but what to do now if you need simple raw AMR-NB file without extra 3GP-container?

      Simple Google search about how to extract raw AMR audio from 3GPP-file recorded by your Android return us a link to the isobox4j library that can convert between all kinds of 3gp, amr, mp4, etc. files. It is perfect, but it is 400Kb. Do you really need to have such huge library in your project only for converting one type of file to another?

      I will show you the easier way that works fine only with Android 3GP-files. What you need to do – just remove 3GP-container and store AMR-data with appropriate header.

      3GP-header fields are stored in 32-bits, big-endian format. So, you need correct functions to read 32-bits values from ByteArrayInputStream.

      public long readUint32(ByteArrayInputStream bis) {
          long result = 0;
          result += ((long) readUInt16(bis)) << 16;
          result += readUInt16(bis);
          return result;
      }
      public int readUInt16(ByteArrayInputStream bis) {
          int result = 0;
          result += bis.read() << 8;
          result += bis.read();
          return result;
      }

      Now you need to skip 3gp-headers. First header is file header (‘ftyp’) and next is MediaData (‘mdat’). I’ve made it according to 3GP and Iso file structure specifications, using classes. Base Box contains two fields: size and type.

      class Box {
          protected long size;
          protected long type;
       
          protected long boxSize = 0;
       
          public Box(ByteArrayInputStream bis) {
              size = readUint32(bis);
              boxSize += 4;
              type = readUint32(bis);
              boxSize += 4;
          }
      }

      Now classes for Filetype header and MediaData header:

      class FileTypeBox extends Box {
          private static char[] HEADER_TYPE = {'f', 't', 'y', 'p'};
       
          protected long brand;
          protected long minorVersion;
          protected long[] compatibleBrands;
       
          public FileTypeBox(ByteArrayInputStream bis) {
              super(bis);
              brand = readUint32(bis);
              boxSize += 4;
              minorVersion = readUint32(bis);
              boxSize += 4;
              int remainSize = (int)(size - boxSize);
              if (remainSize > 0) {
                  compatibleBrands = new long[remainSize / 4];
                  for (int i = 0; i < compatibleBrands.length; i++) {
                      compatibleBrands[i] = readUint32(bis);
                  }
              }
          }
      }
      class MediaDataBox extends Box {
          private static char[] HEADER_TYPE = {'m', 'd', 'a', 't'};
       
          protected byte[] data;
       
          public MediaDataBox(ByteArrayInputStream bis) {
              super(bis);
              // you can read data[] here, but we need only size
          }
       
          public int getDataLength() {
              return (int)(size - boxSize);
          }
      }

      I add HEADER_TYPE to each Box-class. You can add checking that class field type has the appropriate HEADER_TYPE value just to be sure that you read and parse correct file.
      So, we’re ready to convert 3GP to AMR. 3GP-structure is as follows:
      1. FileType header
      2. MediaDataHeader. Data inside it is raw AMR data.
      3. MovieData box (‘moov’ type) that presents, but is empty and we don’t need to copy it to destination AMR-file.
      Converting steps is as follows:
      1. Skip FileType header
      2. Skip MediaData Header size and type fields, get raw AMR data only.
      3. Create new file
      4. Add AMR-header magic number – “#!AMR\n” (according to RFC-3267)
      5. Copy all raw AMR data to file.
      That’s it!

      // #!AMR\n
      private static byte[] AMR_MAGIC_HEADER = {0x23, 0x21, 0x41, 0x4d, 0x52, 0x0a};
       
      public byte[] convert3gpDataToAmr(byte[] data) {
          if (data == null) {
              return null;
          }
       
          ByteArrayInputStream bis = new ByteArrayInputStream(data);
          // read FileTypeHeader
          FileTypeBox ftypHeader = new FileTypeBox(bis);
          // You can check if it is correct here
          // read MediaDataHeader
          MediaDataBox mdatHeader = new MediaDataBox(bis);
          // You can check if it is correct here
          int rawAmrDataLength = mdatHeader.getDataLength();
          int fullAmrDataLength = AMR_MAGIC_HEADER.length + rawAmrDataLength;
          byte[] amrData = new byte[fullAmrDataLength];
          System.arraycopy(AMR_MAGIC_HEADER, 0, amrData, 0, AMR_MAGIC_HEADER.length);
          bis.read(amrData, AMR_MAGIC_HEADER.length, rawAmrDataLength);
          return amrData;
      }

      Enjoy!

      © 2017 Android Tales

      Theme by Anders NorenUp ↑