Merge pull request #43 from kiwix/searchWidget

Kiwix - Search widget added
This commit is contained in:
Elad Keyshawn 2016-06-01 11:26:20 +03:00
commit 128634e22e
37 changed files with 433 additions and 84 deletions

View File

@ -99,7 +99,7 @@
</activity> </activity>
<activity android:name=".settings.KiwixSettingsActivity" /> <activity android:name=".settings.KiwixSettingsActivity" />
<activity android:name=".SearchActivity" /> <activity android:name=".SearchActivity" />
<activity android:name=".views.BookmarksActivity" /> <activity android:name=".BookmarksActivity" />
<provider <provider
@ -107,6 +107,18 @@
android:authorities="org.kiwix.zim.base" android:authorities="org.kiwix.zim.base"
android:exported="true" /> android:exported="true" />
<receiver android:name=".utils.KiwixSearchWidget" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="org.kiwix.kiwixmobile.utils.KiwixSearchWidget.TEXT_CLICKED"/>
<action android:name="org.kiwix.kiwixmobile.utils.KiwixSearchWidget.ICON_CLICKED"/>
<action android:name="org.kiwix.kiwixmobile.utils.KiwixSearchWidget.MIC_CLICKED"/>
<action android:name="org.kiwix.kiwixmobile.utils.KiwixSearchWidget.STAR_CLICKED"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/kiwix_widget_provider_info" />
</receiver>
</application> </application>

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 659 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 951 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white"/>
<corners android:radius="3dip"/>
<padding android:left="0dip" android:top="0dip" android:right="0dip" android:bottom="0dip" />
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="50dp"
android:id="@+id/kiwix_search_widget_layout_id"
android:background="@drawable/search_widget_background"
android:padding="@dimen/widget_margin"
android:gravity="center_vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/search_widget_icon"
android:src="@drawable/ic_widget_kiwix"
android:layout_weight="0.1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/search_widget_text"
android:textColor="@color/grey"
android:id="@+id/search_widget_text"
android:layout_weight="0.7"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/search_widget_star"
android:src="@drawable/ic_stars_black_24dp"
android:layout_weight="0.1"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/search_widget_mic"
android:src="@drawable/ic_mic_black_24dp"
android:layout_weight="0.1"/>
</LinearLayout>

View File

@ -9,11 +9,12 @@
<color name="secondary_text">#727272</color> <color name="secondary_text">#727272</color>
<color name="icons">#212121</color> <color name="icons">#212121</color>
<color name="divider">#B6B6B6</color> <color name="divider">#B6B6B6</color>
<color name="white_undo">#FAFAFA</color> <color name="white">#FAFAFA</color>
<color name="gray_list_bg">#0d000000</color> <color name="gray_list_bg">#0d000000</color>
<color name="drawer_background">#ffffff</color> <color name="drawer_background">#ffffff</color>
<color name="selected_light">#0F000000</color> <color name="selected_light">#0F000000</color>
<color name="divider_light">#1E000000</color> <color name="divider_light">#1E000000</color>
<color name="greyed_out_selected">#BDBDBD</color> <color name="greyed_out_selected">#BDBDBD</color>
<color name="black_regular_mat_design">#212121</color> <color name="black_regular_mat_design">#212121</color>
<color name="grey">#808080</color>
</resources> </resources>

View File

@ -6,5 +6,6 @@
<dimen name="dimen_small_padding">4dp</dimen> <dimen name="dimen_small_padding">4dp</dimen>
<dimen name="dimen_medium_padding">8dp</dimen> <dimen name="dimen_medium_padding">8dp</dimen>
<dimen name="navigation_width">260dp</dimen> <dimen name="navigation_width">260dp</dimen>
<dimen name="widget_margin">0dp</dimen>
</resources> </resources>

View File

