RSS

Category Archives: Uncategorized

Create a Location based Prayer Times Android application


Today we’ll create an Android application that can calculate Prayer Times for muslims. If you integrate location API with this application to retrieve user location then, it can be used anywhere in the world. The application takes care of the timezone automatically.

Create a cool UI for the application and feel free to use my source code and don’t forget to give me the feedback regarding accuracy.

MainActivity.java

package com.smartapps.prayertimes;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
	private TextView txtPrayerTimes;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		txtPrayerTimes = (TextView) findViewById(R.id.txtPrayerTimes);
	}

        // onClick method for the button
	public void getTime(View v) {
		// Retrive lat, lng using location API
		double latitude = 23.7;
		double longitude = 90.3833;
		double timezone = (Calendar.getInstance().getTimeZone()
				.getOffset(Calendar.getInstance().getTimeInMillis()))
				/ (1000 * 60 * 60);
		PrayTime prayers = new PrayTime();

		prayers.setTimeFormat(prayers.Time12);
		prayers.setCalcMethod(prayers.Makkah);
		prayers.setAsrJuristic(prayers.Shafii);
		prayers.setAdjustHighLats(prayers.AngleBased);
		int[] offsets = { 0, 0, 0, 0, 0, 0, 0 }; // {Fajr,Sunrise,Dhuhr,Asr,Sunset,Maghrib,Isha}
		prayers.tune(offsets);

		Date now = new Date();
		Calendar cal = Calendar.getInstance();
		cal.setTime(now);

		ArrayList prayerTimes = prayers.getPrayerTimes(cal, latitude,
				longitude, timezone);
		ArrayList prayerNames = prayers.getTimeNames();

		for (int i = 0; i < prayerTimes.size(); i++) {
			txtPrayerTimes.append("\n" + prayerNames.get(i) + " - "
					+ prayerTimes.get(i));
		}
	}
}

activity_main.xml: Keep a TextView with id: txtPrayerTimes and a Button with onClick= “getTime”

PrayTime.java courtesy: PrayTimes.org


package com.smartapps.qiblafinder;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.TimeZone;

public class PrayTime {

// ---------------------- Global Variables --------------------
 private int calcMethod; // caculation method
 private int asrJuristic; // Juristic method for Asr
 private int dhuhrMinutes; // minutes after mid-day for Dhuhr
 private int adjustHighLats; // adjusting method for higher latitudes
 private int timeFormat; // time format
 private double lat; // latitude
 private double lng; // longitude
 private double timeZone; // time-zone
 private double JDate; // Julian date
 // ------------------------------------------------------------
 // Calculation Methods
 public int Jafari; // Ithna Ashari
 public int Karachi; // University of Islamic Sciences, Karachi
 public int ISNA; // Islamic Society of North America (ISNA)
 public int MWL; // Muslim World League (MWL)
 public int Makkah; // Umm al-Qura, Makkah
 public int Egypt; // Egyptian General Authority of Survey
 public int Custom; // Custom Setting
 public int Tehran; // Institute of Geophysics, University of Tehran
 // Juristic Methods
 public int Shafii; // Shafii (standard)
 public int Hanafi; // Hanafi
 // Adjusting Methods for Higher Latitudes
 public int None; // No adjustment
 public int MidNight; // middle of night
 public int OneSeventh; // 1/7th of night
 public int AngleBased; // angle/60th of night
 // Time Formats
 public int Time24; // 24-hour format
 public int Time12; // 12-hour format
 public int Time12NS; // 12-hour format with no suffix
 public int Floating; // floating point number
 // Time Names
 private ArrayList<String> timeNames;
 private String InvalidTime; // The string used for invalid times
 // --------------------- Technical Settings --------------------
 private int numIterations; // number of iterations needed to compute times
 // ------------------- Calc Method Parameters --------------------
 private HashMap<Integer, double[]> methodParams;

