diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c68eefe05b..6f5cade628 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1,7 +1,6 @@
+ package="com.quran.labs.androidquran" android:versionCode="9" android:versionName="1.5.2" android:installLocation="preferExternal">
-
\ No newline at end of file
+
diff --git a/README.md b/README.md
index d8a27db031..3788486f55 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,8 @@ code by [@ahmedre](http://twitter.com/ahmedre),
and [@wnafee](http://twitter.com/wnafee). graphics by
[@somaiagabr](http://twitter.com/somaiagabr).
+contributors include [@afarra](http://github.com/afarra) and [@mahmoudhossam](http://github.com/mahmoudhossam).
+
Terms of use
------------
you are free to use parts of (or all of) the Quran Android code in your
@@ -39,6 +41,19 @@ Project dependecies
Changelog
---------
+**version 1.5.2**
+
+- fix crash on android 1.5.
+- rub3/7izb/juz2 notifications while reading
+- autoscroll to ayah if it is not visible on the screen
+- audio options to resume from last played ayah, start of the page, or start
+ of any of the suras on that page.
+- apps2sd support.
+- plethora of bugfixes (arabic fixes, seekbar not refreshing after jump, page
+ resets when orientation changes in translation view, page navigated to in
+ translation not retained when returning to quran view, and warning if the
+ sd card is filled).
+
**version 1.5**
- audio support
diff --git a/lib/gson-1.4.jar b/lib/gson-1.4.jar
deleted file mode 100644
index b9c33d0390..0000000000
Binary files a/lib/gson-1.4.jar and /dev/null differ
diff --git a/lib/gson-1.7.1.jar b/lib/gson-1.7.1.jar
new file mode 100755
index 0000000000..acd16c0646
Binary files /dev/null and b/lib/gson-1.7.1.jar differ
diff --git a/res/layout/about_us.xml b/res/layout/about_us.xml
index 229c69ec10..c5ea226818 100644
--- a/res/layout/about_us.xml
+++ b/res/layout/about_us.xml
@@ -18,7 +18,7 @@
+ android:visibility="visible" android:onClick="onEmailClick"/>
-
-
-
-
-
-
+ android:prompt="@string/prompt_select_reciter"
+ android:entries="@array/quran_readers_name"/>
+
+
+
+
+
+
+
+
diff --git a/res/layout/dialog_play.xml b/res/layout/dialog_play.xml
new file mode 100644
index 0000000000..38e86f9b9e
--- /dev/null
+++ b/res/layout/dialog_play.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index d72392b7a7..5fbc619b1a 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -57,8 +57,8 @@
مساعد قران اندرويد
- ضع الشاشه في الوضع الافقي للتكبير في هذا الاصدار..
- \n- لتغير الصفحة انقر يمين او يسار الشاشة،او باستخدام اصبعك لتحريك الصفحة
- \n- اضغط على وسط الشاشة للحصول على التمرير لتحويل صفحات.
+ \n- لتغير الصفحة استخدم اصبعك لتحريك الصفحة
+ \n- اضغط على الشاشة للحصول على التمرير لتحويل صفحات و امكانية الاستماع و امكانية حفظ الصفحة.
\n- يمكنك تحديد الاتجاه في وضع افقي أو رأسي.
\n- تصفح و حمل الترجمة المتاحة (اختر القايمة حصول على لاترجمة(
\n-يمكنك تحميل العديد من الترجمات كما تريد، ولكن ترجمة واحدة فقط
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 887a08dda7..2a88018899 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -1,4 +1,5 @@
- #0f2d4d
+ #0f2d4d
+ #802A2A
diff --git a/res/values/strings.xml b/res/values/strings.xml
index aabae678f1..f99ccfe09c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -46,9 +46,12 @@
quran.android@gmail.com
Quran Android is a free, open source Quran
application for Android. The images used are from the quran.com
- project, and the data used in the translations and Arabic comes from
+ project, the audio comes from everyayah.com,
+ the data used in the translations and Arabic comes from
tanzil.net.
\n\nCredits:
+ \n Ahmed Farra - bugfixes and many contributions.
+ \n Mahmoud Hossam - bugfixes.
\n @fo2ad - audio recitation support
\n @wnafee - page flip animation (based on android-page-curl project)
\n @hams_rrr - arabic support for non-arabic phones
@@ -62,9 +65,8 @@
Quran Android Help
- Flip your screen to landscape mode for a zoomed in version.
- \n- Change pages by tapping the right or left side of the screen, or by
- swiping your finger across the screen.
- \n- Tap the center of the screen to get a slider for switching pages.
+ \n- Change pages by swiping your finger across the screen.
+ \n- Tap the screen to get a bookmark button, a slider for switching pages and audio.
\n- You can fix the orientation in either landscape or portrait modes.
\n- Browse and download available translations (choose Menu > Get Translations).
\n- You can download as many translations as you want, yet only one translation
@@ -83,6 +85,7 @@
useArabicNames
keepScreenOn
displayMarkerPopup
+ autoScroll
lockOrientation
landscapeOrientation
translationTextSize
@@ -118,5 +121,10 @@
Set Active
Select Ayah
Select Sura
- Choose download option
+ Select Reciter
+ Start playing from...
+ Current Page (%s)
+ Resume %1$s : %2$s
+ Choose download option
+ Current Page (%s)
diff --git a/res/xml/quran_preferences.xml b/res/xml/quran_preferences.xml
index f8d7afdb18..1cee4d055c 100644
--- a/res/xml/quran_preferences.xml
+++ b/res/xml/quran_preferences.xml
@@ -25,7 +25,12 @@
+ android:persistent="true" android:key="@string/prefs_display_marker_popup" android:defaultValue="true">
+
+
diff --git a/src/com/quran/labs/androidquran/AboutUsActivity.java b/src/com/quran/labs/androidquran/AboutUsActivity.java
index 51fa5dc0af..535275518e 100644
--- a/src/com/quran/labs/androidquran/AboutUsActivity.java
+++ b/src/com/quran/labs/androidquran/AboutUsActivity.java
@@ -5,38 +5,23 @@
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
import android.widget.TextView;
-public class AboutUsActivity extends Activity implements OnClickListener {
- protected Button btnEmailUs;
- protected TextView txtAbout;
+public class AboutUsActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.about_us);
-
- btnEmailUs = (Button)findViewById(R.id.btnEmailUs);
- btnEmailUs.setOnClickListener(this);
-
- txtAbout = (TextView)findViewById(R.id.txtAbout);
- txtAbout.setVerticalScrollBarEnabled(true);
- txtAbout.setMovementMethod(new ScrollingMovementMethod());
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.about_us);
+ TextView txtAbout = (TextView) findViewById(R.id.txtAbout);
+ txtAbout.setVerticalScrollBarEnabled(true);
+ txtAbout.setMovementMethod(new ScrollingMovementMethod());
}
-
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.btnEmailUs:
- final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
- emailIntent.setType("plain/text");
- emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, getString(R.string.email_subject));
- emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{getString(R.string.email_to)});
- startActivity(Intent.createChooser(emailIntent, "Send mail..."));
- break;
- default:
- break;
- }
+
+ public void onEmailClick(View v) {
+ Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
+ emailIntent.setType("plain/text");
+ emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, getString(R.string.email_subject));
+ emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] { getString(R.string.email_to) });
+ startActivity(Intent.createChooser(emailIntent, "Send mail..."));
}
}
diff --git a/src/com/quran/labs/androidquran/BookmarksActivity.java b/src/com/quran/labs/androidquran/BookmarksActivity.java
index ac8574d9a8..e9d8ac4754 100644
--- a/src/com/quran/labs/androidquran/BookmarksActivity.java
+++ b/src/com/quran/labs/androidquran/BookmarksActivity.java
@@ -19,6 +19,7 @@
import com.quran.labs.androidquran.common.BaseQuranActivity;
import com.quran.labs.androidquran.data.QuranInfo;
+import com.quran.labs.androidquran.util.ArabicStyle;
import com.quran.labs.androidquran.util.BookmarksManager;
public class BookmarksActivity extends BaseQuranActivity {
@@ -39,8 +40,8 @@ private void showBookmarks() {
ArrayList bookmarks = BookmarksManager.getInstance().getBookmarks();
for (int i = 0; i < bookmarks.size(); i++) {
int page = bookmarks.get(i);
- String title = QuranInfo.getSuraNameString(page);
- String info = QuranInfo.getSuraDetailsForBookmark(page);
+ String title = ArabicStyle.reshape(QuranInfo.getSuraNameString(page));
+ String info = ArabicStyle.reshape(QuranInfo.getSuraDetailsForBookmark(page));
Map map = new HashMap();
map.put("suraname", title);
map.put("info", info);
diff --git a/src/com/quran/labs/androidquran/QuranActivity.java b/src/com/quran/labs/androidquran/QuranActivity.java
index 65005e1ddf..865aeb0bc9 100644
--- a/src/com/quran/labs/androidquran/QuranActivity.java
+++ b/src/com/quran/labs/androidquran/QuranActivity.java
@@ -16,11 +16,11 @@
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
+import static com.quran.labs.androidquran.data.ApplicationConstants.*;
import com.markupartist.android.widget.ActionBar;
import com.markupartist.android.widget.ActionBar.IntentAction;
import com.quran.labs.androidquran.common.BaseQuranActivity;
-import com.quran.labs.androidquran.data.ApplicationConstants;
import com.quran.labs.androidquran.data.QuranInfo;
import com.quran.labs.androidquran.service.QuranDataService;
import com.quran.labs.androidquran.util.ArabicStyle;
@@ -42,15 +42,21 @@ public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.quran_list);
QuranSettings.load(prefs);
- // set the asset manager to define the Arabic font
- ArabicStyle.setAssetManager(getAssets());
- Intent i = new Intent(this, QuranDataActivity.class);
- startActivityForResult(i, ApplicationConstants.DATA_CHECK_CODE);
-
+ setArabicFont();
actionBar = (ActionBar) findViewById(R.id.actionbar);
addActions();
}
+ /**
+ * set the asset manager to define the Arabic font
+ */
+
+ public void setArabicFont(){
+ ArabicStyle.setAssetManager(getAssets());
+ Intent i = new Intent(this, QuranDataActivity.class);
+ startActivityForResult(i, DATA_CHECK_CODE);
+ }
+
/**
* Sets up the action bar.
*/
@@ -65,7 +71,7 @@ protected void onNewIntent(Intent intent) {
String action = intent.getAction();
if (ACTION_BOOKMARK.equals(action)) {
Intent i = new Intent(getApplicationContext(), BookmarksActivity.class);
- startActivityForResult(i, ApplicationConstants.BOOKMARKS_CODE);
+ startActivityForResult(i, BOOKMARKS_CODE);
} else if (ACTION_RESUME.equals(action)) {
jumpTo(QuranSettings.getInstance().getLastPage());
}
@@ -96,12 +102,12 @@ public void onConfigurationChanged(Configuration newConfig) {
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
- if (requestCode == ApplicationConstants.DATA_CHECK_CODE){
+ if (requestCode == DATA_CHECK_CODE){
showSuras();
Integer lastPage = QuranSettings.getInstance().getLastPage();
- if (lastPage != null && lastPage != ApplicationConstants.NO_PAGE_SAVED)
+ if (lastPage != null && lastPage != NO_PAGE_SAVED)
jumpTo(lastPage);
- } else if (requestCode == ApplicationConstants.SETTINGS_CODE) {
+ } else if (requestCode == SETTINGS_CODE) {
QuranSettings.load(prefs);
showSuras();
}
@@ -118,12 +124,12 @@ public void showSuras() {
int pos = 0;
int sura = 1;
int next = 1;
- QuranElement[] elements = new QuranElement[114+30];
+ QuranElement[] elements = new QuranElement[SURAS_COUNT + JUZ2_COUNT];
- for (int juz=1; juz <= ApplicationConstants.JUZ2_COUNT; juz++){
+ for (int juz=1; juz <= JUZ2_COUNT; juz++){
elements[pos++] = new QuranElement(QuranInfo.getJuzTitle() + " " + juz, true, juz, QuranInfo.JUZ_PAGE_START[juz-1]);
- next = (juz == ApplicationConstants.JUZ2_COUNT) ? ApplicationConstants.PAGES_LAST+1 : QuranInfo.JUZ_PAGE_START[juz];
- while ((sura <= ApplicationConstants.SURAS_COUNT) && (QuranInfo.SURA_PAGE_START[sura-1] < next)) {
+ next = (juz == JUZ2_COUNT) ? PAGES_LAST+1 : QuranInfo.JUZ_PAGE_START[juz];
+ while ((sura <= SURAS_COUNT) && (QuranInfo.SURA_PAGE_START[sura-1] < next)) {
String title = QuranInfo.getSuraTitle() + " " + QuranInfo.getSuraName(sura-1);
elements[pos++] = new QuranElement(title, false, sura, QuranInfo.SURA_PAGE_START[sura-1]);
sura++;
diff --git a/src/com/quran/labs/androidquran/QuranViewActivity.java b/src/com/quran/labs/androidquran/QuranViewActivity.java
index b6848176a6..61119f1696 100644
--- a/src/com/quran/labs/androidquran/QuranViewActivity.java
+++ b/src/com/quran/labs/androidquran/QuranViewActivity.java
@@ -2,6 +2,7 @@
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Map;
import android.app.AlertDialog;
import android.content.ComponentName;
@@ -33,9 +34,9 @@
import com.quran.labs.androidquran.data.QuranInfo;
import com.quran.labs.androidquran.service.AudioServiceBinder;
import com.quran.labs.androidquran.service.QuranAudioService;
+import com.quran.labs.androidquran.util.ArabicStyle;
import com.quran.labs.androidquran.util.QuranAudioLibrary;
import com.quran.labs.androidquran.util.QuranSettings;
-import com.quran.labs.androidquran.util.QuranUtils;
public class QuranViewActivity extends PageViewQuranActivity implements
AyahStateListener {
@@ -125,26 +126,16 @@ private IntentAction getIntentAction(String intentAction, int drawable) {
@Override
protected void onNewIntent(Intent intent) {
- // TODO Auto-generated method stub
super.onNewIntent(intent);
String action = intent.getAction();
if (quranAudioPlayer != null && action != null) {
if (action.equalsIgnoreCase(ACTION_PLAY)) {
bindAudioService();
- if (quranAudioPlayer.isPaused())
+ if (quranAudioPlayer.isPaused()) {
quranAudioPlayer.resume();
- else {
- lastAyah = getLastAyah();
- // soura not totall found
- if (QuranUtils.isSouraAudioFound(lastAyah
- .getQuranReaderId(), lastAyah.getSoura()) < 0) {
- showDownloadDialog(lastAyah);
- } else {
- quranAudioPlayer.enableRemotePlay(false);
- playAudio(lastAyah);
- }
- }
- onActionPlay();
+ onActionPlay();
+ } else
+ showPlayDialog();
} else if (action.equalsIgnoreCase(ACTION_PAUSE)) {
quranAudioPlayer.pause();
onActionStop();
@@ -197,8 +188,57 @@ private void onActionStop() {
playing = false;
}
- private void showDownloadDialog(final AyahItem i) {
+ private void showPlayDialog() {
+ AlertDialog.Builder dialog = new AlertDialog.Builder(this);
+ LayoutInflater li = LayoutInflater.from(this);
+ final View view = li.inflate(R.layout.dialog_play, null);
+ dialog.setView(view);
+ final Map suraButtons = initPlayRadioButtons(view, quranPageFeeder.getCurrentPagePosition());
+ dialog.setPositiveButton("Play", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ RadioGroup radio = (RadioGroup) view.findViewById(R.id.radioGroupPlay);
+ int checkedRbId = radio.getCheckedRadioButtonId();
+ if (R.id.radioPlayPage == checkedRbId) {
+ // TODO Should have a method to get first ayah on page -AF
+ Integer[] pageBounds = QuranInfo.getPageBounds(quranPageFeeder.getCurrentPagePosition());
+ lastAyah = QuranAudioLibrary.getAyahItem(getApplicationContext(),
+ pageBounds[0], pageBounds[1], getQuranReaderId());
+ } else if (R.id.radioPlayLast == checkedRbId) {
+ // TODO Method to return AyahItem instead of one for Ayah + one for sura -AF
+ int lastPlayedSura = QuranSettings.getInstance().getLastPlayedSura();
+ int lastPlayedAyah = QuranSettings.getInstance().getLastPlayedAyah();
+ if (lastPlayedSura > 0 && lastPlayedAyah >= 0)
+ lastAyah = QuranAudioLibrary.getAyahItem(getApplicationContext(),
+ lastPlayedSura, lastPlayedAyah, getQuranReaderId());
+ } else {
+ for (Integer sura : suraButtons.keySet()) {
+ if (radio.getCheckedRadioButtonId() == suraButtons.get(sura).getId()) {
+ int ayah = sura == 1 || sura == 9 ? 1 : 0;
+ lastAyah = QuranAudioLibrary.getAyahItem(getApplicationContext(),
+ sura, ayah, getQuranReaderId());
+ break;
+ }
+ }
+ }
+ onActionPlay();
+ dialog.dismiss();
+ quranAudioPlayer.enableRemotePlay(false);
+ playAudio(lastAyah);
+ }
+ });
+ dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ }
+ });
+
+ AlertDialog diag = dialog.create();
+ diag.show();
+ }
+ private void showDownloadDialog(final AyahItem i) {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
LayoutInflater li = LayoutInflater.from(this);
final View view = li.inflate(R.layout.dialog_download, null);
@@ -207,8 +247,6 @@ private void showDownloadDialog(final AyahItem i) {
s.setSelection(getReaderIndex(getQuranReaderId()));
dialog.setView(view);
initDownloadRadioButtons(view, getLastAyah());
- // AlertDialog dialog = new DownloadDialog(this);
- dialog.setMessage("Select download option..");
dialog.setPositiveButton("Download",
new DialogInterface.OnClickListener() {
@@ -290,16 +328,47 @@ public void onClick(DialogInterface dialog, int which) {
diag.show();
}
+ // Returns a map of Sura Number to RadioButtons
+ private Map initPlayRadioButtons(View parent, int pageNum){
+ RadioButton radioPage = (RadioButton) parent.findViewById(R.id.radioPlayPage);
+ RadioButton radioLastAyah = (RadioButton) parent.findViewById(R.id.radioPlayLast);
+
+ radioPage.setText(getString(R.string.play_dialog_page, new Object[]{pageNum}));
+ int lastPlayedSura = QuranSettings.getInstance().getLastPlayedSura();
+ int lastPlayedAyah = QuranSettings.getInstance().getLastPlayedAyah();
+ if (lastPlayedSura > 0 && lastPlayedAyah >= 0)
+ radioLastAyah.setText(ArabicStyle.reshape(getString(R.string.play_dialog_resume,
+ new Object[]{QuranInfo.getSuraName(lastPlayedSura - 1), lastPlayedAyah})));
+ else
+ radioLastAyah.setVisibility(View.GONE);
+
+ Integer[] pageBounds = QuranInfo.getPageBounds(quranPageFeeder.getCurrentPagePosition());
+ RadioGroup rg = (RadioGroup)parent.findViewById(R.id.radioGroupPlay);
+ Map rbMap = new HashMap();
+ for (int i = pageBounds[0]; i <= pageBounds[2]; i++) {
+ RadioButton rb = new RadioButton(getApplicationContext());
+ rb.setText(ArabicStyle.reshape(QuranInfo.getSuraTitle() + " " + QuranInfo.getSuraName(i-1)));
+ rg.addView(rb);
+ rbMap.put(i, rb);
+ }
+ rg.invalidate();
+ return rbMap;
+ }
+
private void initDownloadRadioButtons(View parent, AyahItem ayahItem){
RadioButton radioSura = (RadioButton) parent.findViewById(R.id.radioDownloadSura);
RadioButton radioJuz = (RadioButton) parent.findViewById(R.id.radioDownloadJuza);
RadioButton radioPage = (RadioButton) parent.findViewById(R.id.radioDownloadPage);
- radioSura.setText(QuranInfo.getSuraName(ayahItem.getSoura() - 1));
- radioJuz.setText(QuranInfo.getJuzTitle() + " " + QuranInfo.getJuzFromPage(QuranInfo.getPageFromSuraAyah(ayahItem.getSoura(), ayahItem.getAyah())));
- radioPage.setText("Page");
+ radioSura.setText(ArabicStyle.reshape(QuranInfo.getSuraTitle() + " "
+ + QuranInfo.getSuraName(ayahItem.getSoura() - 1)));
+ radioJuz.setText(ArabicStyle.reshape(QuranInfo.getJuzTitle() + " " + QuranInfo.getJuzFromPage(
+ QuranInfo.getPageFromSuraAyah(ayahItem.getSoura(), ayahItem.getAyah()))));
+ radioPage.setText(getString(R.string.download_dialog_page,
+ new Object[]{quranPageFeeder.getCurrentPagePosition()}));
}
+
private void showJumpToAyahDialog() {
final Integer[] pageBounds = QuranInfo.getPageBounds(quranPageFeeder
.getCurrentPagePosition());
@@ -329,7 +398,8 @@ public void onItemSelected(AdapterView> adapter, View view,
int endAyah = suraIndex == pageBounds[2]? pageBounds[3] : QuranInfo.SURA_NUM_AYAHS[suraIndex - 1];
initAyatSpinner(ayatSpinner, startAyah, endAyah);
if (suraIndex == pageBounds[0]) {
- ayatSpinner.setSelection(pageBounds[1] - 1);
+ int selection = checkbox.isChecked()? 0 : pageBounds[1] - 1;
+ ayatSpinner.setSelection(selection);
}
}
@@ -386,7 +456,7 @@ private void initSurasSpinner(final Spinner spinner, int startSura, int endSura)
ArrayList> data = new ArrayList>();
for (int i = startSura; i <= endSura; i++) {
HashMap hash = new HashMap();
- hash.put("suraName", QuranInfo.getSuraName(i-1));
+ hash.put("suraName", ArabicStyle.reshape(QuranInfo.getSuraName(i-1)));
hash.put("suraId", ""+i);
data.add(hash);
}
@@ -421,11 +491,11 @@ private void showChangeReaderDialog() {
LayoutInflater li = LayoutInflater.from(this);
final View view = li.inflate(R.layout.dialog_download, null);
Spinner s = (Spinner) view.findViewById(R.id.spinner);
- View v = view.findViewById(R.id.radioGroupDownload);
+ View v = view.findViewById(R.id.scrollViewDownload);
v.setVisibility(View.GONE);
s.setSelection(getReaderIndex(getQuranReaderId()));
dialogBuilder.setView(view);
- dialogBuilder.setMessage("Change quran reader");
+ dialogBuilder.setMessage("Change reciter");
dialogBuilder.setPositiveButton("Set",
new DialogInterface.OnClickListener() {
@@ -577,6 +647,7 @@ private AyahItem getLastAyah() {
last = quranAudioPlayer.getCurrentAyah();
}
+ // TODO Should have a method to get first ayah on page -AF
if (last == null) {
Integer[] pageBounds = QuranInfo.getPageBounds(quranPageFeeder.getCurrentPagePosition());
last = QuranAudioLibrary.getAyahItem(getApplicationContext(),
@@ -613,6 +684,8 @@ public void onAyahPlay(AyahItem ayah) {
quranPageFeeder.highlightAyah(ayah.getSoura(), ayah.getAyah());
+ QuranSettings.getInstance().setLastPlayedAyah(ayah.getSoura(), ayah.getAyah());
+
if (!playing)
onActionPlay();
}
diff --git a/src/com/quran/labs/androidquran/TranslationActivity.java b/src/com/quran/labs/androidquran/TranslationActivity.java
index 330f6d498d..37d911e76c 100644
--- a/src/com/quran/labs/androidquran/TranslationActivity.java
+++ b/src/com/quran/labs/androidquran/TranslationActivity.java
@@ -49,6 +49,14 @@ protected void onResume() {
checkTranslationAvailability();
}
+ @Override
+ public void onBackPressed() {
+ Intent data = new Intent();
+ data.putExtra("page", quranPageFeeder.getCurrentPagePosition());
+ setResult(RESULT_OK, data);
+ super.onBackPressed();
+ }
+
private boolean checkTranslationAvailability() {
Log.d("QuranAndroid", "checking translations");
TranslationItem[] translationLists;
diff --git a/src/com/quran/labs/androidquran/common/BaseQuranActivity.java b/src/com/quran/labs/androidquran/common/BaseQuranActivity.java
index a36ecc182f..6f366b1f89 100644
--- a/src/com/quran/labs/androidquran/common/BaseQuranActivity.java
+++ b/src/com/quran/labs/androidquran/common/BaseQuranActivity.java
@@ -60,6 +60,12 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
jumpTo(lastPage);
}
break;
+ case ApplicationConstants.TRANSLATION_VIEW_CODE:
+ if (resultCode == Activity.RESULT_OK) {
+ Integer lastPage = data.getIntExtra("page", ApplicationConstants.PAGES_FIRST);
+ jumpTo(lastPage);
+ }
+ break;
}
}
diff --git a/src/com/quran/labs/androidquran/common/PageViewQuranActivity.java b/src/com/quran/labs/androidquran/common/PageViewQuranActivity.java
index 71e5bcee9d..c7d751a933 100644
--- a/src/com/quran/labs/androidquran/common/PageViewQuranActivity.java
+++ b/src/com/quran/labs/androidquran/common/PageViewQuranActivity.java
@@ -147,6 +147,7 @@ protected void onStart() {
@Override
public void jumpTo(int page) {
quranPageFeeder.jumpToPage(page);
+ updatePageInfo();
}
protected void goToNextPage() {
diff --git a/src/com/quran/labs/androidquran/common/QuranPageFeeder.java b/src/com/quran/labs/androidquran/common/QuranPageFeeder.java
index 4688fe59e6..1fa7dc620e 100644
--- a/src/com/quran/labs/androidquran/common/QuranPageFeeder.java
+++ b/src/com/quran/labs/androidquran/common/QuranPageFeeder.java
@@ -5,6 +5,7 @@
import java.util.Map;
import android.app.Activity;
+import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.LayoutInflater;
@@ -17,6 +18,7 @@
import com.quran.labs.androidquran.R;
import com.quran.labs.androidquran.data.ApplicationConstants;
import com.quran.labs.androidquran.data.QuranInfo;
+import com.quran.labs.androidquran.util.ArabicStyle;
import com.quran.labs.androidquran.util.QuranSettings;
import com.quran.labs.androidquran.util.QuranUtils;
import com.quran.labs.androidquran.widgets.HighlightingImageView;
@@ -81,9 +83,7 @@ public void jumpToPage(int page){
mQuranPage.addNextPage(createPage(page));
mQuranPage.addNextPage(createPage(page+1));
}
-
mCurrentPageNumber = page;
-
mQuranPage.refresh(true);
}
@@ -114,18 +114,26 @@ public void highlightAyah(int sura, int ayah){
if (iv != null){
HighlightingImageView hi = (HighlightingImageView)iv;
hi.highlightAyah(sura, ayah);
+ if (QuranSettings.getInstance().isAutoScroll() && v.getResources()
+ .getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ AyahBounds yBounds = hi.getYBoundsForCurrentHighlight();
+ if (yBounds != null)
+ mQuranPage.scrollToAyah(R.id.page_scroller, yBounds);
+ }
mQuranPage.invalidate();
}
}
public void unHighlightAyah(){
View v = mQuranPage.getCurrentPage();
- HighlightingImageView iv =
- (HighlightingImageView)v.findViewById(R.id.page_image);
- if (iv != null){
- HighlightingImageView hi = (HighlightingImageView)iv;
- hi.unhighlight();
- mQuranPage.invalidate();
+ if (v != null) {
+ HighlightingImageView iv =
+ (HighlightingImageView)v.findViewById(R.id.page_image);
+ if (iv != null){
+ HighlightingImageView hi = (HighlightingImageView)iv;
+ hi.unhighlight();
+ mQuranPage.invalidate();
+ }
}
}
@@ -164,19 +172,20 @@ public void displayMarkerPopup() {
int hizb = (rub3 / 4) + 1;
StringBuilder sb = new StringBuilder();
+ boolean arabic = QuranSettings.getInstance().isArabicNames();
if (rub3 % 8 == 0) {
- sb.append("Juz' ").append((hizb/2) + 1);
+ sb.append(arabic ? "الجزء" : "Juz'").append(' ').append((hizb/2) + 1);
} else {
- sb.append("Hizb ").append(hizb);
int remainder = rub3 % 4;
if (remainder == 1)
- sb.insert(0, "¼ ");
+ sb.append(arabic ? "ربع" : "¼").append(' ');
else if (remainder == 2)
- sb.insert(0, "½ ");
+ sb.append(arabic ? "نصف" : "½").append(' ');
else if (remainder == 3)
- sb.insert(0, "¾ ");
+ sb.append(arabic ? "ثلاثة أرباع" : "¾").append(' ');
+ sb.append(arabic ? "الحزب" : "Hizb").append(' ').append(hizb);
}
- Toast.makeText(mContext, sb.toString(), Toast.LENGTH_SHORT).show();
+ Toast.makeText(mContext, ArabicStyle.reshape(sb.toString()), Toast.LENGTH_SHORT).show();
lastPopupTime = System.currentTimeMillis();
}
diff --git a/src/com/quran/labs/androidquran/common/TranslationPageFeeder.java b/src/com/quran/labs/androidquran/common/TranslationPageFeeder.java
index f3b26df1b6..5f5d14c19b 100644
--- a/src/com/quran/labs/androidquran/common/TranslationPageFeeder.java
+++ b/src/com/quran/labs/androidquran/common/TranslationPageFeeder.java
@@ -61,6 +61,10 @@ protected View createPage(int index) {
tv.setTextSize(QuranSettings.getInstance().getTranslationTextSize());
updateViewForUser(v, false, false);
+
+ QuranSettings.getInstance().setLastPage(mCurrentPageNumber);
+ QuranSettings.save(mContext.prefs);
+
return v;
}
diff --git a/src/com/quran/labs/androidquran/data/ApplicationConstants.java b/src/com/quran/labs/androidquran/data/ApplicationConstants.java
index 3d19f0548c..fb2a59e211 100644
--- a/src/com/quran/labs/androidquran/data/ApplicationConstants.java
+++ b/src/com/quran/labs/androidquran/data/ApplicationConstants.java
@@ -1,7 +1,5 @@
package com.quran.labs.androidquran.data;
-
-
public class ApplicationConstants {
// activity codes
@@ -25,9 +23,6 @@ public class ApplicationConstants {
public static final int AYA_MAX = 286;
public static final int NO_PAGE_SAVED = -1;
- // Colors
- public static final String PAGE_BORDER_COLOR = "#802A2A";
-
// dialogs
public static final int JUMP_DIALOG = 1;
@@ -42,10 +37,13 @@ public class ApplicationConstants {
public static final String PREF_LOCK_ORIENTATION = "lockOrientation";
public static final String PREF_LANDSCAPE_ORIENTATION = "landscapeOrientation";
public static final String PREF_DISPLAY_MARKER_POPUP = "displayMarkerPopup";
+ public static final String PREF_AUTO_SCROLL = "autoScroll";
public static final String PREF_TRANSLATION_TEXT_SIZE = "translationTextSize";
public static final String PREF_ACTIVE_TRANSLATION = "activeTranslation";
public static final String PREF_RESHAPE_ARABIC = "reshapeArabic";
public static final String PREF_LAST_READER = "lastReader";
+ public static final String PREF_LAST_PLAYED_SURA = "lastPlayedSura";
+ public static final String PREF_LAST_PLAYED_AYAH = "lastPlayedAyah";
// Notifications
public static final int NOTIFICATION_DOWNLOAD_COMPLETED = 1;
diff --git a/src/com/quran/labs/androidquran/service/AudioServiceBinder.java b/src/com/quran/labs/androidquran/service/AudioServiceBinder.java
index 1b63629634..0cc58654b8 100644
--- a/src/com/quran/labs/androidquran/service/AudioServiceBinder.java
+++ b/src/com/quran/labs/androidquran/service/AudioServiceBinder.java
@@ -114,6 +114,7 @@ public synchronized void play(AyahItem item) {
mp.reset();
mp.setOnCompletionListener(this);
url = null;
+ // FIXME Even though soura is downloaded, Basmallah of every sura asks for download since Al-Fati7a isn't downloaded -AF
if(item.isAudioFoundLocally())
url = item.getLocalAudioUrl();
else if(remotePlayEnabled) {
@@ -126,7 +127,7 @@ else if(remotePlayEnabled) {
}
else
{
- // show notification ayah not found, download it or play remotely
+ // TODO show notification ayah not found, download it or play remotely
}
}
if(url != null){
@@ -194,8 +195,10 @@ public synchronized void onCompletion(MediaPlayer mp) {
if(repeats < numberOfRepeats){
repeats++;
play(currentItem);
- }else{
+ } else{
repeats = 0;
+ if (mp != null && mp.isPlaying())
+ mp.stop();
AyahItem nextItem = null;
if (this.currentItem != null)
nextItem = QuranAudioLibrary.getNextAyahAudioItem(context, this.currentItem);
@@ -277,8 +280,8 @@ private void showNotification(AyahItem item){
System.currentTimeMillis());
- notification.setLatestEventInfo(context,
- context.getApplicationInfo().name,
+ String name = context.getString(R.string.app_name);
+ notification.setLatestEventInfo(context, name,
item.getSoura() + " - " + QuranInfo.getSuraName(item.getSoura() -1)
+ " (" + item.getAyah() + ")", pi);
// notification.contentView = new RemoteViews("com.quran.labs.androidquran",
diff --git a/src/com/quran/labs/androidquran/service/QuranDataService.java b/src/com/quran/labs/androidquran/service/QuranDataService.java
index 2ce3e3ce01..2bc5124428 100644
--- a/src/com/quran/labs/androidquran/service/QuranDataService.java
+++ b/src/com/quran/labs/androidquran/service/QuranDataService.java
@@ -22,7 +22,9 @@
import android.content.Intent;
import android.net.ConnectivityManager;
import android.os.Binder;
+import android.os.Environment;
import android.os.IBinder;
+import android.os.StatFs;
import android.util.Log;
import com.quran.labs.androidquran.QuranActivity;
@@ -93,33 +95,35 @@ public int onStartCommand(Intent intent, int flags, int startId) {
handleStart(intent, startId);
return START_STICKY;
}
-
+
public void handleStart(Intent intent) {
- handleStart(intent, - 1);
+ handleStart(intent, -1);
}
public void handleStart(Intent intent, int startId) {
if (intent == null)
return;
-
+
int downloadType = intent.getIntExtra(DWONLOAD_TYPE_KEY, -1);
switch (downloadType) {
- case DOWNLOAD_QURAN_IMAGES:
- isRunning = true;
- thread = new DownloadThread(this, new String[] { QuranUtils.getZipFileUrl() },
- new String[] { "images.zip" }, new String[]{QuranUtils.getQuranBaseDirectory()}, true);
- thread.start();
+ case DOWNLOAD_QURAN_IMAGES:
+ isRunning = true;
+ thread = new DownloadThread(this,
+ new String[] { QuranUtils.getZipFileUrl() },
+ new String[] { "images.zip" },
+ new String[] { QuranUtils.getQuranBaseDirectory() }, true);
+ thread.start();
break;
- case DOWNLOAD_SURA_AUDIO:
- isRunning = true;
- downloadSuraAudio(intent);
+ case DOWNLOAD_SURA_AUDIO:
+ isRunning = true;
+ downloadSuraAudio(intent);
break;
- case DOWNLOAD_TRANSLATION:
- isRunning = true;
- downloadTranslation(intent);
+ case DOWNLOAD_TRANSLATION:
+ isRunning = true;
+ downloadTranslation(intent);
break;
}
- if(thread == null)
+ if (thread == null)
stopSelf();
}
@@ -132,27 +136,28 @@ private void downloadSuraAudio(Intent intent) {
// optional end ayah
int endAyah = intent.getIntExtra(END_AYAH_KEY,
QuranInfo.SURA_NUM_AYAHS[soura - 1]);
-// if (endAyah > QuranInfo.SURA_NUM_AYAHS[soura - 1])
-// endAyah = QuranInfo.SURA_NUM_AYAHS[soura - 1];
- boolean downloadImage = intent.getBooleanExtra(DOWNLOAD_AYAH_IMAGES_KEY, false);
+ // if (endAyah > QuranInfo.SURA_NUM_AYAHS[soura - 1])
+ // endAyah = QuranInfo.SURA_NUM_AYAHS[soura - 1];
+ boolean downloadImage = intent.getBooleanExtra(
+ DOWNLOAD_AYAH_IMAGES_KEY, false);
Log.d("quran_srv", "finish reading params");
-
+
ArrayList fileNames = new ArrayList();
ArrayList urls = new ArrayList();
ArrayList directories = new ArrayList();
-
+
int ayatStartIndex = startAyah;
int ayatEndIndex = endAyah;
for (int j = soura; j <= endSoura; j++) {
- if(j == soura){
+ if (j == soura) {
ayatStartIndex = startAyah;
- }else{
+ } else {
ayatStartIndex = 1;
}
- if(j == endSoura){
+ if (j == endSoura) {
ayatEndIndex = endAyah;
- }else{
+ } else {
ayatEndIndex = QuranInfo.getNumAyahs(j);
}
for (int i = ayatStartIndex; i <= ayatEndIndex; i++) {
@@ -186,8 +191,8 @@ private void downloadSuraAudio(Intent intent) {
urls.add(ayah.getRemoteImageUrl());
}
}
- }
-
+ }
+
// Check aya info db
String base = QuranUtils.getQuranDatabaseDirectory();
if (base == null)
@@ -199,10 +204,11 @@ private void downloadSuraAudio(Intent intent) {
fileNames.add("ayahinfo.db.zip");
directories.add(base);
}
-
+
if (urls.size() > 0) {
- thread = new DownloadThread(this, urls.toArray(new String[urls.size()]),
- fileNames.toArray(new String[urls.size()]), directories.toArray(new String[urls.size()]), false);
+ thread = new DownloadThread(this, urls.toArray(new String[urls
+ .size()]), fileNames.toArray(new String[urls.size()]),
+ directories.toArray(new String[urls.size()]), false);
thread.start();
} else {
isRunning = false;
@@ -212,11 +218,12 @@ private void downloadSuraAudio(Intent intent) {
private void downloadTranslation(Intent intent) {
String url = intent.getStringExtra(URL_KEY);
String fileName = intent.getStringExtra(FILE_NAME_KEY);
- thread = new DownloadThread(this, new String[] { url },
- new String[] { fileName }, new String[]{QuranUtils.getQuranDatabaseDirectory()}, false);
+ thread = new DownloadThread(this, new String[] { url },
+ new String[] { fileName },
+ new String[] { QuranUtils.getQuranDatabaseDirectory() }, false);
thread.start();
}
-
+
public void stop() {
Log.d("quran_srv", "Stop Service called");
try {
@@ -224,7 +231,7 @@ public void stop() {
thread.interrupt();
}
} catch (Exception e) {
-
+
}
progress = 0;
isRunning = false;
@@ -260,9 +267,11 @@ private class DownloadThread extends Thread {
private String[] saveToDirectories;
private boolean zipped;
private int downloadIndex;
- //private RemoteViews contentView;
- //private Notification notification;
- //private NotificationManager notificationManager;
+ private int fileLength;
+
+ // private RemoteViews contentView;
+ // private Notification notification;
+ // private NotificationManager notificationManager;
DownloadThread(QuranDataService service, String[] downloadUrls,
String[] fileNames, String[] saveToDirectories, boolean zipped) {
@@ -273,35 +282,37 @@ private class DownloadThread extends Thread {
this.zipped = zipped;
downloadIndex = 0;
}
-
+
private void onDowloadStart() {
showNotification(ApplicationConstants.NOTIFICATION_DOWNLOADING,
"Downloading..", Notification.FLAG_AUTO_CANCEL);
}
-
+
private void onDownloadPaused() {
showNotification(ApplicationConstants.NOTIFICATION_DOWNLOADING,
"Download Paused", Notification.FLAG_AUTO_CANCEL);
}
-
+
private void onDownloadCanceled() {
showNotification(ApplicationConstants.NOTIFICATION_DOWNLOADING,
"Download Canceled", Notification.FLAG_AUTO_CANCEL);
}
-
+
private void showNotification(int notificationId, String msg, int flags) {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager notificationManager = (NotificationManager) getSystemService(ns);
long when = System.currentTimeMillis();
- Notification notification = new Notification(R.drawable.icon, msg, when);
+ Notification notification = new Notification(R.drawable.icon, msg,
+ when);
notification.defaults |= flags;
Context context = getApplicationContext();
CharSequence contentTitle = "Quran Android";
CharSequence contentText = msg;
Intent notificationIntent = new Intent(context, QuranActivity.class);
- notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+ notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
@@ -326,52 +337,62 @@ private boolean resumeDownload() {
f.mkdirs();
File file = new File(saveToDirectories[downloadIndex],
fileNames[downloadIndex] + DOWNLOAD_EXT);
-
URL url = new URL(downloadUrls[downloadIndex]);
URLConnection conn = url.openConnection();
- int total = conn.getContentLength();
+ fileLength = conn.getContentLength();
+ if(!isSpaceAvailable()){
+ Log.e("quran_srv", "Not enough space on SD card");
+ return false;
+ }
Log.d("quran_srv", "File to download: " + file.getName()
- + " - total length: " + total);
+ + " - total length: " + fileLength);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
if (file.exists()) {
downloaded = (int) file.length();
- connection.setRequestProperty("Range", "bytes="
- + (file.length()) + "-");
+ connection.setRequestProperty("Range",
+ "bytes=" + (file.length()) + "-");
Log.d("quran_srv", "Resuming from " + downloaded);
- if (downloaded == total)
+ if (downloaded == fileLength)
continue;
}
connection.setRequestProperty("Range", "bytes="
+ downloaded + "-");
connection.setDoInput(true);
- in = new BufferedInputStream(connection.getInputStream(), DOWNLOAD_BUFFER_SIZE);
- fos = (downloaded == 0) ? new FileOutputStream(file
- .getAbsolutePath()) : new FileOutputStream(file
- .getAbsolutePath(), true);
+ in = new BufferedInputStream(connection.getInputStream(),
+ DOWNLOAD_BUFFER_SIZE);
+ fos = (downloaded == 0) ? new FileOutputStream(
+ file.getAbsolutePath()) : new FileOutputStream(
+ file.getAbsolutePath(), true);
bout = new BufferedOutputStream(fos, DOWNLOAD_BUFFER_SIZE);
byte[] data = new byte[DOWNLOAD_BUFFER_SIZE];
int x = 0;
- while (isRunning && (x = in.read(data, 0, DOWNLOAD_BUFFER_SIZE)) >= 0) {
+ while (isRunning
+ && (x = in.read(data, 0, DOWNLOAD_BUFFER_SIZE)) >= 0) {
bout.write(data, 0, x);
downloaded += x;
- double percent = 100.0 * ((1.0 * downloaded) / (1.0 * total));
- updateProgress((int) percent, fileNames.length, downloadIndex);
+ double percent = 100.0 * ((1.0 * downloaded) / (1.0 * fileLength));
+ updateProgress((int) percent, fileNames.length,
+ downloadIndex);
}
bout.flush();
bout.close();
fos.close();
-
+
if (isRunning) {
- file.renameTo(new File(saveToDirectories[downloadIndex], fileNames[downloadIndex]));
-
+ file.renameTo(new File(
+ saveToDirectories[downloadIndex],
+ fileNames[downloadIndex]));
+
if (zipped || fileNames[downloadIndex].endsWith(".zip"))
- unzipFile(saveToDirectories[downloadIndex], fileNames[downloadIndex]);
-
- Log.d("quran_srv", "Download Completed [" + downloadUrls[downloadIndex] + "]");
- } else
+ unzipFile(saveToDirectories[downloadIndex],
+ fileNames[downloadIndex]);
+
+ Log.d("quran_srv", "Download Completed ["
+ + downloadUrls[downloadIndex] + "]");
+ } else
return false;
}
} catch (FileNotFoundException e) {
@@ -386,15 +407,26 @@ private boolean resumeDownload() {
return true;
}
+
+ private boolean isSpaceAvailable(){
+ StatFs fsStats = new StatFs(Environment.getExternalStorageDirectory().getAbsolutePath());
+ double availableSpace = (double)fsStats.getAvailableBlocks() * (double)fsStats.getBlockSize();
+ return availableSpace > fileLength;
+ }
- private void updateProgress(int percent, int totalFiles, int nDownloadedFiles) {
- percent = (int) (((double)percent / (double)100 + (double)nDownloadedFiles) / (double)totalFiles * 100);
+ private void updateProgress(int percent, int totalFiles,
+ int nDownloadedFiles) {
+ percent = (int) (((double) percent / (double) 100 + (double) nDownloadedFiles)
+ / (double) totalFiles * 100);
service.updateProgress(percent);
-// notification.contentView.setTextViewText(R.id.text, "Downloading.. " + percent + "%");
-// notification.contentView.setProgressBar(R.id.progressBar, 100, percent, false);
-//
-// //notify the notification manager on the update.
-// notificationManager.notify(ApplicationConstants.NOTIFICATION_DOWNLOADING, notification);
+ // notification.contentView.setTextViewText(R.id.text,
+ // "Downloading.. " + percent + "%");
+ // notification.contentView.setProgressBar(R.id.progressBar, 100,
+ // percent, false);
+ //
+ // //notify the notification manager on the update.
+ // notificationManager.notify(ApplicationConstants.NOTIFICATION_DOWNLOADING,
+ // notification);
}
@Override
@@ -414,13 +446,14 @@ public void run() {
}
try {
onDownloadPaused();
- Log.d("quran_srv", "Disconnected.. Retring after " + WAIT_TIME + " seconds");
+ Log.d("quran_srv", "Disconnected.. Retring after "
+ + WAIT_TIME + " seconds");
sleep(WAIT_TIME * 1000);
} catch (InterruptedException e) {
-
+
}
}
- } catch(Exception e) {
+ } catch (Exception e) {
Log.e("quran_srv", "Error", e);
}
thread = null;
@@ -428,7 +461,8 @@ public void run() {
protected void unzipFile(String saveToDirectory, String fileName) {
try {
- Log.d("quran_srv", "Unziping file: " + saveToDirectory + fileName);
+ Log.d("quran_srv", "Unziping file: " + saveToDirectory
+ + fileName);
// success, unzip the file...
File file = new File(saveToDirectory, fileName);
FileInputStream is = new FileInputStream(file);
@@ -468,13 +502,15 @@ protected void unzipFile(String saveToDirectory, String fileName) {
private void onDownloadComplete() {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager notificationManager = (NotificationManager) getSystemService(ns);
- notificationManager.cancel(ApplicationConstants.NOTIFICATION_DOWNLOADING);
-
- showNotification(ApplicationConstants.NOTIFICATION_DOWNLOAD_COMPLETED,
- "Download Completed",
- Notification.DEFAULT_SOUND | Notification.FLAG_AUTO_CANCEL |
- Notification.DEFAULT_LIGHTS);
-
+ notificationManager
+ .cancel(ApplicationConstants.NOTIFICATION_DOWNLOADING);
+
+ showNotification(
+ ApplicationConstants.NOTIFICATION_DOWNLOAD_COMPLETED,
+ "Download Completed", Notification.DEFAULT_SOUND
+ | Notification.FLAG_AUTO_CANCEL
+ | Notification.DEFAULT_LIGHTS);
+
service.stopSelf();
isRunning = false;
}
diff --git a/src/com/quran/labs/androidquran/util/QuranScreenInfo.java b/src/com/quran/labs/androidquran/util/QuranScreenInfo.java
index 1086bbbfbc..da998c8cc7 100644
--- a/src/com/quran/labs/androidquran/util/QuranScreenInfo.java
+++ b/src/com/quran/labs/androidquran/util/QuranScreenInfo.java
@@ -48,4 +48,10 @@ public boolean isLandscapeOrientation() {
public void setOrientation(int orientation) {
this.orientation = orientation;
}
+
+ public float getRatio() {
+ if (height > width)
+ return (float)(1.0*height/width);
+ return (float)(1.0*width/height);
+ }
}
diff --git a/src/com/quran/labs/androidquran/util/QuranSettings.java b/src/com/quran/labs/androidquran/util/QuranSettings.java
index 0878079878..7f841e482d 100644
--- a/src/com/quran/labs/androidquran/util/QuranSettings.java
+++ b/src/com/quran/labs/androidquran/util/QuranSettings.java
@@ -13,12 +13,15 @@ public class QuranSettings {
private boolean keepScreenOn = false;
private boolean lockOrientation = false;
private boolean landscapeOrientation = false;
- private boolean displayMarkerPopup = false;
+ private boolean displayMarkerPopup = true;
+ private boolean autoScroll = true;
private int translationTextSize = ApplicationConstants.DEFAULT_TEXT_SIZE;
private int lastPage = 0;
private String activeTranslation = null;
private boolean reshapeArabic = false;
private int lastReader = 0;
+ private int lastPlayedSura = 1;
+ private int lastPlayedAyah = 1;
private QuranSettings() {
@@ -32,6 +35,19 @@ public void setLastReader(int lastReader) {
this.lastReader = lastReader;
}
+ public int getLastPlayedSura() {
+ return lastPlayedSura;
+ }
+
+ public int getLastPlayedAyah() {
+ return lastPlayedAyah;
+ }
+
+ public void setLastPlayedAyah(int sura, int ayah) {
+ this.lastPlayedSura = sura;
+ this.lastPlayedAyah = ayah;
+ }
+
public Integer getLastPage() {
return lastPage;
}
@@ -84,6 +100,14 @@ public void setMarkerPopup(boolean displayMarkerPopup) {
this.displayMarkerPopup = displayMarkerPopup;
}
+ public boolean isAutoScroll() {
+ return autoScroll;
+ }
+
+ public void setAutoScroll(boolean autoScroll) {
+ this.autoScroll = autoScroll;
+ }
+
public int getTranslationTextSize() {
return translationTextSize;
}
@@ -109,12 +133,15 @@ public static void load(SharedPreferences preferences) {
instance.keepScreenOn = preferences.getBoolean(ApplicationConstants.PREF_KEEP_SCREEN_ON, true);
instance.lockOrientation = preferences.getBoolean(ApplicationConstants.PREF_LOCK_ORIENTATION, false);
instance.landscapeOrientation = preferences.getBoolean(ApplicationConstants.PREF_LANDSCAPE_ORIENTATION, false);
- instance.displayMarkerPopup = preferences.getBoolean(ApplicationConstants.PREF_DISPLAY_MARKER_POPUP, false);
+ instance.displayMarkerPopup = preferences.getBoolean(ApplicationConstants.PREF_DISPLAY_MARKER_POPUP, true);
+ instance.autoScroll = preferences.getBoolean(ApplicationConstants.PREF_AUTO_SCROLL, true);
instance.translationTextSize = preferences.getInt(ApplicationConstants.PREF_TRANSLATION_TEXT_SIZE, ApplicationConstants.DEFAULT_TEXT_SIZE);
instance.lastPage = preferences.getInt(ApplicationConstants.PREF_LAST_PAGE, ApplicationConstants.NO_PAGE_SAVED);
instance.activeTranslation = preferences.getString(ApplicationConstants.PREF_ACTIVE_TRANSLATION, null);
instance.reshapeArabic = preferences.getBoolean(ApplicationConstants.PREF_RESHAPE_ARABIC, false);
instance.lastReader = preferences.getInt(ApplicationConstants.PREF_LAST_READER, 0);
+ instance.lastPlayedSura = preferences.getInt(ApplicationConstants.PREF_LAST_PLAYED_SURA, 0);
+ instance.lastPlayedAyah = preferences.getInt(ApplicationConstants.PREF_LAST_PLAYED_AYAH, 0);
}
public static void save(SharedPreferences preferences) {
@@ -124,11 +151,14 @@ public static void save(SharedPreferences preferences) {
editor.putBoolean(ApplicationConstants.PREF_LOCK_ORIENTATION, instance.lockOrientation);
editor.putBoolean(ApplicationConstants.PREF_LANDSCAPE_ORIENTATION, instance.landscapeOrientation);
editor.putBoolean(ApplicationConstants.PREF_DISPLAY_MARKER_POPUP, instance.displayMarkerPopup);
+ editor.putBoolean(ApplicationConstants.PREF_AUTO_SCROLL, instance.autoScroll);
editor.putInt(ApplicationConstants.PREF_TRANSLATION_TEXT_SIZE, instance.translationTextSize);
editor.putInt(ApplicationConstants.PREF_LAST_PAGE, instance.lastPage);
editor.putString(ApplicationConstants.PREF_ACTIVE_TRANSLATION, instance.activeTranslation);
editor.putBoolean(ApplicationConstants.PREF_RESHAPE_ARABIC, instance.reshapeArabic);
editor.putInt(ApplicationConstants.PREF_LAST_READER, instance.lastReader);
+ editor.putInt(ApplicationConstants.PREF_LAST_PLAYED_SURA, instance.lastPlayedSura);
+ editor.putInt(ApplicationConstants.PREF_LAST_PLAYED_AYAH, instance.lastPlayedAyah);
editor.commit();
}
}
diff --git a/src/com/quran/labs/androidquran/util/QuranUtils.java b/src/com/quran/labs/androidquran/util/QuranUtils.java
index b73ea03542..ea6c92fdb0 100644
--- a/src/com/quran/labs/androidquran/util/QuranUtils.java
+++ b/src/com/quran/labs/androidquran/util/QuranUtils.java
@@ -2,7 +2,6 @@
import java.io.File;
import java.io.FileOutputStream;
-import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@@ -287,34 +286,11 @@ public static String getSuraAudioPath(int quranReaderId, int sura){
return getAudioDirectory() + File.separator + quranReaderId
+ File.separator + sura ;
}
-
- public static int isSouraAudioFound(int quranReaderId, int sura){
- File f = new File(getSuraAudioPath(quranReaderId, sura));
- if(f.exists() && f.isDirectory()){
- String[] filesNames = f.list(new FilenameFilter() {
-
- @Override
- public boolean accept(File dir, String filename) {
- try{
- if(filename.endsWith(QuranAudioLibrary.AUDIO_EXTENSION)){
- filename = filename.substring(0, filename.indexOf(QuranAudioLibrary.AUDIO_EXTENSION));
- Integer.parseInt(filename);
- return true;
- }return false;
- }catch (Exception e) {
- return false;
- }
- }
- });
- if(filesNames != null)
- return filesNames.length;
- }
- return -1;
-
- }
+
public static String getSuraImagePath(int sura){
return getAyahImagesDirectory() + File.separator + sura;
}
+
public static String getAyahImagePath(AyahItem ayahItem) {
return getAyahImagePath(ayahItem.getSoura(), ayahItem
.getAyah());
diff --git a/src/com/quran/labs/androidquran/widgets/HighlightingImageView.java b/src/com/quran/labs/androidquran/widgets/HighlightingImageView.java
index 89dbb92801..e7bc7d945d 100644
--- a/src/com/quran/labs/androidquran/widgets/HighlightingImageView.java
+++ b/src/com/quran/labs/androidquran/widgets/HighlightingImageView.java
@@ -19,6 +19,7 @@
import com.quran.labs.androidquran.R;
import com.quran.labs.androidquran.common.AyahBounds;
import com.quran.labs.androidquran.data.AyahInfoDatabaseHandler;
+import com.quran.labs.androidquran.util.QuranScreenInfo;
public class HighlightingImageView extends ImageView {
private List currentlyHighlighting = null;
@@ -110,24 +111,58 @@ private void doHighlightAyah(AyahBounds first,
this.currentlyHighlighting = rangesToDraw;
}
+ public AyahBounds getYBoundsForCurrentHighlight() {
+ if (currentlyHighlighting == null)
+ return null;
+ Integer upperBound = null;
+ Integer lowerBound = null;
+ for (AyahBounds bounds : currentlyHighlighting) {
+ if (upperBound == null || bounds.getMinY() < upperBound)
+ upperBound = bounds.getMinY();
+ if (lowerBound == null || bounds.getMaxY() > lowerBound)
+ lowerBound = bounds.getMaxY();
+ }
+ AyahBounds yBounds = null;
+ if (upperBound != null && lowerBound != null)
+ yBounds = new AyahBounds(0, 0, 0, upperBound, 0, lowerBound);
+ return yBounds;
+ }
+
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (this.currentlyHighlighting != null){
- for (AyahBounds b : currentlyHighlighting){
+ Drawable page = this.getDrawable();
+ if (page != null){
Bitmap bm = BitmapFactory.decodeResource(
- getResources(), R.drawable.highlight);
+ getResources(), R.drawable.highlight);
+
+ float screenRatio = QuranScreenInfo.getInstance().getRatio();
+ float pageRatio = (float) (1.0* page.getIntrinsicHeight()/page.getIntrinsicWidth());
- Drawable page = this.getDrawable();
- if (page != null){
- float widthFactor = (float)((1.0 * getWidth()) /
- (1.0 * page.getIntrinsicWidth()));
- float heightFactor = (float)((1.0 * getHeight()) /
- (1.0 * page.getIntrinsicHeight()));
+ float scaledPageHeight;
+ float scaledPageWidth;
+ // depending on whether or not you will have a top or bottom offset
+ if (screenRatio < pageRatio){
+ scaledPageHeight = getHeight();
+ scaledPageWidth = (float) (1.0*getHeight()/page.getIntrinsicHeight()*page.getIntrinsicWidth());
+ } else {
+ scaledPageWidth = getWidth();
+ scaledPageHeight = (float)(1.0*getWidth()/page.getIntrinsicWidth()*page.getIntrinsicHeight());
+ }
+
+ float widthFactor = scaledPageWidth / page.getIntrinsicWidth();
+ float heightFactor = scaledPageHeight / page.getIntrinsicHeight();
+
+ float offsetX = (getWidth() - scaledPageWidth)/2;
+ float offsetY = (getHeight() - scaledPageHeight)/2;
+
+ for (AyahBounds b : currentlyHighlighting){
RectF scaled = new RectF(b.getMinX() * widthFactor,
b.getMinY() * heightFactor, b.getMaxX() * widthFactor,
b.getMaxY() * heightFactor);
+ scaled.offset(offsetX, offsetY);
canvas.drawBitmap(bm, null, scaled, null);
}
}
diff --git a/src/com/quran/labs/androidquran/widgets/QuranPageCurlView.java b/src/com/quran/labs/androidquran/widgets/QuranPageCurlView.java
index eb027d84b0..94329cbf23 100644
--- a/src/com/quran/labs/androidquran/widgets/QuranPageCurlView.java
+++ b/src/com/quran/labs/androidquran/widgets/QuranPageCurlView.java
@@ -21,6 +21,8 @@
import android.widget.ScrollView;
import com.quran.labs.androidquran.R;
+import com.quran.labs.androidquran.common.AyahBounds;
+import com.quran.labs.androidquran.util.QuranScreenInfo;
/*
* Adapted and modified from http://code.google.com/p/android-page-curl
@@ -529,6 +531,33 @@ public void scrollPage(int scrollerId, int direction) {
}
}
+ public void scrollToAyah(int scrollerId, AyahBounds yBounds) {
+ ScrollView sv = (ScrollView) mCurrentPageView.findViewById(scrollerId);
+ if (sv == null || yBounds == null)
+ return;
+
+ int screenHeight = QuranScreenInfo.getInstance().getHeight();
+ int curScrollY = sv.getScrollY();
+ int scrollToY = curScrollY;
+
+ // If Ayah is within bounds, do nothing
+ if (yBounds.getMinY() > curScrollY && yBounds.getMaxY() < curScrollY + screenHeight)
+ return;
+
+ int ayahHeight = yBounds.getMaxY() - yBounds.getMinY();
+
+ // If entire ayah can fit in screen, center it vertically. Otherwise, scroll to top of Ayah.
+ if (ayahHeight < screenHeight)
+ scrollToY = yBounds.getMinY() - (screenHeight - ayahHeight)/2;
+ else
+ scrollToY = yBounds.getMinY() - (int) (screenHeight*0.05); // Leave a gap of 5% screen height
+
+ sv.smoothScrollTo(sv.getScrollX(), scrollToY);
+ mScrollAnimationHandler.setUpdateRate(mUpdateRate);
+ mScrollAnimationHandler.setCount(20);
+ mScrollAnimationHandler.sleep();
+ }
+
/**
* Reset points to it's initial clip edge state
*/
@@ -866,17 +895,20 @@ public boolean onTouchEvent(MotionEvent event) {
if ((event.getAction() == MotionEvent.ACTION_UP) &&
((event.getEventTime() - event.getDownTime()) <= FINGER_CLICK_TIME_MAX) &&
!dispatchDecisionTaken) {
- float xPos = event.getX();
+ //float xPos = event.getX();
/*
* Only perform click if the tap was in the center of the screen.
* Otherwise, just perform the ACTION_UP as normal which should
* flip the page depending which side of the screen the tap was on
+ *
+ * update 9/4/2011 - removed this behavior because it was confusing
+ * and made it always click on touch.
*/
- if ((xPos > width/4) && (xPos < width*3/4)){
+ //if ((xPos > width/4) && (xPos < width*3/4)){
event.setAction(MotionEvent.ACTION_CANCEL);
performClick();
- }
+ //}
}