Friday, October 31, 2014

Generate and Play a tone in Android

Generate and Play a tone in Android

Here is the code to generate and play the tone with frequency base in Android.

This will be playing for 3 second whenever you change the frequency rate by using seekbar it will be start play for 3 second.

PlaySound Activity


import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Bundle;
import android.os.Handler;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

public class PlaySound extends Activity{

    private final int duration = 3; // seconds
    private final int sampleRate = 8000;
    private final int numSamples = duration * sampleRate;
    private final double sample[] = new double[numSamples];
    private double freqOfTone = 500; // hz

    private final byte generatedSnd[] = new byte[2 * numSamples];

    Handler handler = new Handler();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        genTone();
        
        final TextView tv = (TextView)findViewById(R.id.textview);
        tv.setText(""+freqOfTone);
        SeekBar seekbar = (SeekBar)findViewById(R.id.seekbar);
        seekbar.setProgress((int)freqOfTone);
        seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
   @Override
   public void onStopTrackingTouch(SeekBar seekBar) {
    freqOfTone = seekBar.getProgress();
    tv.setText(""+freqOfTone);
    genTone();
    handler.post(new Runnable() {

                    public void run() {
                        playSound();
                    }
                });
   }
   
   @Override
   public void onStartTrackingTouch(SeekBar seekBar) {
    
   }
   
   @Override
   public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
    // TODO Auto-generated method stub
    
   }
  });
        
        
    }

    @Override
    protected void onResume() {
        super.onResume();

        // Use a new tread as this can take a while
        final Thread thread = new Thread(new Runnable() {
            public void run() {
                
                handler.post(new Runnable() {

                    public void run() {
                        playSound();
                    }
                });
            }
        });
        thread.start();
    }

    void genTone(){
        // fill out the array
        for (int i = 0; i < numSamples; ++i) {
            sample[i] = Math.sin(2 * Math.PI * i / (sampleRate/freqOfTone));
        }

        // convert to 16 bit pcm sound array
        // assumes the sample buffer is normalised.
        int idx = 0;
        for (final double dVal : sample) {
            // scale to maximum amplitude
            final short val = (short) ((dVal * 32767));
            // in 16 bit wav PCM, first byte is the low order byte
            generatedSnd[idx++] = (byte) (val & 0x00ff);
            generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);

        }
    }

    AudioTrack audioTrack;
    void playSound(){
     if(audioTrack!=null){
      audioTrack.stop();
      audioTrack.release();
      audioTrack = null;
     }
     audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                sampleRate, AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length,
                AudioTrack.MODE_STATIC);
        
        
        audioTrack.write(generatedSnd, 0, generatedSnd.length);
        audioTrack.play();
    }
}

Layout file which have TextView which display current frequency value and Seekbar to change the frequency.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <SeekBar
        android:layout_margin="10dp"
        android:id="@+id/seekbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="3000" />

    
    <TextView
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp"
        android:id="@+id/textview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

Happy to help you, Happy to code

Wednesday, October 15, 2014

Clock widget for home screen


Create clock for home screen widget

Create new project without activity.

Create "xml" folder under "res" folder.

Create new xml file like widget_xml.xml under xml folder

Copy/paste below code in widget_xml.xml

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/widget_layout"
    android:minHeight="300dp"
    android:minWidth="175dp"
    android:updatePeriodMillis="1000" >

</appwidget-provider>

Now define receiver in you AndroidManifest.xml file, copy/past below code

<receiver android:name=".MyWidgetProvider" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widget_xml" />
</receiver>

Create layout file for widget say widget_layout.xml in you res/layout this is for our widget layout which will be used to display current time.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="8dip" >

    <TextView
        android:background="#ffffff"
        android:textColor="#000000"
        android:id="@+id/update"
        style="@android:style/TextAppearance.Medium"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="4dip"
        android:gravity="center_horizontal|center_vertical"
        android:padding="10dp"
        android:text="Static Text"
        android:textSize="20sp" >
    </TextView>

</LinearLayout>

Now create one class under your package having name MyWidgetProvider and copy/paste below code, extending the AppWidgetProvider which will create for widget we need to implementing onEnabled(), onDeleted(), onDisabled() method to managing our service for start and stop. While onUpdate() method will be used as for update the widget with new time on first time, this will be update on first time only.

public class MyWidgetProvider extends AppWidgetProvider {

 public void onEnabled(Context context) {
  super.onEnabled(context);
  context.startService(new Intent(context, UpdateWidgetService.class));
 }

 public void onDeleted(Context context, int[] appWidgetIds) {
  super.onDeleted(context, appWidgetIds);
  context.stopService(new Intent(context, UpdateWidgetService.class));
 }

 @Override
 public void onDisabled(Context context) {
  super.onDisabled(context);
  context.stopService(new Intent(context, UpdateWidgetService.class));
 }

 @Override
 public void onUpdate(Context context, AppWidgetManager appWidgetManager,
   int[] appWidgetIds) {

  RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
    R.layout.widget_layout);
  remoteViews.setTextViewText(R.id.update,
    Utility.getCurrentTime("hh:mm:ss a"));
  ComponentName thiswidget = new ComponentName(context,
    MyWidgetProvider.class);
  AppWidgetManager manager = AppWidgetManager.getInstance(context);
  manager.updateAppWidget(thiswidget, remoteViews);
 }
}

Now create UpdateWidgetService which updating the widget value every 1 second. This service we need to create for updating the widget value. As onUpdate() will be called once so we need to update widget content value every second so for that we create this service and start new runnable with handle which will be calling recursively itself every 1 second to update the widget value.