 private double[] prayerTimesCurrent;
 private int[] offsets;

public PrayTime() {
 // Initialize vars

this.setCalcMethod(0);
 this.setAsrJuristic(0);
 this.setDhuhrMinutes(0);
 this.setAdjustHighLats(1);
 this.setTimeFormat(0);

// Calculation Methods
 this.setJafari(0); // Ithna Ashari
 this.setKarachi(1); // University of Islamic Sciences, Karachi
 this.setISNA(2); // Islamic Society of North America (ISNA)
 this.setMWL(3); // Muslim World League (MWL)
 this.setMakkah(4); // Umm al-Qura, Makkah
 this.setEgypt(5); // Egyptian General Authority of Survey
 this.setTehran(6); // Institute of Geophysics, University of Tehran
 this.setCustom(7); // Custom Setting

// Juristic Methods
 this.setShafii(0); // Shafii (standard)
 this.setHanafi(1); // Hanafi

// Adjusting Methods for Higher Latitudes
 this.setNone(0); // No adjustment
 this.setMidNight(1); // middle of night
 this.setOneSeventh(2); // 1/7th of night
 this.setAngleBased(3); // angle/60th of night

// Time Formats
 this.setTime24(0); // 24-hour format
 this.setTime12(1); // 12-hour format
 this.setTime12NS(2); // 12-hour format with no suffix
 this.setFloating(3); // floating point number

// Time Names
 timeNames = new ArrayList<String>();
 timeNames.add("Fajr");
 timeNames.add("Sunrise");
 timeNames.add("Dhuhr");
 timeNames.add("Asr");
 timeNames.add("Sunset");
 timeNames.add("Maghrib");
 timeNames.add("Isha");

InvalidTime = "-----"; // The string used for invalid times

// --------------------- Technical Settings --------------------

this.setNumIterations(1); // number of iterations needed to compute
 // times

// ------------------- Calc Method Parameters --------------------

// Tuning offsets {fajr, sunrise, dhuhr, asr, sunset, maghrib, isha}
 offsets = new int[7];
 offsets[0] = 0;
 offsets[1] = 0;
 offsets[2] = 0;
 offsets[3] = 0;
 offsets[4] = 0;
 offsets[5] = 0;
 offsets[6] = 0;


 methodParams = new HashMap<Integer, double[]>();

// Jafari
 double[] Jvalues = { 16, 0, 4, 0, 14 };
 methodParams.put(Integer.valueOf(this.getJafari()), Jvalues);

// Karachi
 double[] Kvalues = { 18, 1, 0, 0, 18 };
 methodParams.put(Integer.valueOf(this.getKarachi()), Kvalues);

// ISNA
 double[] Ivalues = { 15, 1, 0, 0, 15 };
 methodParams.put(Integer.valueOf(this.getISNA()), Ivalues);

// MWL
 double[] MWvalues = { 18, 1, 0, 0, 17 };
 methodParams.put(Integer.valueOf(this.getMWL()), MWvalues);

// Makkah
 double[] MKvalues = { 18.5, 1, 0, 1, 90 };
 methodParams.put(Integer.valueOf(this.getMakkah()), MKvalues);

// Egypt
 double[] Evalues = { 19.5, 1, 0, 0, 17.5 };
 methodParams.put(Integer.valueOf(this.getEgypt()), Evalues);

// Tehran
 double[] Tvalues = { 17.7, 0, 4.5, 0, 14 };
 methodParams.put(Integer.valueOf(this.getTehran()), Tvalues);

// Custom
 double[] Cvalues = { 18, 1, 0, 0, 17 };
 methodParams.put(Integer.valueOf(this.getCustom()), Cvalues);

}

// ---------------------- Trigonometric Functions -----------------------
 // range reduce angle in degrees.
 private double fixangle(double a) {

a = a - (360 * (Math.floor(a / 360.0)));

a = a < 0 ? (a + 360) : a;

return a;
 }

// range reduce hours to 0..23
 private double fixhour(double a) {
 a = a - 24.0 * Math.floor(a / 24.0);
 a = a < 0 ? (a + 24) : a;
 return a;
 }

// radian to degree
 private double radiansToDegrees(double alpha) {
 return ((alpha * 180.0) / Math.PI);
 }

// deree to radian
 private double DegreesToRadians(double alpha) {
 return ((alpha * Math.PI) / 180.0);
 }

// degree sin
 private double dsin(double d) {
 return (Math.sin(DegreesToRadians(d)));
 }

// degree cos
 private double dcos(double d) {
 return (Math.cos(DegreesToRadians(d)));
 }

// degree tan
 private double dtan(double d) {
 return (Math.tan(DegreesToRadians(d)));
 }

// degree arcsin
 private double darcsin(double x) {
 double val = Math.asin(x);
 return radiansToDegrees(val);
 }

// degree arccos
 private double darccos(double x) {
 double val = Math.acos(x);
 return radiansToDegrees(val);
 }

// degree arctan
 private double darctan(double x) {
 double val = Math.atan(x);
 return radiansToDegrees(val);
 }

// degree arctan2
 private double darctan2(double y, double x) {
 double val = Math.atan2(y, x);
 return radiansToDegrees(val);
 }

// degree arccot
 private double darccot(double x) {
 double val = Math.atan2(1.0, x);
 return radiansToDegrees(val);
 }

// ---------------------- Time-Zone Functions -----------------------
 // compute local time-zone for a specific date
 private double getTimeZone1() {
 TimeZone timez = TimeZone.getDefault();
 double hoursDiff = (timez.getRawOffset() / 1000.0) / 3600;
 return hoursDiff;
 }

// compute base time-zone of the system
 private double getBaseTimeZone() {
 TimeZone timez = TimeZone.getDefault();
 double hoursDiff = (timez.getRawOffset() / 1000.0) / 3600;
 return hoursDiff;

}

// detect daylight saving in a given date
 private double detectDaylightSaving() {
 TimeZone timez = TimeZone.getDefault();
 double hoursDiff = timez.getDSTSavings();
 return hoursDiff;
 }

// ---------------------- Julian Date Functions -----------------------
 // calculate julian date from a calendar date
 private double julianDate(int year, int month, int day) {

if (month <= 2) {
 year -= 1;
 month += 12;
 }
 double A = Math.floor(year / 100.0);

double B = 2 - A + Math.floor(A / 4.0);

double JD = Math.floor(365.25 * (year + 4716))
 + Math.floor(30.6001 * (month + 1)) + day + B - 1524.5;

return JD;
 }

// convert a calendar date to julian date (second method)
 private double calcJD(int year, int month, int day) {
 double J1970 = 2440588.0;
 Date date = new Date(year, month - 1, day);

double ms = date.getTime(); // # of milliseconds since midnight Jan 1,
 // 1970
 double days = Math.floor(ms / (1000.0 * 60.0 * 60.0 * 24.0));
 return J1970 + days - 0.5;

}

// ---------------------- Calculation Functions -----------------------
 // References:
 // http://www.ummah.net/astronomy/saltime
 // http://aa.usno.navy.mil/faq/docs/SunApprox.html
 // compute declination angle of sun and equation of time
 private double[] sunPosition(double jd) {

double D = jd - 2451545;
 double g = fixangle(357.529 + 0.98560028 * D);
 double q = fixangle(280.459 + 0.98564736 * D);
 double L = fixangle(q + (1.915 * dsin(g)) + (0.020 * dsin(2 * g)));

// double R = 1.00014 - 0.01671 * [self dcos:g] - 0.00014 * [self dcos:
 // (2*g)];
 double e = 23.439 - (0.00000036 * D);
 double d = darcsin(dsin(e) * dsin(L));
 double RA = (darctan2((dcos(e) * dsin(L)), (dcos(L)))) / 15.0;
 RA = fixhour(RA);
 double EqT = q / 15.0 - RA;
 double[] sPosition = new double[2];
 sPosition[0] = d;
 sPosition[1] = EqT;

return sPosition;
 }

// compute equation of time
 private double equationOfTime(double jd) {
 double eq = sunPosition(jd)[1];
 return eq;
 }

// compute declination angle of sun
 private double sunDeclination(double jd) {
 double d = sunPosition(jd)[0];
 return d;
 }

// compute mid-day (Dhuhr, Zawal) time
 private double computeMidDay(double t) {
 double T = equationOfTime(this.getJDate() + t);
 double Z = fixhour(12 - T);
 return Z;
 }

// compute time for a given angle G
 private double computeTime(double G, double t) {

double D = sunDeclination(this.getJDate() + t);
 double Z = computeMidDay(t);
 double Beg = -dsin(G) - dsin(D) * dsin(this.getLat());
 double Mid = dcos(D) * dcos(this.getLat());
 double V = darccos(Beg / Mid) / 15.0;

return Z + (G > 90 ? -V : V);
 }

// compute the time of Asr
 // Shafii: step=1, Hanafi: step=2
 private double computeAsr(double step, double t) {
 double D = sunDeclination(this.getJDate() + t);
 double G = -darccot(step + dtan(Math.abs(this.getLat() - D)));
 return computeTime(G, t);
 }

// ---------------------- Misc Functions -----------------------
 // compute the difference between two times
 private double timeDiff(double time1, double time2) {
 return fixhour(time2 - time1);
 }

// -------------------- Interface Functions --------------------
 // return prayer times for a given date
 private ArrayList<String> getDatePrayerTimes(int year, int month, int day,
 double latitude, double longitude, double tZone) {
 this.setLat(latitude);
 this.setLng(longitude);
 this.setTimeZone(tZone);
 this.setJDate(julianDate(year, month, day));
 double lonDiff = longitude / (15.0 * 24.0);
 this.setJDate(this.getJDate() - lonDiff);
 return computeDayTimes();
 }

// return prayer times for a given date
 public ArrayList<String> getPrayerTimes(Calendar date, double latitude,
 double longitude, double tZone) {

int year = date.get(Calendar.YEAR);
 int month = date.get(Calendar.MONTH);
 int day = date.get(Calendar.DATE);

return getDatePrayerTimes(year, month + 1, day, latitude, longitude,
 tZone);
 }

// set custom values for calculation parameters
 private void setCustomParams(double[] params) {

for (int i = 0; i < 5; i++) {
 if (params[i] == -1) {
 params[i] = methodParams.get(this.getCalcMethod())[i];
 methodParams.put(this.getCustom(), params);
 } else {
 methodParams.get(this.getCustom())[i] = params[i];
 }
 }
 this.setCalcMethod(this.getCustom());
 }

// set the angle for calculating Fajr
 public void setFajrAngle(double angle) {
 double[] params = { angle, -1, -1, -1, -1 };
 setCustomParams(params);
 }

// set the angle for calculating Maghrib
 public void setMaghribAngle(double angle) {
 double[] params = { -1, 0, angle, -1, -1 };
 setCustomParams(params);

}

// set the angle for calculating Isha
 public void setIshaAngle(double angle) {
 double[] params = { -1, -1, -1, 0, angle };
 setCustomParams(params);

}

// set the minutes after Sunset for calculating Maghrib
 public void setMaghribMinutes(double minutes) {
 double[] params = { -1, 1, minutes, -1, -1 };
 setCustomParams(params);

}

// set the minutes after Maghrib for calculating Isha
 public void setIshaMinutes(double minutes) {
 double[] params = { -1, -1, -1, 1, minutes };
 setCustomParams(params);

}

// convert double hours to 24h format
 public String floatToTime24(double time) {

String result;

if (Double.isNaN(time)) {
 return InvalidTime;
 }

time = fixhour(time + 0.5 / 60.0); // add 0.5 minutes to round
 int hours = (int) Math.floor(time);
 double minutes = Math.floor((time - hours) * 60.0);

if ((hours >= 0 && hours <= 9) && (minutes >= 0 && minutes <= 9)) {
 result = "0" + hours + ":0" + Math.round(minutes);
 } else if ((hours >= 0 && hours <= 9)) {
 result = "0" + hours + ":" + Math.round(minutes);
 } else if ((minutes >= 0 && minutes <= 9)) {
 result = hours + ":0" + Math.round(minutes);
 } else {
 result = hours + ":" + Math.round(minutes);
 }
 return result;
 }

// convert double hours to 12h format
 public String floatToTime12(double time, boolean noSuffix) {

if (Double.isNaN(time)) {
 return InvalidTime;
 }

time = fixhour(time + 0.5 / 60); // add 0.5 minutes to round
 int hours = (int) Math.floor(time);
 double minutes = Math.floor((time - hours) * 60);
 String suffix, result;
 if (hours >= 12) {
 suffix = "pm";
 } else {
 suffix = "am";
 }
 hours = ((((hours + 12) - 1) % (12)) + 1);
 /*
 * hours = (hours + 12) - 1; int hrs = (int) hours % 12; hrs += 1;
 */
 if (noSuffix == false) {
 if ((hours >= 0 && hours <= 9) && (minutes >= 0 && minutes <= 9)) {
 result = "0" + hours + ":0" + Math.round(minutes) + " "
 + suffix;
 } else if ((hours >= 0 && hours <= 9)) {
 result = "0" + hours + ":" + Math.round(minutes) + " " + suffix;
 } else if ((minutes >= 0 && minutes <= 9)) {
 result = hours + ":0" + Math.round(minutes) + " " + suffix;
 } else {
 result = hours + ":" + Math.round(minutes) + " " + suffix;
 }

} else {
 if ((hours >= 0 && hours <= 9) && (minutes >= 0 && minutes <= 9)) {
 result = "0" + hours + ":0" + Math.round(minutes);
 } else if ((hours >= 0 && hours <= 9)) {
 result = "0" + hours + ":" + Math.round(minutes);
 } else if ((minutes >= 0 && minutes <= 9)) {
 result = hours + ":0" + Math.round(minutes);
 } else {
 result = hours + ":" + Math.round(minutes);
 }
 }
 return result;

}

// convert double hours to 12h format with no suffix
 public String floatToTime12NS(double time) {
 return floatToTime12(time, true);
 }

// ---------------------- Compute Prayer Times -----------------------
 // compute prayer times at given julian date
 private double[] computeTimes(double[] times) {

double[] t = dayPortion(times);

double Fajr = this.computeTime(
 180 - methodParams.get(this.getCalcMethod())[0], t[0]);

double Sunrise = this.computeTime(180 - 0.833, t[1]);

double Dhuhr = this.computeMidDay(t[2]);
 double Asr = this.computeAsr(1 + this.getAsrJuristic(), t[3]);
 double Sunset = this.computeTime(0.833, t[4]);

double Maghrib = this.computeTime(
 methodParams.get(this.getCalcMethod())[2], t[5]);
 double Isha = this.computeTime(
 methodParams.get(this.getCalcMethod())[4], t[6]);

double[] CTimes = { Fajr, Sunrise, Dhuhr, Asr, Sunset, Maghrib, Isha };

return CTimes;

}

// compute prayer times at given julian date
 private ArrayList<String> computeDayTimes() {
 double[] times = { 5, 6, 12, 13, 18, 18, 18 }; // default times

for (int i = 1; i <= this.getNumIterations(); i++) {
 times = computeTimes(times);
 }

times = adjustTimes(times);
 times = tuneTimes(times);

return adjustTimesFormat(times);
 }

// adjust times in a prayer time array
 private double[] adjustTimes(double[] times) {
 for (int i = 0; i < times.length; i++) {
 times[i] += this.getTimeZone() - this.getLng() / 15;
 }

times[2] += this.getDhuhrMinutes() / 60; // Dhuhr
 if (methodParams.get(this.getCalcMethod())[1] == 1) // Maghrib
 {
 times[5] = times[4] + methodParams.get(this.getCalcMethod())[2]
 / 60;
 }
 if (methodParams.get(this.getCalcMethod())[3] == 1) // Isha
 {
 times[6] = times[5] + methodParams.get(this.getCalcMethod())[4]
 / 60;
 }

if (this.getAdjustHighLats() != this.getNone()) {
 times = adjustHighLatTimes(times);
 }

return times;
 }

// convert times array to given time format
 private ArrayList<String> adjustTimesFormat(double[] times) {

ArrayList<String> result = new ArrayList<String>();

if (this.getTimeFormat() == this.getFloating()) {
 for (double time : times) {
 result.add(String.valueOf(time));
 }
 return result;
 }

for (int i = 0; i < 7; i++) {
 if (this.getTimeFormat() == this.getTime12()) {
 result.add(floatToTime12(times[i], false));
 } else if (this.getTimeFormat() == this.getTime12NS()) {
 result.add(floatToTime12(times[i], true));
 } else {
 result.add(floatToTime24(times[i]));
 }
 }
 return result;
 }

// adjust Fajr, Isha and Maghrib for locations in higher latitudes
 private double[] adjustHighLatTimes(double[] times) {
 double nightTime = timeDiff(times[4], times[1]); // sunset to sunrise

// Adjust Fajr
 double FajrDiff = nightPortion(methodParams.get(this.getCalcMethod())[0])
 * nightTime;

if (Double.isNaN(times[0]) || timeDiff(times[0], times[1]) > FajrDiff) {
 times[0] = times[1] - FajrDiff;
 }

// Adjust Isha
 double IshaAngle = (methodParams.get(this.getCalcMethod())[3] == 0) ? methodParams
 .get(this.getCalcMethod())[4] : 18;
 double IshaDiff = this.nightPortion(IshaAngle) * nightTime;
 if (Double.isNaN(times[6])
 || this.timeDiff(times[4], times[6]) > IshaDiff) {
 times[6] = times[4] + IshaDiff;
 }

// Adjust Maghrib
 double MaghribAngle = (methodParams.get(this.getCalcMethod())[1] == 0) ? methodParams
 .get(this.getCalcMethod())[2] : 4;
 double MaghribDiff = nightPortion(MaghribAngle) * nightTime;
 if (Double.isNaN(times[5])
 || this.timeDiff(times[4], times[5]) > MaghribDiff) {
 times[5] = times[4] + MaghribDiff;
 }

return times;
 }

// the night portion used for adjusting times in higher latitudes
 private double nightPortion(double angle) {
 double calc = 0;

if (adjustHighLats == AngleBased)
 calc = (angle) / 60.0;
 else if (adjustHighLats == MidNight)
 calc = 0.5;
 else if (adjustHighLats == OneSeventh)
 calc = 0.14286;

return calc;
 }

// convert hours to day portions
 private double[] dayPortion(double[] times) {
 for (int i = 0; i < 7; i++) {
 times[i] /= 24;
 }
 return times;
 }

// Tune timings for adjustments
 // Set time offsets
 public void tune(int[] offsetTimes) {

for (int i = 0; i < offsetTimes.length; i++) { // offsetTimes length
 // should be 7 in order
 // of Fajr, Sunrise,
 // Dhuhr, Asr, Sunset,
 // Maghrib, Isha
 this.offsets[i] = offsetTimes[i];
 }
 }

private double[] tuneTimes(double[] times) {
 for (int i = 0; i < times.length; i++) {
 times[i] = times[i] + this.offsets[i] / 60.0;
 }

return times;
 }




public int getCalcMethod() {
 return calcMethod;
 }

public void setCalcMethod(int calcMethod) {
 this.calcMethod = calcMethod;
 }

public int getAsrJuristic() {
 return asrJuristic;
 }

public void setAsrJuristic(int asrJuristic) {
 this.asrJuristic = asrJuristic;
 }

public int getDhuhrMinutes() {
 return dhuhrMinutes;
 }

public void setDhuhrMinutes(int dhuhrMinutes) {
 this.dhuhrMinutes = dhuhrMinutes;
 }

public int getAdjustHighLats() {
 return adjustHighLats;
 }

public void setAdjustHighLats(int adjustHighLats) {
 this.adjustHighLats = adjustHighLats;
 }

public int getTimeFormat() {
 return timeFormat;
 }

public void setTimeFormat(int timeFormat) {
 this.timeFormat = timeFormat;
 }

public double getLat() {
 return lat;
 }

public void setLat(double lat) {
 this.lat = lat;
 }

public double getLng() {
 return lng;
 }

public void setLng(double lng) {
 this.lng = lng;
 }

public double getTimeZone() {
 return timeZone;
 }

public void setTimeZone(double timeZone) {
 this.timeZone = timeZone;
 }

public double getJDate() {
 return JDate;
 }

public void setJDate(double jDate) {
 JDate = jDate;
 }

private int getJafari() {
 return Jafari;
 }

private void setJafari(int jafari) {
 Jafari = jafari;
 }

private int getKarachi() {
 return Karachi;
 }

private void setKarachi(int karachi) {
 Karachi = karachi;
 }

private int getISNA() {
 return ISNA;
 }

private void setISNA(int iSNA) {
 ISNA = iSNA;
 }

private int getMWL() {
 return MWL;
 }

private void setMWL(int mWL) {
 MWL = mWL;
 }

private int getMakkah() {
 return Makkah;
 }

private void setMakkah(int makkah) {
 Makkah = makkah;
 }

private int getEgypt() {
 return Egypt;
 }

private void setEgypt(int egypt) {
 Egypt = egypt;
 }

private int getCustom() {
 return Custom;
 }

private void setCustom(int custom) {
 Custom = custom;
 }

private int getTehran() {
 return Tehran;
 }

private void setTehran(int tehran) {
 Tehran = tehran;
 }

private int getShafii() {
 return Shafii;
 }

private void setShafii(int shafii) {
 Shafii = shafii;
 }

private int getHanafi() {
 return Hanafi;
 }

private void setHanafi(int hanafi) {
 Hanafi = hanafi;
 }

private int getNone() {
 return None;
 }

private void setNone(int none) {
 None = none;
 }

private int getMidNight() {
 return MidNight;
 }

private void setMidNight(int midNight) {
 MidNight = midNight;
 }

private int getOneSeventh() {
 return OneSeventh;
 }

private void setOneSeventh(int oneSeventh) {
 OneSeventh = oneSeventh;
 }

private int getAngleBased() {
 return AngleBased;
 }

private void setAngleBased(int angleBased) {
 AngleBased = angleBased;
 }

private int getTime24() {
 return Time24;
 }

private void setTime24(int time24) {
 Time24 = time24;
 }

private int getTime12() {
 return Time12;
 }

private void setTime12(int time12) {
 Time12 = time12;
 }

private int getTime12NS() {
 return Time12NS;
 }

private void setTime12NS(int time12ns) {
 Time12NS = time12ns;
 }

private int getFloating() {
 return Floating;
 }

private void setFloating(int floating) {
 Floating = floating;
 }

private int getNumIterations() {
 return numIterations;
 }

private void setNumIterations(int numIterations) {
 this.numIterations = numIterations;
 }

public ArrayList<String> getTimeNames() {
 return timeNames;
 }
}