@ -51,7 +51,7 @@
<string name="pref_language_chooser">Choose a language</string> <string name="pref_language_chooser">Choose a language</string>
<string name="tts_lang_not_supported">The language of this page is not supported, or appropriate language data was not installed. The article may not be properly read.</string> <string name="tts_lang_not_supported">The language of this page is not supported, or appropriate language data was not installed. The article may not be properly read.</string>
<string name="no_reader_application_installed">Could not find an installed application for this type of file</string> <string name="no_reader_application_installed">Could not find an installed application for this type of file</string>
<string name="customapp_missing_content">Your application is corrupted.\nThis might happen when you remove files on the SD Card.\nYou need to uninstall then reinstall the App from the Play Store.</string> <string name="custom_app_missing_content">Your application is corrupted.\nThis might happen when you remove files on the SD Card.\nYou need to uninstall then reinstall the App from the Play Store.</string>
<string name="go_to_play_store">Go to Play Store</string> <string name="go_to_play_store">Go to Play Store</string>
<string name="no_bookmarks">No Bookmarks</string> <string name="no_bookmarks">No Bookmarks</string>
<string name="menu_bookmarks_list">Bookmarks</string> <string name="menu_bookmarks_list">Bookmarks</string>
@ -59,7 +59,7 @@
<string name="request_storage">To access zim files we need access to your storage</string> <string name="request_storage">To access zim files we need access to your storage</string>
<string name="clear_recent_history_dialog">Are you sure you want to delete your search history?</string> <string name="clear_recent_history_dialog">Are you sure you want to delete your search history?</string>
<string name="clear_recent_and_tabs_history_dialog">Are you sure you want to delete your search history and reset all active tabs?</string> <string name="clear_recent_and_tabs_history_dialog">Are you sure you want to delete your search history and reset all active tabs?</string>
<string name="deleteRecentSearchItem">Delete this item?</string> <string name="delete_recent_search_item">Delete this item?</string>
<string name="pref_clear_all_history_title">Clear History</string> <string name="pref_clear_all_history_title">Clear History</string>
<string name="pref_clear_all_history_summary">Clear recent searches and tabs history</string> <string name="pref_clear_all_history_summary">Clear recent searches and tabs history</string>
<string name="all_history_cleared_toast">All History Cleared</string> <string name="all_history_cleared_toast">All History Cleared</string>
@ -71,7 +71,7 @@
<string name="did_you_know">Did you know?</string> <string name="did_you_know">Did you know?</string>
<string name="undo">Undo</string> <string name="undo">Undo</string>
<string name="tab_closed">Tab closed</string> <string name="tab_closed">Tab closed</string>
<string name="deleted_message">Deleted</string> <string name="deleted_message">deleted</string>
<string name="bookmarks_restored">Bookmarks restored</string> <string name="bookmarks_restored">Bookmarks restored</string>
<string name="bookmark_added">Bookmark added</string> <string name="bookmark_added">Bookmark added</string>
<string name="rate_dialog_title">Please Rate Us</string> <string name="rate_dialog_title">Please Rate Us</string>
@ -85,5 +85,8 @@
<string name="pref_newtab_background_title">Open new tab in background</string> <string name="pref_newtab_background_title">Open new tab in background</string>
<string name="pref_newtab_background_summary">When opening a new tab it will open in background</string> <string name="pref_newtab_background_summary">When opening a new tab it will open in background</string>
<string name="pref_extras">Extras</string> <string name="pref_extras">Extras</string>
<string name="new_tab_snackbar">Link opened in new tab</string> <string name="new_tab_snackbar">Article opened in new tab</string>
<string name="search_widget_text">Search Kiwix</string>
<string name="speech_prompt_text">Speak to search Kiwix</string>
<string name="speech_not_supported">Sorry! Your device doesn\\\'t support speech input</string>
</resources> </resources>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="250dp"
android:minHeight="40dp"
android:minResizeWidth="250dp"
android:minResizeHeight="40dp"
android:updatePeriodMillis="86400000"
android:previewImage="@drawable/search_widget_preview"
android:initialLayout="@layout/kiwix_search_widget"
android:resizeMode="horizontal|vertical">
</appwidget-provider>

View File