public class UpdateWidgetService extends Service {
 private static final String LOG = UpdateWidgetService.class.getSimpleName();
 private Context context;
 
 private Handler handler = new Handler();
 private Runnable runn = new Runnable() {
  @Override
  public void run() {
   Log.i(LOG, "Called");
   //You can do the processing here update the widget/remote views.
     RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
       R.layout.widget_layout);
     remoteViews.setTextViewText(R.id.update, Utility.getCurrentTime("hh:mm:ss a"));
     ComponentName thiswidget = new ComponentName(context, MyWidgetProvider.class);
     AppWidgetManager manager = AppWidgetManager.getInstance(context);
     manager.updateAppWidget(thiswidget, remoteViews);
     handler.postDelayed(runn, 1000);
  }
 };
 @Override
 public void onDestroy() {
  super.onDestroy();
  if(handler!=null){
   handler.removeCallbacks(runn);
  }
  handler = null;
 }
 @Override
 public int onStartCommand(Intent intent, int flags, int startId) {
  context = this;
  handler.post(runn);
  return super.onStartCommand(intent, flags, startId);
 }

 @Override
 public IBinder onBind(Intent intent) {
  return null;
 }
}

Now register this service class into your AndroidManifest.xml file

<service android:name=".UpdateWidgetService"/> 

Create java class for utility say Utility.java and copy/paste below code.

public class Utility {
 public static String getCurrentTime(String timeformat) {
  Format formatter = new SimpleDateFormat(timeformat);
  return formatter.format(Calendar.getInstance().getTime());
 }
} 

Now run this app, we don't have any activity so it will just install in your device. Long press on your home screen and select Widget option from them.

Search clock widget as it containing your application icon and hold and drag and drop on the home screen. It will be starting time as your current device time. On every 1 sec of delay from service it will be refresh the time.

Happy to coding and happy to help you

Saturday, October 4, 2014

Timer counter Logic



Timer counter logic

private TextView tvTimeCounter;
int hour, min, sec; // this all initiating with 0 by default;

Handler counterHandler = new Handler(); // Use handler for Runnable

// Counter Runnable which will called itself after 1 sec (Recursively)
Runnable counterRunnable = new Runnable(){
    @Override
        public void run() {
            if (sec == 59) {
                if (min == 59) {
                    hour++;
                    min = 0;
                } else {
                    min++;
                }
                sec = 0;
            } else {
                sec++;
            }

            updateTimer();
            counterHandler.postDelayed(this, 1000);
        }

}


// This method will be called every 1 sec and update your TextView with new time
public void updateTimer() {
        runOnUiThread(new Runnable() {
            public void run() {
                tvTimeCounter.setText(String.format("%02d:%02d:%02d", hour,
                        min, sec));

            }
        });
 


public void onCreate(Bundle bundle){
      super.onCreate(bundle);
      tvTimeCounter = new TextView();
      setContentView(tvTimeCounter);
}

public void onResume(){
     super.onResume();
     counterHandler.postDelay(counterRunnable); // on activity resume it will counter your counter
}

public void onPause(){
     super.onPause();
     counterHandler.removeCallback(counterRunnable); // on activity pause stop counter by removing handler
}



Just copy the above code and you have getting your Timer counter in Android

Happy to help you

Thursday, October 2, 2014

Customizing Progressbar in Android


Customizing Progressbar in Android

In default style you change the Progressbar from circular to horizontal. Now in that also you can change the color whatever you like it.

Here is the below code will change the color circular Progressbar. Its looks like this





circular_progress_drawable.xml

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="360" >

    <shape
        android:innerRadiusRatio="3"
        android:shape="ring"
        android:thicknessRatio="8"
        android:useLevel="false" >
        <size
            android:height="76dip"
            android:width="76dip" />

        <gradient
            android:angle="0"
            android:endColor="#
00FF00"
            android:startColor="@android:color/transparent"
            android:type="sweep"
            android:useLevel="false" />
    </shape>

</rotate>

Use this file in your Progressbar  like this way.

<ProgressBar
            android:id="@+id/progress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:indeterminate="true"
            android:indeterminateDrawable="@drawable/progress_drawable" />

Two main things you need to use i.e. android:indeterminate="true" to allow indeterminate and change the indeterminate drawable android:indeterminateDrawable="@drawable/progress_drawable" with our drawable.

Now for Horizontal progressbar






progress_horizontal_drawable.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="5dip" />

            <gradient
                android:angle="270"
                android:centerColor="#ff5a5d5a"
                android:centerY="0.75"
                android:endColor="#ff747674"
                android:startColor="#ff9d9e9d" />
        </shape>
    </item>
    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <corners android:radius="5dip" />

                <gradient
                    android:angle="270"
                    android:centerColor="#80ffb600"
                    android:centerY="0.75"
                    android:endColor="#a0ffcb00"
                    android:startColor="#80ffd300" />
            </shape>
        </clip>
    </item>
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners android:radius="5dip" />

                <gradient
                    android:angle="270"
                    android:endColor="#008000"
                    android:startColor="#33FF33" />
            </shape>
        </clip>
    </item>

</layer-list>

Use this file in Progressbar

<ProgressBar
            style="?android:attr/progressBarStyleHorizontal"
            android:id="@+id/progress"
            android:progress="50"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:indeterminate="false"
            android:progressDrawable="@drawable/progress_drawable" />