Prayer Times Demo

 
10 Comments

Posted by on July 7, 2013 in Uncategorized

 

Some Useful Links for Android development [Based on features]


During my training sessions, trainers frequently ask few questions. Also I get a lot of requests to provide useful links on various features in Android platform. Although developer site is good enough and there is stackoverflow and github to get solutions, I think it will be helpful to many if they get some good links here.

1. LazyList: Creating Custom ListView with Lazy Loading:

Often you’ll need to show a big list in ListView with image icons which are supposed to be downloaded from any server. The problem is you can’t wait to get all images downloaded and then show the listview with data. This project in github solves this problem by asynchronous loading of images. Another great thing is that it supports caching of the images. Caching is down by saving those images in SDCard.

LazyList in github.com

2. Location API: Accuracy of Android GPS

These 2 blogposts discusses various use-case scenarios regarding the use of Location API GPS data in Android. They thoroughly discuss the accuracy issues along with which way to choose during development based on application requirements. The posts are very detailed and great.

Android GPS: Accuracy Part 1

Android GPS: Accuracy Part 2

3. Android Location API: The Ultimate Solution

This is the best post to me so far regarding Android Location API. This post accompanies a open source project hosted in Google Code:

Location API: Deep Dive

Project: Android Protips Location

4. Android: Connecting with PHP+MySQL