@ -1,4 +1,24 @@
package org.kiwix.kiwixmobile.views; /*
* Copyright 2013 Elad Keyshawn <elad.keyshawn@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.kiwix.kiwixmobile;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
@ -20,6 +40,7 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import org.kiwix.kiwixmobile.R; import org.kiwix.kiwixmobile.R;
import org.kiwix.kiwixmobile.utils.HelperClasses.ShortcutUtils;
import java.util.ArrayList; import java.util.ArrayList;
@ -42,14 +63,16 @@ public class BookmarksActivity extends AppCompatActivity
setContentView(R.layout.activity_bookmarks); setContentView(R.layout.activity_bookmarks);
setUpToolbar(); setUpToolbar();
snackbarLayout = (LinearLayout) findViewById(R.id.bookmarks_activity_layout); snackbarLayout = (LinearLayout) findViewById(R.id.bookmarks_activity_layout);
contents = getIntent().getStringArrayListExtra("bookmark_contents"); selected = new ArrayList<>();
selected = new ArrayList<>(); bookmarksList = (ListView) findViewById(R.id.bookmarks_list);
bookmarksList = (ListView) findViewById(R.id.bookmarks_list); noBookmarksTextView = (TextView) findViewById(R.id.bookmarks_list_nobookmarks);
noBookmarksTextView = (TextView) findViewById(R.id.bookmarks_list_nobookmarks);
adapter = new ArrayAdapter(getApplicationContext(), R.layout.bookmarks_row, R.id.bookmark_title,
contents);
bookmarksList.setAdapter(adapter);
if(getIntent().getStringArrayListExtra("bookmark_contents") != null) {
contents = getIntent().getStringArrayListExtra("bookmark_contents");
adapter = new ArrayAdapter(getApplicationContext(), R.layout.bookmarks_row, R.id.bookmark_title,
contents);
bookmarksList.setAdapter(adapter);
}
setNoBookmarksState(); setNoBookmarksState();
bookmarksList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL); bookmarksList.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL);
@ -117,19 +140,19 @@ public class BookmarksActivity extends AppCompatActivity
private void popDeleteBookmarksSnackbar() { private void popDeleteBookmarksSnackbar() {
Snackbar bookmarkDeleteSnackbar = Snackbar bookmarkDeleteSnackbar =
Snackbar.make(snackbarLayout, numOfSelected + " " + stringsGetter(R.string.deleted_message), Snackbar.LENGTH_LONG) Snackbar.make(snackbarLayout, numOfSelected + " " + ShortcutUtils.stringsGetter(R.string.deleted_message,this), Snackbar.LENGTH_LONG)
.setAction(stringsGetter(R.string.undo), new View.OnClickListener() { .setAction(ShortcutUtils.stringsGetter(R.string.undo,this), new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
contents.clear(); contents.clear();
contents.addAll(tempContents); contents.addAll(tempContents);
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
setNoBookmarksState(); setNoBookmarksState();
Toast.makeText(getApplicationContext(), stringsGetter(R.string.bookmarks_restored), Toast.LENGTH_SHORT) Toast.makeText(getApplicationContext(), ShortcutUtils.stringsGetter(R.string.bookmarks_restored,getBaseContext()), Toast.LENGTH_SHORT)
.show(); .show();
} }
}); });
bookmarkDeleteSnackbar.setActionTextColor(getResources().getColor(R.color.white_undo)); bookmarkDeleteSnackbar.setActionTextColor(getResources().getColor(R.color.white));
bookmarkDeleteSnackbar.show(); bookmarkDeleteSnackbar.show();
} }
@ -145,7 +168,7 @@ public class BookmarksActivity extends AppCompatActivity
private void setUpToolbar() { private void setUpToolbar() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle(stringsGetter(R.string.menu_bookmarks_list)); toolbar.setTitle(ShortcutUtils.stringsGetter(R.string.menu_bookmarks_list,this));
setSupportActionBar(toolbar); setSupportActionBar(toolbar);
getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
@ -181,7 +204,4 @@ public class BookmarksActivity extends AppCompatActivity
super.onBackPressed(); super.onBackPressed();
} }
public String stringsGetter(int strId) {
return getResources().getString(strId);
}
} }

View File

@ -82,14 +82,14 @@ import android.widget.Toast;
import org.json.JSONArray; import org.json.JSONArray;
import org.kiwix.kiwixmobile.settings.Constants; import org.kiwix.kiwixmobile.settings.Constants;
import org.kiwix.kiwixmobile.settings.KiwixSettingsActivity; import org.kiwix.kiwixmobile.settings.KiwixSettingsActivity;
import org.kiwix.kiwixmobile.utils.HTMLUtils; import org.kiwix.kiwixmobile.utils.HelperClasses.HTMLUtils;
import org.kiwix.kiwixmobile.utils.HelperClasses.LanguageUtils;
import org.kiwix.kiwixmobile.utils.HelperClasses.ShortcutUtils;
import org.kiwix.kiwixmobile.utils.KiwixTextToSpeech; import org.kiwix.kiwixmobile.utils.KiwixTextToSpeech;
import org.kiwix.kiwixmobile.utils.LanguageUtils; import org.kiwix.kiwixmobile.utils.RateAppCounter;
import org.kiwix.kiwixmobile.utils.files.FileReader; import org.kiwix.kiwixmobile.utils.files.FileReader;
import org.kiwix.kiwixmobile.utils.files.FileUtils; import org.kiwix.kiwixmobile.utils.files.FileUtils;
import org.kiwix.kiwixmobile.utils.files.RateAppCounter;
import org.kiwix.kiwixmobile.views.AnimatedProgressBar; import org.kiwix.kiwixmobile.views.AnimatedProgressBar;
import org.kiwix.kiwixmobile.views.BookmarksActivity;
import org.kiwix.kiwixmobile.views.CompatFindActionModeCallback; import org.kiwix.kiwixmobile.views.CompatFindActionModeCallback;
import org.kiwix.kiwixmobile.views.KiwixWebView; import org.kiwix.kiwixmobile.views.KiwixWebView;
@ -306,6 +306,14 @@ public class KiwixMobileActivity extends AppCompatActivity {
mProgressBar = (AnimatedProgressBar) findViewById(R.id.progress_view); mProgressBar = (AnimatedProgressBar) findViewById(R.id.progress_view);
exitFullscreenButton = (ImageButton) findViewById(R.id.FullscreenControlButton); exitFullscreenButton = (ImageButton) findViewById(R.id.FullscreenControlButton);
boolean IS_WIDGET_SEARCH_INTENT;
boolean IS_WIDGET_VOICE_SEARCH;
boolean IS_WIDGET_STAR;
IS_WIDGET_SEARCH_INTENT = getIntent().getBooleanExtra("isWidgetSearch", false);
IS_WIDGET_VOICE_SEARCH = getIntent().getBooleanExtra("isWidgetVoice", false);
IS_WIDGET_STAR = getIntent().getBooleanExtra("isWidgetStar", false);
tempForUndo = tempForUndo =
new KiwixWebView(getApplicationContext()); /** initializing temporary tab value **/ new KiwixWebView(getApplicationContext()); /** initializing temporary tab value **/
snackbarLayout = snackbarLayout =
@ -444,18 +452,35 @@ public class KiwixMobileActivity extends AppCompatActivity {
setUpExitFullscreenButton(); setUpExitFullscreenButton();
loadPrefs(); loadPrefs();
updateTitle(ZimContentProvider.getZimFileTitle()); updateTitle(ZimContentProvider.getZimFileTitle());
if (IS_WIDGET_STAR) {
goToBookmarks();
} else if (IS_WIDGET_SEARCH_INTENT) {
goToSearch(false);
} else if (IS_WIDGET_VOICE_SEARCH) {
goToSearch(true);
}
}
private void goToSearch(boolean isVoice) {
final String zimFile = ZimContentProvider.getZimFile();
Intent i = new Intent(KiwixMobileActivity.this, SearchActivity.class);
i.putExtra("zimFile", zimFile);
if (isVoice) {
i.putExtra("isWidgetVoice", true);
}
startActivityForResult(i, REQUEST_FILE_SEARCH);
} }
public void showRateDialog(final Context mContext, final SharedPreferences.Editor editor) { public void showRateDialog(final Context mContext, final SharedPreferences.Editor editor) {
AlertDialog alertDialog = new AlertDialog.Builder(mContext).create(); AlertDialog alertDialog = new AlertDialog.Builder(mContext).create();
alertDialog.setTitle(stringsGetter(R.string.rate_dialog_title)); alertDialog.setTitle(ShortcutUtils.stringsGetter(R.string.rate_dialog_title, this));
alertDialog.setMessage(stringsGetter(R.string.rate_dialog_msg_1) + " " alertDialog.setMessage(ShortcutUtils.stringsGetter(R.string.rate_dialog_msg_1, this) + " "
+ getString(R.string.app_name) + getString(R.string.app_name)
+ stringsGetter(R.string.rate_dialog_msg_2)); + ShortcutUtils.stringsGetter(R.string.rate_dialog_msg_2, this));
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, stringsGetter(R.string.rate_dialog_positive), alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, ShortcutUtils.stringsGetter(R.string.rate_dialog_positive, this),
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
@ -464,7 +489,7 @@ public class KiwixMobileActivity extends AppCompatActivity {
} }
}); });
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, stringsGetter(R.string.rate_dialog_negative), alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, ShortcutUtils.stringsGetter(R.string.rate_dialog_negative, this),
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
@ -473,7 +498,7 @@ public class KiwixMobileActivity extends AppCompatActivity {
} }
}); });
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, stringsGetter(R.string.rate_dialog_neutral), alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, ShortcutUtils.stringsGetter(R.string.rate_dialog_neutral, this),
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
@ -488,10 +513,6 @@ public class KiwixMobileActivity extends AppCompatActivity {
alertDialog.show(); alertDialog.show();
} }
private String stringsGetter(int strId) {
return getResources().getString(strId);
}
private void goToRateApp() { private void goToRateApp() {
Intent goToMarket = new Intent(Intent.ACTION_VIEW, KIWIX_LOCAL_MARKET_URI); Intent goToMarket = new Intent(Intent.ACTION_VIEW, KIWIX_LOCAL_MARKET_URI);
@ -677,8 +698,8 @@ public class KiwixMobileActivity extends AppCompatActivity {
} }
private void undoSnackbar(final int index) { private void undoSnackbar(final int index) {
Snackbar undoSnackbar = Snackbar.make(snackbarLayout, stringsGetter(R.string.tab_closed), Snackbar.LENGTH_LONG) Snackbar undoSnackbar = Snackbar.make(snackbarLayout, ShortcutUtils.stringsGetter(R.string.tab_closed, this), Snackbar.LENGTH_LONG)
.setAction(stringsGetter(R.string.undo), new View.OnClickListener() { .setAction(ShortcutUtils.stringsGetter(R.string.undo, this), new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
@ -691,7 +712,7 @@ public class KiwixMobileActivity extends AppCompatActivity {
mLeftDrawerLayout.openDrawer(Gravity.LEFT); mLeftDrawerLayout.openDrawer(Gravity.LEFT);
} }
}); });
undoSnackbar.setActionTextColor(getResources().getColor(R.color.white_undo)); undoSnackbar.setActionTextColor(getResources().getColor(R.color.white));
undoSnackbar.show(); undoSnackbar.show();
} }
@ -1078,18 +1099,18 @@ public class KiwixMobileActivity extends AppCompatActivity {
private void popBookmarkSnackbar(boolean isBookmark) { private void popBookmarkSnackbar(boolean isBookmark) {
if (isBookmark) { if (isBookmark) {
Snackbar bookmarkSnackbar = Snackbar bookmarkSnackbar =
Snackbar.make(snackbarLayout, stringsGetter(R.string.bookmark_added), Snackbar.LENGTH_LONG) Snackbar.make(snackbarLayout, ShortcutUtils.stringsGetter(R.string.bookmark_added, this), Snackbar.LENGTH_LONG)
.setAction(stringsGetter(R.string.open), new View.OnClickListener() { .setAction(ShortcutUtils.stringsGetter(R.string.open, this), new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
goToBookmarks(); goToBookmarks();
} }
}); });
bookmarkSnackbar.setActionTextColor(getResources().getColor(R.color.white_undo)); bookmarkSnackbar.setActionTextColor(getResources().getColor(R.color.white));
bookmarkSnackbar.show(); bookmarkSnackbar.show();
} else { } else {
Snackbar bookmarkSnackbar = Snackbar bookmarkSnackbar =
Snackbar.make(snackbarLayout, stringsGetter(R.string.bookmark_removed), Snackbar.LENGTH_LONG); Snackbar.make(snackbarLayout, ShortcutUtils.stringsGetter(R.string.bookmark_removed, this), Snackbar.LENGTH_LONG);
bookmarkSnackbar.show(); bookmarkSnackbar.show();
} }
} }
@ -1102,6 +1123,20 @@ public class KiwixMobileActivity extends AppCompatActivity {
} }
} }
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
boolean IS_WIDGET_STAR = getIntent().getBooleanExtra("isWidgetStar", false);
boolean IS_WIDGET_SEARCH_INTENT = getIntent().getBooleanExtra("isWidgetSearch", false);
if (IS_WIDGET_STAR) {
goToBookmarks();
} else if (IS_WIDGET_SEARCH_INTENT) {
goToSearch(false);
}
}
private void refreshBookmarks() { private void refreshBookmarks() {
bookmarks.clear(); bookmarks.clear();
if (ZimContentProvider.getId() != null) { if (ZimContentProvider.getId() != null) {
@ -1154,12 +1189,12 @@ public class KiwixMobileActivity extends AppCompatActivity {
}, 500); }, 500);
AlertDialog.Builder builder = new AlertDialog.Builder(this); AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(stringsGetter(R.string.hint_contents_drawer_message)) builder.setMessage(ShortcutUtils.stringsGetter(R.string.hint_contents_drawer_message, this))
.setPositiveButton(stringsGetter(R.string.got_it), new DialogInterface.OnClickListener() { .setPositiveButton(ShortcutUtils.stringsGetter(R.string.got_it, this), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
} }
}) })
.setTitle(stringsGetter(R.string.did_you_know)) .setTitle(ShortcutUtils.stringsGetter(R.string.did_you_know, this))
.setIcon(R.drawable.icon_question); .setIcon(R.drawable.icon_question);
AlertDialog alert = builder.create(); AlertDialog alert = builder.create();
alert.show();//showing the dialog alert.show();//showing the dialog
@ -1261,15 +1296,15 @@ public class KiwixMobileActivity extends AppCompatActivity {
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
if (isOpenNewTabInBackground) { if (isOpenNewTabInBackground) {
newTabInBackground(url); newTabInBackground(url);
Snackbar snackbar = Snackbar.make(snackbarLayout, stringsGetter(R.string.new_tab_snackbar), Snackbar.LENGTH_LONG) Snackbar snackbar = Snackbar.make(snackbarLayout, ShortcutUtils.stringsGetter(R.string.new_tab_snackbar, getBaseContext()), Snackbar.LENGTH_LONG)
.setAction(stringsGetter(R.string.open), new View.OnClickListener() { .setAction(ShortcutUtils.stringsGetter(R.string.open, getBaseContext()), new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (mWebViews.size() > 1) if (mWebViews.size() > 1)
selectTab(mWebViews.size() - 1); selectTab(mWebViews.size() - 1);
} }
}); });
snackbar.setActionTextColor(getResources().getColor(R.color.white_undo)); snackbar.setActionTextColor(getResources().getColor(R.color.white));
snackbar.show(); snackbar.show();
} else { } else {
newTab(url); newTab(url);

View File

@ -1,9 +1,11 @@
package org.kiwix.kiwixmobile; package org.kiwix.kiwixmobile;
import android.content.ActivityNotFoundException;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle; import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.support.v4.view.MenuItemCompat; import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
@ -18,21 +20,21 @@ import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import org.kiwix.kiwixmobile.utils.DatabaseHelper; import org.kiwix.kiwixmobile.utils.HelperClasses.DatabaseHelper;
import org.kiwix.kiwixmobile.utils.HelperClasses.ShortcutUtils;
import org.kiwix.kiwixmobile.views.AutoCompleteAdapter; import org.kiwix.kiwixmobile.views.AutoCompleteAdapter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Locale;
public class SearchActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener { public class SearchActivity extends AppCompatActivity
implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener {
private final int REQ_CODE_SPEECH_INPUT = 100;
private ListView mListView; private ListView mListView;
private AutoCompleteAdapter mAutoAdapter; private AutoCompleteAdapter mAutoAdapter;
private ArrayAdapter<String> mDefaultAdapter; private ArrayAdapter<String> mDefaultAdapter;
private SearchActivity context; private SearchActivity context;
private DatabaseHelper mDatabaseHelper; private DatabaseHelper mDatabaseHelper;
@Override @Override
@ -45,7 +47,6 @@ public class SearchActivity extends AppCompatActivity implements AdapterView.OnI
getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setHomeButtonEnabled(true);
String zimFile = getIntent().getStringExtra("zimFile"); String zimFile = getIntent().getStringExtra("zimFile");
zimFile = escapeSqlSyntax(zimFile);
mListView = (ListView) findViewById(R.id.search_list); mListView = (ListView) findViewById(R.id.search_list);
mDatabaseHelper = new DatabaseHelper(this, zimFile); mDatabaseHelper = new DatabaseHelper(this, zimFile);
SQLiteDatabase db = mDatabaseHelper.getWritableDatabase(); SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
@ -59,6 +60,11 @@ public class SearchActivity extends AppCompatActivity implements AdapterView.OnI
mAutoAdapter = new AutoCompleteAdapter(context); mAutoAdapter = new AutoCompleteAdapter(context);
mListView.setOnItemClickListener(context); mListView.setOnItemClickListener(context);
mListView.setOnItemLongClickListener(context); mListView.setOnItemLongClickListener(context);
boolean IS_VOICE_SEARCH_INTENT = getIntent().getBooleanExtra("isWidgetVoice", false);
if (IS_VOICE_SEARCH_INTENT) {
promptSpeechInput();
}
} }
@Override @Override
@ -114,7 +120,6 @@ public class SearchActivity extends AppCompatActivity implements AdapterView.OnI
@Override @Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String title = ((TextView) view).getText().toString(); String title = ((TextView) view).getText().toString();
title = escapeSqlSyntax(title);
mDatabaseHelper.insertSearch(title); mDatabaseHelper.insertSearch(title);
sendMessage(title); sendMessage(title);
} }
@ -137,7 +142,7 @@ public class SearchActivity extends AppCompatActivity implements AdapterView.OnI
private void deleteSpecificSearchDialog(final String search) { private void deleteSpecificSearchDialog(final String search) {
new AlertDialog.Builder(this) new AlertDialog.Builder(this)
.setMessage(getResources().getString(R.string.deleteRecentSearchItem)) .setMessage(ShortcutUtils.stringsGetter(R.string.delete_recent_search_item, this))
.setPositiveButton(getResources().getString(R.string.delete), new DialogInterface.OnClickListener() { .setPositiveButton(getResources().getString(R.string.delete), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
deleteSpecificSearchItem(search); deleteSpecificSearchItem(search);
@ -154,22 +159,10 @@ public class SearchActivity extends AppCompatActivity implements AdapterView.OnI
private void deleteSpecificSearchItem(String search) { private void deleteSpecificSearchItem(String search) {
SQLiteDatabase db = mDatabaseHelper.getWritableDatabase(); SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
mDatabaseHelper.deleteSpecificSearch(db, escapeSqlSyntax(search)); mDatabaseHelper.deleteSpecificSearch(db, ShortcutUtils.escapeSqlSyntax(search));
resetAdapter(); resetAdapter();
} }
private String escapeSqlSyntax(String search) { //Escapes sql ' if exists
String tempStr = "";
char[] charArray = search.toCharArray();
for (char a : charArray) {
if (a != '\'')
tempStr += a;
else
tempStr += "''";
}
return tempStr;
}
private void resetAdapter() { private void resetAdapter() {
ArrayList<String> a = mDatabaseHelper.getRecentSearches(); ArrayList<String> a = mDatabaseHelper.getRecentSearches();
mDefaultAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1); mDefaultAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
@ -179,4 +172,51 @@ public class SearchActivity extends AppCompatActivity implements AdapterView.OnI
} }
private void promptSpeechInput() {
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault()); // TODO: choose selected lang on kiwix
intent.putExtra(RecognizerIntent.EXTRA_PROMPT,
getString(R.string.speech_prompt_text));
try {
startActivityForResult(intent, REQ_CODE_SPEECH_INPUT);
} catch (ActivityNotFoundException a) {
Toast.makeText(getApplicationContext(),
getString(R.string.speech_not_supported),
Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQ_CODE_SPEECH_INPUT: {
if (resultCode == RESULT_OK && data != null) {
ArrayList<String> result = data
.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
searchViaVoice(result.get(0));
}
break;
}
}
}
private void searchViaVoice(String search) {
search = capitalizeSearch(search);
mDatabaseHelper.insertSearch(search);
sendMessage(search);
}
private String capitalizeSearch(String search) {
search = search.substring(0, 1).toUpperCase() + search.substring(1).toLowerCase();
return search;
}
} }

View File

@ -55,7 +55,7 @@ import android.widget.Toast;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.kiwix.kiwixmobile.utils.LanguageUtils; import org.kiwix.kiwixmobile.utils.HelperClasses.LanguageUtils;
import org.kiwix.kiwixmobile.utils.files.FileSearch; import org.kiwix.kiwixmobile.utils.files.FileSearch;
import org.kiwix.kiwixmobile.utils.files.FileWriter; import org.kiwix.kiwixmobile.utils.files.FileWriter;

View File

@ -38,8 +38,8 @@ import android.widget.BaseAdapter;
import android.widget.Toast; import android.widget.Toast;
import org.kiwix.kiwixmobile.R; import org.kiwix.kiwixmobile.R;
import org.kiwix.kiwixmobile.utils.DatabaseHelper; import org.kiwix.kiwixmobile.utils.HelperClasses.DatabaseHelper;
import org.kiwix.kiwixmobile.utils.LanguageUtils; import org.kiwix.kiwixmobile.utils.HelperClasses.LanguageUtils;
import org.kiwix.kiwixmobile.views.SliderPreference; import org.kiwix.kiwixmobile.views.SliderPreference;
import java.util.Locale; import java.util.Locale;

View File

@ -1,4 +1,4 @@
package org.kiwix.kiwixmobile.utils; package org.kiwix.kiwixmobile.utils.HelperClasses;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context; import android.content.Context;
@ -6,9 +6,8 @@ import android.database.Cursor;
import android.database.DatabaseUtils; import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import org.kiwix.kiwixmobile.KiwixMobileActivity; import org.kiwix.kiwixmobile.utils.HelperClasses.ShortcutUtils;
import java.util.ArrayList; import java.util.ArrayList;
@ -84,9 +83,9 @@ public class DatabaseHelper extends SQLiteOpenHelper {
ArrayList<String> array_list = new ArrayList<String>(); ArrayList<String> array_list = new ArrayList<String>();
SQLiteDatabase db = this.getReadableDatabase(); SQLiteDatabase db = this.getReadableDatabase();
//hp = new HashMap(); //hp = new HashMap();
Log.d(KiwixMobileActivity.TAG_KIWIX, zimFile); // Log.d(KiwixMobileActivity.TAG_KIWIX, zimFile);
Cursor res = db.rawQuery("select * from " + CONTACTS_TABLE_NAME Cursor res = db.rawQuery("select * from " + CONTACTS_TABLE_NAME
+ " where " + CONTACTS_COLUMN_ZIM + " = '" + zimFile + "'", null); + " where " + CONTACTS_COLUMN_ZIM + " = '" + ShortcutUtils.escapeSqlSyntax(zimFile) + "'", null);
res.moveToLast(); res.moveToLast();
while (!res.isBeforeFirst()) { while (!res.isBeforeFirst()) {

View File

@ -1,4 +1,4 @@
package org.kiwix.kiwixmobile.utils; package org.kiwix.kiwixmobile.utils.HelperClasses;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Typeface; import android.graphics.Typeface;

View File

@ -17,7 +17,7 @@
* MA 02110-1301, USA. * MA 02110-1301, USA.
*/ */
package org.kiwix.kiwixmobile.utils; package org.kiwix.kiwixmobile.utils.HelperClasses;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;

View File

@ -1,4 +1,4 @@
package org.kiwix.kiwixmobile.utils; package org.kiwix.kiwixmobile.utils.HelperClasses;
import android.content.Context; import android.content.Context;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;

View File

@ -0,0 +1,53 @@
/*
* Copyright 2013 Elad Keyshawn <elad.keyshawn@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.kiwix.kiwixmobile.utils.HelperClasses;
import android.content.Context;
/*
Helper class containing basic useful functions
that are meant to make shortcuts and beautifying code.
*/
public class ShortcutUtils {
public static String stringsGetter(int strId, Context context) {
return context.getResources().getString(strId);
}
public static String escapeSqlSyntax(String search) {//Escapes sql ' if exists
if (search != null) {
String tempStr = "";
char[] charArray = search.toCharArray();
for (char a : charArray) {
if (a != '\'')
tempStr += a;
else
tempStr += "''";
}
return tempStr;
} else {
return search;
}
}
}

View File

@ -1,4 +1,4 @@
package org.kiwix.kiwixmobile.utils; package org.kiwix.kiwixmobile.utils.HelperClasses;
import android.os.Build; import android.os.Build;
import android.os.Environment; import android.os.Environment;

View File

@ -0,0 +1,96 @@
/*
* Copyright 2013 Elad Keyshawn <elad.keyshawn@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.kiwix.kiwixmobile.utils;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
import org.kiwix.kiwixmobile.KiwixMobileActivity;
import org.kiwix.kiwixmobile.R;
public class KiwixSearchWidget extends AppWidgetProvider {
private static final String TEXT_CLICKED = "SearchKiwixActionClicked";
private static final String ICON_CLICKED = "KiwixIconActionClicked";
private static final String MIC_CLICKED = "MicSearchActionClicked";
private static final String STAR_CLICKED = "StarActionClicked";
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.kiwix_search_widget);
/** Search Kiwix intent **/
Intent mainIntent = new Intent(context, KiwixMobileActivity.class);
mainIntent.putExtra("isWidgetSearch", true);
mainIntent.setAction(TEXT_CLICKED);
PendingIntent searchPendingIntent = PendingIntent.getActivity(context, 0, mainIntent, 0);
/** Kiwix icon intent to main app **/
Intent kiwixIconIntent = new Intent(context, KiwixMobileActivity.class);
kiwixIconIntent.setAction(ICON_CLICKED);
PendingIntent mainAppPendingIntent = PendingIntent.getActivity(context, 0, kiwixIconIntent, 0);
/** Star icon intent to bookmarks **/
Intent starIntent = new Intent(context, KiwixMobileActivity.class);
starIntent.putExtra("isWidgetStar", true);
starIntent.setAction(STAR_CLICKED);
PendingIntent starPendingIntent = PendingIntent.getActivity(context,0,starIntent, 0);
/** Microphone icon intent for voice search **/
Intent voiceIntent = new Intent(context, KiwixMobileActivity.class);
voiceIntent.putExtra("isWidgetVoice", true);
voiceIntent.setAction(MIC_CLICKED);
PendingIntent voicePendingIntent = PendingIntent.getActivity(context, 0, voiceIntent, 0);
views.setOnClickPendingIntent(R.id.search_widget_text, searchPendingIntent);
views.setOnClickPendingIntent(R.id.search_widget_icon, mainAppPendingIntent);
views.setOnClickPendingIntent(R.id.search_widget_star, starPendingIntent);
views.setOnClickPendingIntent(R.id.search_widget_mic, voicePendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
}
// protected PendingIntent getPendingSelfIntent(Context context, String action) {
// Intent intent = new Intent(context, getClass());
// intent.setAction(action);
// return PendingIntent.getBroadcast(context, 0, intent, 0);
// }
}

View File

@ -13,6 +13,7 @@ import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import org.kiwix.kiwixmobile.R; import org.kiwix.kiwixmobile.R;
import org.kiwix.kiwixmobile.ZimContentProvider; import org.kiwix.kiwixmobile.ZimContentProvider;
import org.kiwix.kiwixmobile.utils.HelperClasses.LanguageUtils;
public class KiwixTextToSpeech { public class KiwixTextToSpeech {

View File

@ -1,4 +1,24 @@
package org.kiwix.kiwixmobile.utils.files; /*
* Copyright 2013 Elad Keyshawn <elad.keyshawn@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.kiwix.kiwixmobile.utils;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;