Although the following blogposts do not describe “Best Practices”, but they are a good starting point to create web services in PHP(with MySQL) and connect from Android applications. They include source codes and explanation.

How to Connect Android with PHP, MySql

Login and Registration using PHP. MySql

 
2 Comments

Posted by on April 4, 2013 in Uncategorized

 

From Android towards Cross-Platform


In this video, I have tried to explain how the cross-platform mobile development works.

 
Leave a comment

Posted by on February 12, 2013 in Uncategorized

 

Android: Collecting and Plotting Accelerometer Data


Today we’ll create an app to collect accelerometer reading and plot data in a XY-Line chart.
Accelerometer Reading

Android Sensors and SensorManager:
Android supports several Sensors via SensorManager, for example Accelerometer[http://en.wikipedia.org/wiki/Accelerometer].

1. Project Creation:
Project CreationProject Creation 2

2. Layout:
Now we create the following layout:





        <button>

        </button><button>

        </button><button>





We keep the layout simple by keeping
i. a button to start reading
ii. a button to stop reading and show graph
iii. a button to upload data to server (covered in next post)
iv. a placeholder in the below portion [LinearLayout] as the chart container

Layout

Layout

3. MainActivity.java

First, to listen click events to the buttons and to listen to the SensorEvents we implement the Activity as SensorEventListener and OnClickListener (android.view.View):

package com.smartapps.accel;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;

public class MainActivity extends Activity implements SensorEventListener,
		OnClickListener {
	private Button btnStart, btnStop, btnUpload;
	private LinearLayout layout;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		btnStart = (Button) findViewById(R.id.btnStart);
		btnStop = (Button) findViewById(R.id.btnStop);
		btnUpload = (Button) findViewById(R.id.btnUpload);
		btnStart.setOnClickListener(this);
		btnStop.setOnClickListener(this);
		btnUpload.setOnClickListener(this);
		btnStart.setEnabled(true);
		btnStop.setEnabled(false);

                layout = (LinearLayout) findViewById(R.id.chart_container);
		if (sensorData == null || sensorData.size() == 0) {
			btnUpload.setEnabled(false);
		}

	}

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

	}

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

	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {

	}

	@Override
	public void onSensorChanged(SensorEvent event) {

	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btnStart:
			// start reading
			break;
		case R.id.btnStop:
			// stop reading and show data in chart
			break;
		case R.id.btnUpload:
                        // upload data to server (next post)
			break;
		default:
			break;
		}

	}

}

Next we create AccelData class: AccelData.java

package com.smartapps.accel;

public class AccelData {
	private long timestamp;
	private double x;
	private double y;
	private double z;

	public AccelData(long timestamp, double x, double y, double z) {
		this.timestamp = timestamp;
		this.x = x;
		this.y = y;
		this.z = z;
	}
	public long getTimestamp() {
		return timestamp;
	}
	public void setTimestamp(long timestamp) {
		this.timestamp = timestamp;
	}
	public double getX() {
		return x;
	}
	public void setX(double x) {
		this.x = x;
	}
	public double getY() {
		return y;
	}
	public void setY(double y) {
		this.y = y;
	}
	public double getZ() {
		return z;
	}
	public void setZ(double z) {
		this.z = z;
	}

	public String toString()
	{
		return "t="+timestamp+", x="+x+", y="+y+", z="+z;
	}
}

Now we can complete the MainActivity.java:

package com.smartapps.accel;

import java.util.ArrayList;

import org.achartengine.ChartFactory;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;

public class MainActivity extends Activity implements SensorEventListener,
		OnClickListener {
	private SensorManager sensorManager;
	private Button btnStart, btnStop, btnUpload;
	private boolean started = false;
	private ArrayList sensorData;
	private LinearLayout layout;
	private View mChart;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		layout = (LinearLayout) findViewById(R.id.chart_container);
		sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
		sensorData = new ArrayList();

		btnStart = (Button) findViewById(R.id.btnStart);
		btnStop = (Button) findViewById(R.id.btnStop);
		btnUpload = (Button) findViewById(R.id.btnUpload);
		btnStart.setOnClickListener(this);
		btnStop.setOnClickListener(this);
		btnUpload.setOnClickListener(this);
		btnStart.setEnabled(true);
		btnStop.setEnabled(false);
		if (sensorData == null || sensorData.size() == 0) {
			btnUpload.setEnabled(false);
		}

	}

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

	}

	@Override
	protected void onPause() {
		super.onPause();
		if (started == true) {
			sensorManager.unregisterListener(this);
		}
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {

	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		if (started) {
			double x = event.values[0];
			double y = event.values[1];
			double z = event.values[2];
			long timestamp = System.currentTimeMillis();
			AccelData data = new AccelData(timestamp, x, y, z);
			sensorData.add(data);
		}

	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btnStart:
			btnStart.setEnabled(false);
			btnStop.setEnabled(true);
			btnUpload.setEnabled(false);
			sensorData = new ArrayList();
			// save prev data if available
			started = true;
			Sensor accel = sensorManager
					.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
			sensorManager.registerListener(this, accel,
					SensorManager.SENSOR_DELAY_FASTEST);
			break;
		case R.id.btnStop:
			btnStart.setEnabled(true);
			btnStop.setEnabled(false);
			btnUpload.setEnabled(true);
			started = false;
			sensorManager.unregisterListener(this);
			layout.removeAllViews();
			openChart();

			// show data in chart
			break;
		case R.id.btnUpload:

			break;
		default:
			break;
		}

	}

	private void openChart() {
		if (sensorData != null || sensorData.size() > 0) {
			long t = sensorData.get(0).getTimestamp();
			XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();

			XYSeries xSeries = new XYSeries("X");
			XYSeries ySeries = new XYSeries("Y");
			XYSeries zSeries = new XYSeries("Z");

			for (AccelData data : sensorData) {
				xSeries.add(data.getTimestamp() - t, data.getX());
				ySeries.add(data.getTimestamp() - t, data.getY());
				zSeries.add(data.getTimestamp() - t, data.getZ());
			}

			dataset.addSeries(xSeries);
			dataset.addSeries(ySeries);
			dataset.addSeries(zSeries);

			XYSeriesRenderer xRenderer = new XYSeriesRenderer();
			xRenderer.setColor(Color.RED);
			xRenderer.setPointStyle(PointStyle.CIRCLE);
			xRenderer.setFillPoints(true);
			xRenderer.setLineWidth(1);
			xRenderer.setDisplayChartValues(false);

			XYSeriesRenderer yRenderer = new XYSeriesRenderer();
			yRenderer.setColor(Color.GREEN);
			yRenderer.setPointStyle(PointStyle.CIRCLE);
			yRenderer.setFillPoints(true);
			yRenderer.setLineWidth(1);
			yRenderer.setDisplayChartValues(false);

			XYSeriesRenderer zRenderer = new XYSeriesRenderer();
			zRenderer.setColor(Color.BLUE);
			zRenderer.setPointStyle(PointStyle.CIRCLE);
			zRenderer.setFillPoints(true);
			zRenderer.setLineWidth(1);
			zRenderer.setDisplayChartValues(false);

			XYMultipleSeriesRenderer multiRenderer = new XYMultipleSeriesRenderer();
			multiRenderer.setXLabels(0);
			multiRenderer.setLabelsColor(Color.RED);
			multiRenderer.setChartTitle("t vs (x,y,z)");
			multiRenderer.setXTitle("Sensor Data");
			multiRenderer.setYTitle("Values of Acceleration");
			multiRenderer.setZoomButtonsVisible(true);
			for (int i = 0; i < sensorData.size(); i++) {

				multiRenderer.addXTextLabel(i + 1, ""
						+ (sensorData.get(i).getTimestamp() - t));
			}
			for (int i = 0; i < 12; i++) {
				multiRenderer.addYTextLabel(i + 1, ""+i);
			}

			multiRenderer.addSeriesRenderer(xRenderer);
			multiRenderer.addSeriesRenderer(yRenderer);
			multiRenderer.addSeriesRenderer(zRenderer);

			// Getting a reference to LinearLayout of the MainActivity Layout

			// Creating a Line Chart
			mChart = ChartFactory.getLineChartView(getBaseContext(), dataset,
					multiRenderer);

			// Adding the Line Chart to the LinearLayout
			layout.addView(mChart);

		}
	}
}

SensorManager lets you access the device’s sensors. Get an instance of this class by calling Context.getSystemService() with the argument SENSOR_SERVICE. [http://developer.android.com/reference/android/hardware/SensorManager.html]

Always make sure to disable sensors you don’t need, especially when your activity is paused. Failing to do so can drain the battery in just a few hours. Note that the system will not disable sensors automatically when the screen turns off.

Here we have used aChartEngine to draw chart. To use aChartEngine library you have to download a jar file from here: http://achartengine.googlecode.com/files/achartengine-1.0.0.jar

Copy the downloaded jar file to the libs folder of your project and then add the jar to build path:

Adding jar to Build Path of the Project

Adding jar to Build Path of the Project

Please let me know if you face problems in comments.

Download source code from here: http://www.mediafire.com/?rq49zovwij74w4m

In the next tutorial we’ll upload these data to a php server.

 
17 Comments

Posted by on January 16, 2013 in Uncategorized

 

Android Media API Example


Part 1:

Part 1:

Part 2:

Part 2:

 
2 Comments

Posted by on December 11, 2012 in Uncategorized

 

Tags: , , , ,

Game Tutorial with libgdx


Original Credit:

http://obviam.net/index.php/getting-started-in-android-game-development-with-libgdx-create-a-working-prototype-in-a-day-tutorial-part-1/

Part 1:

Part 2:

Part 3:

Part 4:

Part 5:

Part 6:

 
Leave a comment

Posted by on September 18, 2012 in Uncategorized

 

Brief Overview of Android Internals


 
Leave a comment

Posted by on June 7, 2012 in Uncategorized