mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-03 10:46:53 -04:00
Backported the Android app to API 9. See Bug #783 for more details.
This commit is contained in:
parent
934da9d251
commit
17190d8770
@ -15,10 +15,11 @@
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="11"
|
||||
android:minSdkVersion="9"
|
||||
android:targetSdkVersion="19"/>
|
||||
<application
|
||||
android:icon="@drawable/kiwix_icon"
|
||||
android:theme="@style/Theme.AppCompat"
|
||||
android:label="@string/app_name"
|
||||
android:allowBackup="true">
|
||||
<activity
|
||||
@ -42,7 +43,7 @@
|
||||
<data android:mimeType="*/*"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".KiwixSettings">
|
||||
<activity android:name=".KiwixSettingsActivity">
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
|
@ -11,8 +11,13 @@ buildscript {
|
||||
|
||||
apply plugin: 'android'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.android.support:support-v4:19.0.0'
|
||||
compile 'com.android.support:appcompat-v7:19.0.0'
|
||||
compile files("$buildDir/native-libs/native-libs.jar")
|
||||
|
||||
}
|
||||
@ -22,7 +27,7 @@ android {
|
||||
buildToolsVersion "19"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 11
|
||||
minSdkVersion 9
|
||||
targetSdkVersion 19
|
||||
}
|
||||
|
||||
|
@ -1,14 +0,0 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system edit
|
||||
# "ant.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
#
|
||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target=android-14
|
BIN
res/drawable-hdpi/ic_find_next_holo_dark.png
Normal file
BIN
res/drawable-hdpi/ic_find_next_holo_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
BIN
res/drawable-hdpi/ic_find_previous_holo_dark.png
Normal file
BIN
res/drawable-hdpi/ic_find_previous_holo_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
BIN
res/drawable-mdpi/ic_find_next_holo_dark.png
Normal file
BIN
res/drawable-mdpi/ic_find_next_holo_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 740 B |
BIN
res/drawable-mdpi/ic_find_previous_holo_dark.png
Normal file
BIN
res/drawable-mdpi/ic_find_previous_holo_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 744 B |
BIN
res/drawable-xhdpi/ic_find_next_holo_dark.png
Normal file
BIN
res/drawable-xhdpi/ic_find_next_holo_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
res/drawable-xhdpi/ic_find_previous_holo_dark.png
Normal file
BIN
res/drawable-xhdpi/ic_find_previous_holo_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
@ -28,7 +28,7 @@
|
||||
android:inputType="text|textCapWords"
|
||||
android:maxLines="1"
|
||||
android:background="@android:color/background_dark"
|
||||
android:textColor="@android:color/primary_text_dark"/>
|
||||
android:textColor="@android:color/white"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
11
res/layout/simple_list_item.xml
Normal file
11
res/layout/simple_list_item.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@android:id/text1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingLeft="6dip"
|
||||
android:textColor="@android:color/black"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"/>
|
33
res/layout/webview_find.xml
Normal file
33
res/layout/webview_find.xml
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2007 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit"
|
||||
android:layout_width="0dip"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollHorizontally="true"
|
||||
android:inputType="text"
|
||||
android:hint="@string/search_label"
|
||||
android:imeOptions="actionDone|flagNoExtractUi|flagNoFullscreen"
|
||||
android:layout_marginRight="10dip"/>
|
||||
|
||||
</LinearLayout>
|
@ -1,11 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_rescan_fs"
|
||||
android:icon="@drawable/action_refresh"
|
||||
android:title="@string/menu_rescan_fs"
|
||||
android:showAsAction="always"/>
|
||||
app:showAsAction="always"/>
|
||||
|
||||
</menu>
|
@ -1,81 +1,82 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_search"
|
||||
android:icon="@drawable/action_search"
|
||||
android:title="@string/menu_search"
|
||||
android:visible="false"
|
||||
android:showAsAction="ifRoom"/>
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_back"
|
||||
android:title="@string/menu_back"
|
||||
android:icon="@drawable/navigation_back"
|
||||
android:visible="false"
|
||||
android:showAsAction="ifRoom"/>
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_forward"
|
||||
android:title="@string/menu_forward"
|
||||
android:icon="@drawable/navigation_forward"
|
||||
android:visible="false"
|
||||
android:showAsAction="ifRoom"/>
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_randomarticle"
|
||||
android:icon="@drawable/action_randomarticle"
|
||||
android:title="@string/menu_randomarticle"
|
||||
android:visible="false"
|
||||
android:showAsAction="ifRoom"/>
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_home"
|
||||
android:title="@string/menu_home"
|
||||
android:icon="@drawable/action_home"
|
||||
android:visible="false"
|
||||
android:showAsAction="ifRoom"/>
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_openfile"
|
||||
android:title="@string/menu_openfile"
|
||||
android:icon="@drawable/device_access_sd_storage"
|
||||
android:showAsAction="ifRoom"/>
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_searchintext"
|
||||
android:icon="@drawable/action_search"
|
||||
android:title="@string/menu_searchintext"
|
||||
android:visible="false"
|
||||
android:showAsAction="ifRoom"/>
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_fullscreen"
|
||||
android:icon="@drawable/action_search"
|
||||
android:title="@string/menu_fullscreen"
|
||||
android:visible="false"
|
||||
android:showAsAction="never"/>
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_settings"
|
||||
android:title="@string/menu_settings"
|
||||
android:icon="@drawable/navigation_forward"
|
||||
android:showAsAction="never"/>
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_help"
|
||||
android:title="@string/menu_help"
|
||||
android:icon="@drawable/action_help"
|
||||
android:showAsAction="never"/>
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_share"
|
||||
android:title="@string/menu_share"
|
||||
android:icon="@drawable/action_share"
|
||||
android:showAsAction="ifRoom"/>
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_exit"
|
||||
android:title="@string/menu_exit"
|
||||
android:showAsAction="never"/>
|
||||
app:showAsAction="never"/>
|
||||
|
||||
</menu>
|
||||
|
28
res/menu/webview_menu.xml
Normal file
28
res/menu/webview_menu.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2010 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/find_prev"
|
||||
android:icon="@drawable/ic_find_previous_holo_dark"
|
||||
app:showAsAction="always"/>
|
||||
<item
|
||||
android:id="@+id/find_next"
|
||||
android:icon="@drawable/ic_find_next_holo_dark"
|
||||
app:showAsAction="always"/>
|
||||
</menu>
|
@ -54,4 +54,6 @@
|
||||
<string name="share_via">Share via</string>
|
||||
<string name="pref_language_title">Language</string>
|
||||
<string name="pref_language_chooser">Choose a language</string>
|
||||
<string name="delete_tab_title">Delete Tab</string>
|
||||
<string name="delete_tab_message">Do you want to delete this tab?</string>
|
||||
</resources>
|
||||
|
1
settings.gradle
Normal file
1
settings.gradle
Normal file
@ -0,0 +1 @@
|
||||
include ':android'
|
37
src/org/kiwix/kiwixmobile/BackwardsCompatibilityTools.java
Normal file
37
src/org/kiwix/kiwixmobile/BackwardsCompatibilityTools.java
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2013 Rashiq Ahmad <rashiq.z@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.os.Build;
|
||||
|
||||
public class BackwardsCompatibilityTools {
|
||||
|
||||
public static final boolean newApi() {
|
||||
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
|
||||
}
|
||||
|
||||
public static final boolean equalsOrNewThanApi(int api) {
|
||||
|
||||
return Build.VERSION.SDK_INT >= api;
|
||||
}
|
||||
|
||||
}
|
209
src/org/kiwix/kiwixmobile/CompatFindActionModeCallback.java
Normal file
209
src/org/kiwix/kiwixmobile/CompatFindActionModeCallback.java
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright 2013 Rashiq Ahmad <rashiq.z@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.Context;
|
||||
import android.support.v7.view.ActionMode;
|
||||
import android.text.Editable;
|
||||
import android.text.Selection;
|
||||
import android.text.Spannable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.webkit.WebView;
|
||||
import android.widget.EditText;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class CompatFindActionModeCallback implements ActionMode.Callback, TextWatcher, View.OnClickListener {
|
||||
|
||||
public boolean mIsActive;
|
||||
|
||||
private View mCustomView;
|
||||
|
||||
private EditText mEditText;
|
||||
|
||||
private WebView mWebView;
|
||||
|
||||
private InputMethodManager mInput;
|
||||
|
||||
private boolean mMatchesFound;
|
||||
|
||||
private ActionMode mActionMode;
|
||||
|
||||
public CompatFindActionModeCallback(Context context) {
|
||||
mCustomView = LayoutInflater.from(context).inflate(R.layout.webview_find, null);
|
||||
mEditText = (EditText) mCustomView.findViewById(R.id.edit);
|
||||
mEditText.setOnClickListener(this);
|
||||
mInput = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
mIsActive = false;
|
||||
setText("");
|
||||
}
|
||||
|
||||
public void setActive() {
|
||||
mIsActive = true;
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
mActionMode.finish();
|
||||
mWebView.clearMatches();
|
||||
}
|
||||
|
||||
// Place text in the text field so it can be searched for. Need to press
|
||||
// the find next or find previous button to find all of the matches.
|
||||
public void setText(String text) {
|
||||
mEditText.setText(text);
|
||||
Spannable span = mEditText.getText();
|
||||
int length = span.length();
|
||||
|
||||
// Ideally, we would like to set the selection to the whole field,
|
||||
// but this brings up the Text selection CAB, which dismisses this
|
||||
// one.
|
||||
Selection.setSelection(span, length, length);
|
||||
|
||||
// Necessary each time we set the text, so that this will watch
|
||||
// changes to it.
|
||||
span.setSpan(this, 0, length, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
|
||||
mMatchesFound = false;
|
||||
}
|
||||
|
||||
// Set the WebView to search. Must be non null, and set before calling startActionMode.
|
||||
public void setWebView(WebView webView) {
|
||||
if (null == webView) {
|
||||
throw new AssertionError("WebView supplied to CompatFindActionModeCallback cannot be null");
|
||||
}
|
||||
mWebView = webView;
|
||||
}
|
||||
|
||||
// Move the highlight to the next match.
|
||||
// If true, find the next match further down in the document.
|
||||
// If false, find the previous match, up in the document.
|
||||
private void findNext(boolean next) {
|
||||
|
||||
if (mWebView == null) {
|
||||
throw new AssertionError("No WebView for CompatFindActionModeCallback::findNext");
|
||||
}
|
||||
|
||||
mWebView.findNext(next);
|
||||
}
|
||||
|
||||
// Highlight all the instances of the string from mEditText in mWebView.
|
||||
public void findAll() {
|
||||
if (mWebView == null) {
|
||||
throw new AssertionError("No WebView for CompatFindActionModeCallback::findAll");
|
||||
}
|
||||
CharSequence find = mEditText.getText();
|
||||
if (find.length() == 0) {
|
||||
mWebView.clearMatches();
|
||||
mMatchesFound = false;
|
||||
mWebView.findAll(null);
|
||||
} else {
|
||||
mMatchesFound = true;
|
||||
mWebView.findAll(find.toString());
|
||||
|
||||
// Enable word highlighting with reflection
|
||||
try {
|
||||
for (Method ms : WebView.class.getDeclaredMethods()) {
|
||||
if (ms.getName().equals("setFindIsUp")) {
|
||||
ms.setAccessible(true);
|
||||
ms.invoke(mWebView, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Show on screen keyboard
|
||||
public void showSoftInput() {
|
||||
mInput.showSoftInput(mEditText, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
findNext(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
||||
mode.setCustomView(mCustomView);
|
||||
mode.getMenuInflater().inflate(R.menu.webview_menu, menu);
|
||||
mActionMode = mode;
|
||||
Editable edit = mEditText.getText();
|
||||
Selection.setSelection(edit, edit.length());
|
||||
mMatchesFound = false;
|
||||
mEditText.requestFocus();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyActionMode(ActionMode mode) {
|
||||
mActionMode = null;
|
||||
mIsActive = false;
|
||||
mWebView.clearMatches();
|
||||
mInput.hideSoftInputFromWindow(mWebView.getWindowToken(), 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||
if (mWebView == null) {
|
||||
throw new AssertionError("No WebView for CompatFindActionModeCallback::onActionItemClicked");
|
||||
}
|
||||
|
||||
mInput.hideSoftInputFromWindow(mWebView.getWindowToken(), 0);
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.find_prev:
|
||||
findNext(false);
|
||||
break;
|
||||
case R.id.find_next:
|
||||
findNext(true);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
// Does nothing. Needed to implement TextWatcher.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
findAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
// Does nothing. Needed to implement TextWatcher.
|
||||
}
|
||||
}
|
@ -19,20 +19,23 @@
|
||||
|
||||
package org.kiwix.kiwixmobile;
|
||||
|
||||
import android.app.ActionBar;
|
||||
import android.app.FragmentTransaction;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ClipData;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
@ -44,15 +47,18 @@ import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.HorizontalScrollView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class KiwixMobileActivity extends FragmentActivity implements ActionBar.TabListener,
|
||||
View.OnLongClickListener, View.OnDragListener, KiwixMobileFragment.FragmentCommunicator {
|
||||
import static org.kiwix.kiwixmobile.BackwardsCompatibilityTools.equalsOrNewThanApi;
|
||||
import static org.kiwix.kiwixmobile.BackwardsCompatibilityTools.newApi;
|
||||
|
||||
|
||||
public class KiwixMobileActivity extends ActionBarActivity implements ActionBar.TabListener,
|
||||
View.OnLongClickListener, KiwixMobileFragment.FragmentCommunicator {
|
||||
|
||||
public static ArrayList<State> mPrefState;
|
||||
|
||||
@ -66,6 +72,8 @@ public class KiwixMobileActivity extends FragmentActivity implements ActionBar.T
|
||||
|
||||
private KiwixMobileFragment mCurrentFragment;
|
||||
|
||||
private View.OnDragListener mOnDragListener;
|
||||
|
||||
private int mNumberOfTabs = 0;
|
||||
|
||||
private int mCurrentDraggedTab;
|
||||
@ -74,29 +82,38 @@ public class KiwixMobileActivity extends FragmentActivity implements ActionBar.T
|
||||
|
||||
private int mTabsHeight;
|
||||
|
||||
private CompatFindActionModeCallback mCompatCallback;
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
requestWindowFeature(Window.FEATURE_PROGRESS);
|
||||
|
||||
setProgressBarVisibility(true);
|
||||
|
||||
handleLocaleCheck();
|
||||
|
||||
setContentView(R.layout.viewpager);
|
||||
|
||||
// Set an OnDragListener on the entire View. Now we can track, if the user drags the
|
||||
// Tab outside the View
|
||||
getWindow().getDecorView().setOnDragListener(this);
|
||||
// Set an OnDragListener on the entire View. Now we can track,
|
||||
// if the user drags the Tab outside the View
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
setUpOnDragListener();
|
||||
getWindow().getDecorView().setOnDragListener(mOnDragListener);
|
||||
}
|
||||
|
||||
mViewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
|
||||
|
||||
mViewPager = (ViewPager) findViewById(R.id.viewPager);
|
||||
|
||||
mActionBar = getActionBar();
|
||||
mActionBar = getSupportActionBar();
|
||||
|
||||
mPrefState = new ArrayList<State>();
|
||||
|
||||
mCompatCallback = new CompatFindActionModeCallback(this);
|
||||
|
||||
mIsFullscreenOpened = false;
|
||||
|
||||
setUpViewPagerAndActionBar();
|
||||
@ -107,7 +124,7 @@ public class KiwixMobileActivity extends FragmentActivity implements ActionBar.T
|
||||
|
||||
private void setUpViewPagerAndActionBar() {
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
||||
if (equalsOrNewThanApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)) {
|
||||
mActionBar.setHomeButtonEnabled(false);
|
||||
}
|
||||
|
||||
@ -154,6 +171,73 @@ public class KiwixMobileActivity extends FragmentActivity implements ActionBar.T
|
||||
});
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
private void setUpOnDragListener() {
|
||||
mOnDragListener = new View.OnDragListener() {
|
||||
|
||||
// Delete the current Tab, that is being dragged, if it hits the bounds of the Screen
|
||||
@Override
|
||||
public boolean onDrag(View v, DragEvent event) {
|
||||
|
||||
DisplayMetrics displaymetrics = new DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
|
||||
|
||||
// Get the height of the title bar
|
||||
final int titleBarHeight;
|
||||
|
||||
switch (displaymetrics.densityDpi) {
|
||||
|
||||
case DisplayMetrics.DENSITY_HIGH:
|
||||
titleBarHeight = 48;
|
||||
break;
|
||||
|
||||
case DisplayMetrics.DENSITY_MEDIUM:
|
||||
titleBarHeight = 32;
|
||||
break;
|
||||
|
||||
case DisplayMetrics.DENSITY_LOW:
|
||||
titleBarHeight = 24;
|
||||
break;
|
||||
|
||||
default:
|
||||
titleBarHeight = 0;
|
||||
}
|
||||
|
||||
// Get the width and height of the screen
|
||||
final int screenHeight = displaymetrics.heightPixels;
|
||||
final int screenWidth = displaymetrics.widthPixels;
|
||||
|
||||
// Get the current position of the View, that is being dragged
|
||||
final int positionX = (int) event.getX();
|
||||
final int positionY = (int) event.getY();
|
||||
|
||||
if (event.getAction() == DragEvent.ACTION_DRAG_EXITED) {
|
||||
|
||||
removeTabAt(mCurrentDraggedTab);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event.getAction() == DragEvent.ACTION_DROP) {
|
||||
|
||||
// Does it hit the boundries on the x-axis?
|
||||
if ((positionX > screenWidth - (0.25 * mTabsWidth)) ||
|
||||
(positionX < (0.25 * mTabsWidth))) {
|
||||
Log.i("kiwix", "Dragged out");
|
||||
removeTabAt(mCurrentDraggedTab);
|
||||
}
|
||||
// Does it hit the boundries on the y-axis?
|
||||
else if ((positionY > screenHeight - (0.25 * mTabsHeight)) ||
|
||||
((positionY - titleBarHeight) < (0.5 * mTabsHeight))) {
|
||||
Log.i("kiwix", "Dragged out");
|
||||
removeTabAt(mCurrentDraggedTab);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Reset the Locale and change the font of all TextViews and its subclasses, if necessary
|
||||
private void handleLocaleCheck() {
|
||||
LanguageUtils.handleLocaleChange(this);
|
||||
@ -176,13 +260,10 @@ public class KiwixMobileActivity extends FragmentActivity implements ActionBar.T
|
||||
|
||||
mCurrentFragment = getCurrentVisibleFragment();
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
|
||||
switch (item.getItemId()) {
|
||||
|
||||
case R.id.menu_home:
|
||||
case android.R.id.home:
|
||||
imm.hideSoftInputFromWindow(mCurrentFragment.articleSearchtextView.getWindowToken(), 0);
|
||||
mCurrentFragment.openMainPage();
|
||||
break;
|
||||
|
||||
@ -195,18 +276,18 @@ public class KiwixMobileActivity extends FragmentActivity implements ActionBar.T
|
||||
break;
|
||||
|
||||
case R.id.menu_searchintext:
|
||||
mCurrentFragment.webView.showFindDialog("", true);
|
||||
break;
|
||||
mCompatCallback.setActive();
|
||||
mCompatCallback.setWebView(mCurrentFragment.webView);
|
||||
mCompatCallback.showSoftInput();
|
||||
startSupportActionMode(mCompatCallback);
|
||||
|
||||
case R.id.menu_forward:
|
||||
imm.hideSoftInputFromWindow(mCurrentFragment.articleSearchtextView.getWindowToken(), 0);
|
||||
if (mCurrentFragment.webView.canGoForward()) {
|
||||
mCurrentFragment.webView.goForward();
|
||||
}
|
||||
break;
|
||||
|
||||
case R.id.menu_back:
|
||||
imm.hideSoftInputFromWindow(mCurrentFragment.articleSearchtextView.getWindowToken(), 0);
|
||||
if (mCurrentFragment.webView.canGoBack()) {
|
||||
mCurrentFragment.menu.findItem(R.id.menu_forward).setVisible(true);
|
||||
mCurrentFragment.webView.goBack();
|
||||
@ -214,7 +295,6 @@ public class KiwixMobileActivity extends FragmentActivity implements ActionBar.T
|
||||
break;
|
||||
|
||||
case R.id.menu_randomarticle:
|
||||
imm.hideSoftInputFromWindow(mCurrentFragment.articleSearchtextView.getWindowToken(), 0);
|
||||
mCurrentFragment.openRandomArticle();
|
||||
break;
|
||||
|
||||
@ -223,22 +303,18 @@ public class KiwixMobileActivity extends FragmentActivity implements ActionBar.T
|
||||
break;
|
||||
|
||||
case R.id.menu_help:
|
||||
imm.hideSoftInputFromWindow(mCurrentFragment.articleSearchtextView.getWindowToken(), 0);
|
||||
mCurrentFragment.showWelcome();
|
||||
break;
|
||||
|
||||
case R.id.menu_openfile:
|
||||
imm.hideSoftInputFromWindow(mCurrentFragment.articleSearchtextView.getWindowToken(), 0);
|
||||
mCurrentFragment.selectZimFile();
|
||||
break;
|
||||
|
||||
case R.id.menu_exit:
|
||||
imm.hideSoftInputFromWindow(mCurrentFragment.articleSearchtextView.getWindowToken(), 0);
|
||||
finish();
|
||||
break;
|
||||
|
||||
case R.id.menu_settings:
|
||||
imm.hideSoftInputFromWindow(mCurrentFragment.articleSearchtextView.getWindowToken(), 0);
|
||||
// Display the fragment as the main content.
|
||||
mCurrentFragment.selectSettings();
|
||||
break;
|
||||
@ -270,7 +346,7 @@ public class KiwixMobileActivity extends FragmentActivity implements ActionBar.T
|
||||
private void openFullScreen() {
|
||||
mCurrentFragment = getCurrentVisibleFragment();
|
||||
|
||||
getActionBar().hide();
|
||||
getSupportActionBar().hide();
|
||||
mCurrentFragment.exitFullscreenButton.setVisibility(View.VISIBLE);
|
||||
mCurrentFragment.menu.findItem(R.id.menu_fullscreen)
|
||||
.setTitle(getResources().getString(R.string.menu_exitfullscreen));
|
||||
@ -284,7 +360,7 @@ public class KiwixMobileActivity extends FragmentActivity implements ActionBar.T
|
||||
private void closeFullScreen() {
|
||||
mCurrentFragment = getCurrentVisibleFragment();
|
||||
|
||||
getActionBar().show();
|
||||
getSupportActionBar().show();
|
||||
mCurrentFragment.menu.findItem(R.id.menu_fullscreen)
|
||||
.setTitle(getResources().getString(R.string.menu_fullscreen));
|
||||
mCurrentFragment.exitFullscreenButton.setVisibility(View.INVISIBLE);
|
||||
@ -298,13 +374,22 @@ public class KiwixMobileActivity extends FragmentActivity implements ActionBar.T
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
mCurrentFragment = getCurrentVisibleFragment();
|
||||
|
||||
// Finish the search functionality on API 11<
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
if (mCompatCallback.mIsActive) {
|
||||
mCompatCallback.finish();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// handle the back button for the WebView in the current Fragment
|
||||
mCurrentFragment = getCurrentVisibleFragment();
|
||||
mCurrentFragment.onKeyDown(keyCode, event);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@ -332,7 +417,7 @@ public class KiwixMobileActivity extends FragmentActivity implements ActionBar.T
|
||||
// current tab would throw a NullPointerException, if the app were in landscape mode and
|
||||
// therefore possibly in NAVIGATION_MODE_LIST mode
|
||||
if (mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS) {
|
||||
getActionBar().getSelectedTab().setText(title);
|
||||
getSupportActionBar().getSelectedTab().setText(title);
|
||||
}
|
||||
if (mPrefState.size() != 0) {
|
||||
if (mPrefState.get(position).hasToBeRefreshed()) {
|
||||
@ -482,14 +567,14 @@ public class KiwixMobileActivity extends FragmentActivity implements ActionBar.T
|
||||
mCurrentFragment = getCurrentVisibleFragment();
|
||||
|
||||
String title = getResources().getString(R.string.app_name);
|
||||
if (mCurrentFragment.webView.getTitle() != null &&
|
||||
!mCurrentFragment.webView.getTitle().isEmpty()) {
|
||||
if (mCurrentFragment.webView.getTitle() != null
|
||||
&& !mCurrentFragment.webView.getTitle().isEmpty()) {
|
||||
title = mCurrentFragment.webView.getTitle();
|
||||
}
|
||||
|
||||
// Set the title for the selected Tab
|
||||
if (mActionBar.getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS) {
|
||||
getActionBar().getSelectedTab().setText(title);
|
||||
getSupportActionBar().getSelectedTab().setText(title);
|
||||
}
|
||||
}
|
||||
|
||||
@ -517,16 +602,28 @@ public class KiwixMobileActivity extends FragmentActivity implements ActionBar.T
|
||||
// This method gets a reference to the fragment, that is currently visible in the ViewPager
|
||||
private KiwixMobileFragment getCurrentVisibleFragment() {
|
||||
|
||||
return ((KiwixMobileFragment) mViewPagerAdapter.
|
||||
getFragmentAtPosition(mViewPager.getCurrentItem()));
|
||||
return ((KiwixMobileFragment) mViewPagerAdapter.getFragmentAtPosition(mViewPager.getCurrentItem()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
|
||||
|
||||
mCurrentDraggedTab = (Integer) v.getTag(R.id.action_bar_tab_id);
|
||||
|
||||
if (newApi()) {
|
||||
onLongClickOperation(v);
|
||||
} else {
|
||||
compatOnLongClickOperation();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
private void onLongClickOperation(View v) {
|
||||
|
||||
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
|
||||
|
||||
mTabsWidth = v.getWidth();
|
||||
mTabsHeight = v.getHeight();
|
||||
|
||||
@ -535,69 +632,21 @@ public class KiwixMobileActivity extends FragmentActivity implements ActionBar.T
|
||||
ClipData data = ClipData.newPlainText("", "");
|
||||
|
||||
v.startDrag(data, shadowBuilder, v, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Delete the current Tab, that is being dragged, if it hits the bounds of the Screen
|
||||
@Override
|
||||
public boolean onDrag(View v, DragEvent event) {
|
||||
private void compatOnLongClickOperation() {
|
||||
|
||||
DisplayMetrics displaymetrics = new DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
|
||||
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
|
||||
|
||||
// Get the height of the title bar
|
||||
final int titleBarHeight;
|
||||
|
||||
switch (displaymetrics.densityDpi) {
|
||||
|
||||
case DisplayMetrics.DENSITY_HIGH:
|
||||
titleBarHeight = 48;
|
||||
break;
|
||||
|
||||
case DisplayMetrics.DENSITY_MEDIUM:
|
||||
titleBarHeight = 32;
|
||||
break;
|
||||
|
||||
case DisplayMetrics.DENSITY_LOW:
|
||||
titleBarHeight = 24;
|
||||
break;
|
||||
|
||||
default:
|
||||
titleBarHeight = 0;
|
||||
}
|
||||
|
||||
// Get the width and height of the screen
|
||||
final int screenHeight = displaymetrics.heightPixels;
|
||||
final int screenWidth = displaymetrics.widthPixels;
|
||||
|
||||
// Get the current position of the View, that is being dragged
|
||||
final int positionX = (int) event.getX();
|
||||
final int positionY = (int) event.getY();
|
||||
|
||||
if (event.getAction() == DragEvent.ACTION_DRAG_EXITED) {
|
||||
|
||||
removeTabAt(mCurrentDraggedTab);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event.getAction() == DragEvent.ACTION_DROP) {
|
||||
|
||||
// Does it hit the boundries on the x-axis?
|
||||
if ((positionX > screenWidth - (0.25 * mTabsWidth)) ||
|
||||
(positionX < (0.25 * mTabsWidth))) {
|
||||
Log.i("kiwix", "Dragged out");
|
||||
dialog.setTitle(getString(R.string.delete_tab_title));
|
||||
dialog.setMessage(getString(R.string.delete_tab_message));
|
||||
dialog.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
removeTabAt(mCurrentDraggedTab);
|
||||
}
|
||||
// Does it hit the boundries on the y-axis?
|
||||
else if ((positionY > screenHeight - (0.25 * mTabsHeight)) ||
|
||||
((positionY - titleBarHeight) < (0.5 * mTabsHeight))) {
|
||||
Log.i("kiwix", "Dragged out");
|
||||
removeTabAt(mCurrentDraggedTab);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
dialog.setNegativeButton(android.R.string.no, null);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public class State {
|
||||
|
@ -20,6 +20,7 @@
|
||||
package org.kiwix.kiwixmobile;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActionBar;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
@ -32,6 +33,7 @@ import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
@ -39,6 +41,7 @@ import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.TextWatcher;
|
||||
@ -85,6 +88,8 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static org.kiwix.kiwixmobile.BackwardsCompatibilityTools.newApi;
|
||||
|
||||
public class KiwixMobileFragment extends Fragment {
|
||||
|
||||
public static final String TAG_KIWIX = "kiwix";
|
||||
@ -183,14 +188,16 @@ public class KiwixMobileFragment extends Fragment {
|
||||
|
||||
setUpWebView();
|
||||
|
||||
setUpTabDeleteCross();
|
||||
|
||||
setUpArticleSearchTextView(savedInstanceState);
|
||||
|
||||
loadPrefs();
|
||||
|
||||
manageExternalLaunchAndRestoringViewState(savedInstanceState);
|
||||
|
||||
if (newApi()) {
|
||||
setUpTabDeleteCross();
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@ -296,8 +303,8 @@ public class KiwixMobileFragment extends Fragment {
|
||||
if (event.getAction() != MotionEvent.ACTION_UP) {
|
||||
return false;
|
||||
}
|
||||
if (event.getX() > articleSearchtextView.getWidth() - articleSearchtextView.getPaddingRight()
|
||||
- mClearIcon.getIntrinsicWidth()) {
|
||||
if (event.getX() > articleSearchtextView.getWidth()
|
||||
- articleSearchtextView.getPaddingRight() - mClearIcon.getIntrinsicWidth()) {
|
||||
articleSearchtextView.setText("");
|
||||
articleSearchtextView.setCompoundDrawables(mSearchIcon, null, null, null);
|
||||
}
|
||||
@ -316,8 +323,7 @@ public class KiwixMobileFragment extends Fragment {
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
articleSearchtextView.setCompoundDrawables(mSearchIcon, null,
|
||||
articleSearchtextView.getText().toString().equals("") ? null : mClearIcon,
|
||||
null);
|
||||
articleSearchtextView.getText().toString().equals("") ? null : mClearIcon, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -330,15 +336,19 @@ public class KiwixMobileFragment extends Fragment {
|
||||
});
|
||||
|
||||
// Create the adapter and set it to the AutoCompleteTextView
|
||||
adapter = new AutoCompleteAdapter(getActivity(),
|
||||
android.R.layout.simple_list_item_1);
|
||||
if (newApi()) {
|
||||
adapter = new AutoCompleteAdapter(getActivity(), android.R.layout.simple_list_item_1);
|
||||
} else {
|
||||
adapter = new AutoCompleteAdapter(getActivity(), R.layout.simple_list_item);
|
||||
}
|
||||
|
||||
articleSearchtextView.setAdapter(adapter);
|
||||
articleSearchtextView.setOnItemClickListener(new OnItemClickListener() {
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(
|
||||
Context.INPUT_METHOD_SERVICE);
|
||||
InputMethodManager imm = (InputMethodManager)
|
||||
getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(articleSearchtextView.getWindowToken(), 0);
|
||||
articleSearchtextView.setText(parent.getItemAtPosition(position).toString());
|
||||
openArticleFromSearch();
|
||||
@ -347,8 +357,7 @@ public class KiwixMobileFragment extends Fragment {
|
||||
|
||||
articleSearchtextView.setOnEditorActionListener(new OnEditorActionListener() {
|
||||
@Override
|
||||
public boolean onEditorAction(TextView v, int actionId,
|
||||
KeyEvent event) {
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
return openArticleFromSearch();
|
||||
}
|
||||
});
|
||||
@ -356,6 +365,7 @@ public class KiwixMobileFragment extends Fragment {
|
||||
articleSearchtextView.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
private void setUpTabDeleteCross() {
|
||||
|
||||
mTabDeleteCross.setOnDragListener(new View.OnDragListener() {
|
||||
@ -618,7 +628,7 @@ public class KiwixMobileFragment extends Fragment {
|
||||
}
|
||||
break;
|
||||
case PREFERENCES_REQUEST_CODE:
|
||||
if (resultCode == KiwixSettings.RESULT_RESTART) {
|
||||
if (resultCode == KiwixSettingsActivity.RESULT_RESTART) {
|
||||
getActivity().finish();
|
||||
startActivity(new Intent(getActivity(), KiwixMobileActivity.class));
|
||||
}
|
||||
@ -671,8 +681,7 @@ public class KiwixMobileFragment extends Fragment {
|
||||
// Pinch to zoom
|
||||
// This seems to suffer from a bug in Android. If you set to "false" this only apply after a restart of the app.
|
||||
Log.d(TAG_KIWIX, "pref_zoom_enabled value (" + pref_zoom_enabled + ")");
|
||||
webView.getSettings().setBuiltInZoomControls(true);
|
||||
webView.getSettings().setDisplayZoomControls(pref_zoom_enabled);
|
||||
webView.disableZoomControlls(pref_zoom_enabled);
|
||||
|
||||
if (!isBacktotopEnabled) {
|
||||
mBackToTopButton.setVisibility(View.INVISIBLE);
|
||||
@ -699,7 +708,7 @@ public class KiwixMobileFragment extends Fragment {
|
||||
}
|
||||
|
||||
public void selectSettings() {
|
||||
Intent i = new Intent(getActivity(), KiwixSettings.class);
|
||||
Intent i = new Intent(getActivity(), KiwixSettingsActivity.class);
|
||||
startActivityForResult(i, PREFERENCES_REQUEST_CODE);
|
||||
}
|
||||
|
||||
@ -716,8 +725,8 @@ public class KiwixMobileFragment extends Fragment {
|
||||
// Move cursor to end
|
||||
articleSearchtextView.setSelection(articleSearchtextView.getText().length());
|
||||
|
||||
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(
|
||||
Context.INPUT_METHOD_SERVICE);
|
||||
InputMethodManager imm = (InputMethodManager) getActivity()
|
||||
.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
|
||||
}
|
||||
}
|
||||
@ -747,7 +756,8 @@ public class KiwixMobileFragment extends Fragment {
|
||||
if (file.exists()) {
|
||||
if (ZimContentProvider.setZimFile(file.getAbsolutePath()) != null) {
|
||||
|
||||
getActivity().getActionBar().setSubtitle(ZimContentProvider.getZimFileTitle());
|
||||
((ActionBarActivity) getActivity()).getSupportActionBar()
|
||||
.setSubtitle(ZimContentProvider.getZimFileTitle());
|
||||
|
||||
// Apparently with webView.clearHistory() only history before currently (fully)
|
||||
// loaded page is cleared -> request clear, actual clear done after load.
|
||||
@ -1060,10 +1070,9 @@ public class KiwixMobileFragment extends Fragment {
|
||||
failingUrl);
|
||||
// TODO apparently screws up back/forward
|
||||
webView.loadDataWithBaseURL("file://error",
|
||||
"<html><body>" + errorString + "</body></html>", "text/html", "utf-8",
|
||||
failingUrl);
|
||||
"<html><body>" + errorString + "</body></html>", "text/html", "utf-8", failingUrl);
|
||||
String title = getResources().getString(R.string.app_name);
|
||||
getActivity().getActionBar().setTitle(title);
|
||||
((ActionBarActivity) getActivity()).getSupportActionBar().setTitle(title);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1075,12 +1084,13 @@ public class KiwixMobileFragment extends Fragment {
|
||||
title = webView.getTitle();
|
||||
}
|
||||
|
||||
if (getActivity().getActionBar().getTabCount() < 2) {
|
||||
getActivity().getActionBar().setTitle(title);
|
||||
if (((ActionBarActivity) getActivity()).getSupportActionBar().getTabCount() < 2) {
|
||||
((ActionBarActivity) getActivity()).getSupportActionBar().setTitle(title);
|
||||
}
|
||||
|
||||
if (getActivity().getActionBar().getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS) {
|
||||
getActivity().getActionBar().getSelectedTab().setText(title);
|
||||
if (((ActionBarActivity) getActivity()).getSupportActionBar().getNavigationMode()
|
||||
== ActionBar.NAVIGATION_MODE_TABS) {
|
||||
((ActionBarActivity) getActivity()).getSupportActionBar().getSelectedTab().setText(title);
|
||||
}
|
||||
|
||||
// Workaround for #643
|
||||
|
@ -1,130 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 Rashiq Ahmad <rashiq.z@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.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.os.Bundle;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.Preference.OnPreferenceChangeListener;
|
||||
import android.preference.PreferenceFragment;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class KiwixSettings extends Activity {
|
||||
|
||||
public static final int RESULT_RESTART = 1236;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getFragmentManager().beginTransaction().replace(android.R.id.content, new PrefsFragment()).commit();
|
||||
|
||||
new LanguageUtils(this).changeFont(getLayoutInflater());
|
||||
}
|
||||
|
||||
public class PrefsFragment extends PreferenceFragment {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Load the preferences from an XML resource
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
|
||||
prepareListPreferenceForAutoSummary("pref_zoom");
|
||||
setUpLanguageChooser("pref_language_chooser");
|
||||
setAppVersionNumber();
|
||||
}
|
||||
|
||||
private void prepareListPreferenceForAutoSummary(String preferenceId) {
|
||||
|
||||
ListPreference prefList = (ListPreference) findPreference(preferenceId);
|
||||
|
||||
prefList.setDefaultValue(prefList.getEntryValues()[0]);
|
||||
String summary = prefList.getValue();
|
||||
|
||||
if (summary == null) {
|
||||
prefList.setValue((String) prefList.getEntryValues()[0]);
|
||||
summary = prefList.getValue();
|
||||
}
|
||||
|
||||
prefList.setSummary(prefList.getEntries()[prefList.findIndexOfValue(summary)]);
|
||||
prefList.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (preference instanceof ListPreference) {
|
||||
preference.setSummary(((ListPreference) preference)
|
||||
.getEntries()[((ListPreference) preference)
|
||||
.findIndexOfValue(newValue.toString())]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpLanguageChooser(String preferenceId) {
|
||||
|
||||
ListPreference languageList = (ListPreference) findPreference(preferenceId);
|
||||
|
||||
LanguageUtils languageUtils = new LanguageUtils(getActivity());
|
||||
|
||||
languageList.setTitle(Locale.getDefault().getDisplayLanguage());
|
||||
|
||||
languageList.setEntries(languageUtils.getValues().toArray(new String[0]));
|
||||
languageList.setEntryValues(languageUtils.getKeys().toArray(new String[0]));
|
||||
|
||||
languageList.setDefaultValue(Locale.getDefault().toString());
|
||||
|
||||
languageList.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
|
||||
if (!newValue.equals(Locale.getDefault().toString())) {
|
||||
|
||||
LanguageUtils.handleLocaleChange(getActivity(), newValue.toString());
|
||||
// Request a restart when the user returns to the Activity, that called this Activity
|
||||
setResult(RESULT_RESTART);
|
||||
finish();
|
||||
startActivity(new Intent(getActivity(), KiwixSettings.class));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setAppVersionNumber() {
|
||||
String version;
|
||||
|
||||
try {
|
||||
version = getPackageManager().getPackageInfo("org.kiwix.kiwixmobile", 0).versionName;
|
||||
} catch (NameNotFoundException e) {
|
||||
return;
|
||||
}
|
||||
EditTextPreference versionPref = (EditTextPreference) findPreference("pref_version");
|
||||
versionPref.setSummary(version);
|
||||
}
|
||||
}
|
||||
}
|
117
src/org/kiwix/kiwixmobile/KiwixSettingsActivity.java
Normal file
117
src/org/kiwix/kiwixmobile/KiwixSettingsActivity.java
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2013 Rashiq Ahmad <rashiq.z@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.pm.PackageManager.NameNotFoundException;
|
||||
import android.os.Bundle;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.Preference.OnPreferenceChangeListener;
|
||||
import android.preference.PreferenceActivity;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class KiwixSettingsActivity extends PreferenceActivity {
|
||||
|
||||
public static final int RESULT_RESTART = 1236;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
|
||||
prepareListPreferenceForAutoSummary("pref_zoom");
|
||||
setUpLanguageChooser("pref_language_chooser");
|
||||
setAppVersionNumber();
|
||||
new LanguageUtils(this).changeFont(getLayoutInflater());
|
||||
}
|
||||
|
||||
private void prepareListPreferenceForAutoSummary(String preferenceId) {
|
||||
|
||||
ListPreference prefList = (ListPreference) findPreference(preferenceId);
|
||||
|
||||
prefList.setDefaultValue(prefList.getEntryValues()[0]);
|
||||
String summary = prefList.getValue();
|
||||
|
||||
if (summary == null) {
|
||||
prefList.setValue((String) prefList.getEntryValues()[0]);
|
||||
summary = prefList.getValue();
|
||||
}
|
||||
|
||||
prefList.setSummary(prefList.getEntries()[prefList.findIndexOfValue(summary)]);
|
||||
prefList.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (preference instanceof ListPreference) {
|
||||
preference.setSummary(((ListPreference) preference)
|
||||
.getEntries()[((ListPreference) preference)
|
||||
.findIndexOfValue(newValue.toString())]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpLanguageChooser(String preferenceId) {
|
||||
|
||||
ListPreference languageList = (ListPreference) findPreference(preferenceId);
|
||||
|
||||
LanguageUtils languageUtils = new LanguageUtils(KiwixSettingsActivity.this);
|
||||
|
||||
languageList.setTitle(Locale.getDefault().getDisplayLanguage());
|
||||
|
||||
languageList.setEntries(languageUtils.getValues().toArray(new String[0]));
|
||||
|
||||
languageList.setEntryValues(languageUtils.getKeys().toArray(new String[0]));
|
||||
|
||||
languageList.setDefaultValue(Locale.getDefault().toString());
|
||||
|
||||
languageList.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
|
||||
if (!newValue.equals(Locale.getDefault().toString())) {
|
||||
|
||||
LanguageUtils.handleLocaleChange(KiwixSettingsActivity.this, newValue.toString());
|
||||
// Request a restart when the user returns to the Activity, that called this Activity
|
||||
setResult(RESULT_RESTART);
|
||||
finish();
|
||||
startActivity(new Intent(KiwixSettingsActivity.this, KiwixSettingsActivity.class));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setAppVersionNumber() {
|
||||
String version;
|
||||
|
||||
try {
|
||||
version = getPackageManager().getPackageInfo("org.kiwix.kiwixmobile", 0).versionName;
|
||||
} catch (NameNotFoundException e) {
|
||||
return;
|
||||
}
|
||||
EditTextPreference versionPref = (EditTextPreference) findPreference("pref_version");
|
||||
versionPref.setSummary(version);
|
||||
}
|
||||
}
|
@ -21,11 +21,16 @@ package org.kiwix.kiwixmobile;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.webkit.WebView;
|
||||
import android.widget.ZoomButtonsController;
|
||||
|
||||
/*
|
||||
* Custom version of link{@android.webkit.WebView}
|
||||
* to get scroll positions for implimenting the Back to top
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.kiwix.kiwixmobile.BackwardsCompatibilityTools.newApi;
|
||||
|
||||
/**
|
||||
* A custom WebView to get scroll positions for implimenting the Back-To-Top Button
|
||||
*/
|
||||
public class KiwixWebView extends WebView {
|
||||
|
||||
@ -33,6 +38,10 @@ public class KiwixWebView extends WebView {
|
||||
|
||||
private OnLongClickListener mOnLongClickListener;
|
||||
|
||||
private ZoomButtonsController zoomControll = null;
|
||||
|
||||
private boolean mDisableZoomControlls;
|
||||
|
||||
|
||||
public KiwixWebView(Context context) {
|
||||
super(context);
|
||||
@ -63,12 +72,45 @@ public class KiwixWebView extends WebView {
|
||||
int windowHeight = getMeasuredHeight();
|
||||
int pages = getContentHeight() / windowHeight;
|
||||
int page = t / windowHeight;
|
||||
//alert the listeners
|
||||
|
||||
// Alert the listener
|
||||
if (mChangeListener != null) {
|
||||
mChangeListener.onPageChanged(page, pages);
|
||||
}
|
||||
}
|
||||
|
||||
public void disableZoomControlls(boolean disable) {
|
||||
|
||||
mDisableZoomControlls = disable;
|
||||
|
||||
if (newApi()) {
|
||||
getSettings().setBuiltInZoomControls(true);
|
||||
getSettings().setDisplayZoomControls(disable);
|
||||
} else {
|
||||
getZoomControlls();
|
||||
}
|
||||
}
|
||||
|
||||
// Use reflection to hide the zoom controlls
|
||||
private void getZoomControlls() {
|
||||
try {
|
||||
Class webview = Class.forName("android.webkit.WebView");
|
||||
Method method = webview.getMethod("getZoomButtonsController");
|
||||
zoomControll = (ZoomButtonsController) method.invoke(this, null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
super.onTouchEvent(ev);
|
||||
if (zoomControll != null) {
|
||||
zoomControll.setVisible(mDisableZoomControlls);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setOnPageChangedListener(OnPageChangeListener listener) {
|
||||
mChangeListener = listener;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ package org.kiwix.kiwixmobile;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Handler;
|
||||
import android.preference.PreferenceManager;
|
||||
@ -32,6 +33,7 @@ import android.view.InflateException;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
@ -160,11 +162,13 @@ public class LanguageUtils {
|
||||
layoutInflater.setFactory(new LayoutInflaterFactory(mContext, layoutInflater));
|
||||
|
||||
} catch (NoSuchFieldException e) {
|
||||
Log.e("kiwix", "could not access private field of the LayoutInflater");
|
||||
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e("kiwix", "could not access private field of the LayoutInflater");
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
|
||||
Log.e("kiwix", "could not access private field of the LayoutInflater");
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,17 +230,17 @@ public class LanguageUtils {
|
||||
Log.d("kiwix", "Applying custom font");
|
||||
|
||||
// Reduce the text size
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textView.getTextSize() - 3f);
|
||||
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textView.getTextSize() - 2f);
|
||||
}
|
||||
});
|
||||
|
||||
return view;
|
||||
|
||||
} catch (InflateException e) {
|
||||
Log.e("kiwix", "Could not apply the custom font");
|
||||
Log.e("kiwix", "Could not apply the custom font to " + name + " " + e.getMessage());
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
Log.e("kiwix", "Could not apply the custom font");
|
||||
Log.e("kiwix", "Could not apply the custom font to " + name + " " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,12 +249,13 @@ public class LanguageUtils {
|
||||
|
||||
// This method will determine which font will be applied to the not-supported-locale.
|
||||
// You can define exceptions to the default DejaVu font in the 'exceptions' Hashmap:
|
||||
|
||||
private String getTypeface() {
|
||||
|
||||
// Define the exceptions to the rule. The font has to be placed in the assets folder.
|
||||
// Key: the language code; Value: the name of the font.
|
||||
HashMap<String, String> exceptions = new HashMap<String, String>();
|
||||
exceptions.put("my", "Parabaik.ttf");
|
||||
exceptions.put("my", "fonts/Parabaik.ttf");
|
||||
|
||||
// Check, if an exception applies to our current locale
|
||||
if (exceptions.containsKey(Locale.getDefault().getLanguage())) {
|
||||
@ -258,7 +263,7 @@ public class LanguageUtils {
|
||||
}
|
||||
|
||||
// Return the default font
|
||||
return "DejaVuSansCondensed.ttf";
|
||||
return "fonts/DejaVuSansCondensed.ttf";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,11 +19,6 @@
|
||||
|
||||
package org.kiwix.kiwixmobile;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
@ -32,223 +27,238 @@ import android.os.ParcelFileDescriptor;
|
||||
import android.os.ParcelFileDescriptor.AutoCloseOutputStream;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class ZimContentProvider extends ContentProvider {
|
||||
public static final Uri CONTENT_URI = Uri.parse("content://org.kiwix.zim/");
|
||||
public static final Uri UI_URI = Uri.parse("content://org.kiwix.ui/");
|
||||
|
||||
private static String zimFileName;
|
||||
private static JNIKiwix jniKiwix;
|
||||
|
||||
public synchronized static String setZimFile(String fileName) {
|
||||
if (!jniKiwix.loadZIM(fileName)) {
|
||||
Log.e("kiwix", "Unable to open the file " + fileName);
|
||||
zimFileName = null;
|
||||
} else {
|
||||
zimFileName = fileName;
|
||||
}
|
||||
return zimFileName;
|
||||
}
|
||||
public static final Uri CONTENT_URI = Uri.parse("content://org.kiwix.zim/");
|
||||
|
||||
public static final Uri UI_URI = Uri.parse("content://org.kiwix.ui/");
|
||||
|
||||
private static String zimFileName;
|
||||
|
||||
private static JNIKiwix jniKiwix;
|
||||
|
||||
public synchronized static String setZimFile(String fileName) {
|
||||
if (!jniKiwix.loadZIM(fileName)) {
|
||||
Log.e("kiwix", "Unable to open the file " + fileName);
|
||||
zimFileName = null;
|
||||
} else {
|
||||
zimFileName = fileName;
|
||||
}
|
||||
return zimFileName;
|
||||
}
|
||||
|
||||
public static String getZimFile() {
|
||||
return zimFileName;
|
||||
}
|
||||
|
||||
public static String getZimFileTitle() {
|
||||
if (jniKiwix == null || zimFileName == null) {
|
||||
return null;
|
||||
} else {
|
||||
JNIKiwixString title = new JNIKiwixString();
|
||||
if (jniKiwix.getTitle(title)) {
|
||||
return title.value;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getZimFile() {
|
||||
return zimFileName;
|
||||
}
|
||||
public static String getZimFileTitle() {
|
||||
if (jniKiwix==null || zimFileName==null)
|
||||
return null;
|
||||
else {
|
||||
JNIKiwixString title = new JNIKiwixString();
|
||||
if (jniKiwix.getTitle(title)) {
|
||||
return title.value;
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getMainPage() {
|
||||
if (jniKiwix==null || zimFileName==null)
|
||||
return null;
|
||||
else {
|
||||
return jniKiwix.getMainPage();
|
||||
}
|
||||
}
|
||||
if (jniKiwix == null || zimFileName == null) {
|
||||
return null;
|
||||
} else {
|
||||
return jniKiwix.getMainPage();
|
||||
}
|
||||
}
|
||||
|
||||
public static String getId() {
|
||||
if (jniKiwix==null || zimFileName==null)
|
||||
return null;
|
||||
else {
|
||||
return jniKiwix.getId();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean searchSuggestions(String prefix, int count) {
|
||||
if (jniKiwix==null || zimFileName==null)
|
||||
return false;
|
||||
else {
|
||||
return jniKiwix.searchSuggestions(prefix, count);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getNextSuggestion() {
|
||||
if (jniKiwix==null || zimFileName==null)
|
||||
return null;
|
||||
else {
|
||||
JNIKiwixString title=new JNIKiwixString();
|
||||
if (jniKiwix.getNextSuggestion(title)) {
|
||||
return title.value;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getPageUrlFromTitle(String title) {
|
||||
if (jniKiwix==null || zimFileName==null)
|
||||
return null;
|
||||
else {
|
||||
JNIKiwixString url=new JNIKiwixString();
|
||||
if (jniKiwix.getPageUrlFromTitle(title, url)) {
|
||||
return url.value;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getRandomArticleUrl() {
|
||||
if (jniKiwix==null || zimFileName==null)
|
||||
return null;
|
||||
else {
|
||||
JNIKiwixString url=new JNIKiwixString();
|
||||
if (jniKiwix.getRandomPage(url)) {
|
||||
return url.value;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
jniKiwix = new JNIKiwix();
|
||||
|
||||
return (true);
|
||||
}
|
||||
if (jniKiwix == null || zimFileName == null) {
|
||||
return null;
|
||||
} else {
|
||||
return jniKiwix.getId();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(Uri uri) {
|
||||
Log.w("kiwix", "ZimContentProvider.getType() (not implemented) called");
|
||||
return null;
|
||||
}
|
||||
public static boolean searchSuggestions(String prefix, int count) {
|
||||
if (jniKiwix == null || zimFileName == null) {
|
||||
return false;
|
||||
} else {
|
||||
return jniKiwix.searchSuggestions(prefix, count);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelFileDescriptor openFile(Uri uri, String mode)
|
||||
throws FileNotFoundException {
|
||||
ParcelFileDescriptor[] pipe = null;
|
||||
public static String getNextSuggestion() {
|
||||
if (jniKiwix == null || zimFileName == null) {
|
||||
return null;
|
||||
} else {
|
||||
JNIKiwixString title = new JNIKiwixString();
|
||||
if (jniKiwix.getNextSuggestion(title)) {
|
||||
return title.value;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
pipe = ParcelFileDescriptor.createPipe();
|
||||
new TransferThread(jniKiwix, uri, new AutoCloseOutputStream(
|
||||
pipe[1])).start();
|
||||
} catch (IOException e) {
|
||||
Log.e(getClass().getSimpleName(), "Exception opening pipe", e);
|
||||
throw new FileNotFoundException("Could not open pipe for: "
|
||||
+ uri.toString());
|
||||
}
|
||||
public static String getPageUrlFromTitle(String title) {
|
||||
if (jniKiwix == null || zimFileName == null) {
|
||||
return null;
|
||||
} else {
|
||||
JNIKiwixString url = new JNIKiwixString();
|
||||
if (jniKiwix.getPageUrlFromTitle(title, url)) {
|
||||
return url.value;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (pipe[0]);
|
||||
}
|
||||
public static String getRandomArticleUrl() {
|
||||
if (jniKiwix == null || zimFileName == null) {
|
||||
return null;
|
||||
} else {
|
||||
JNIKiwixString url = new JNIKiwixString();
|
||||
if (jniKiwix.getRandomPage(url)) {
|
||||
return url.value;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(Uri url, String[] projection, String selection,
|
||||
String[] selectionArgs, String sort) {
|
||||
throw new RuntimeException("Operation not supported");
|
||||
}
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
jniKiwix = new JNIKiwix();
|
||||
|
||||
@Override
|
||||
public Uri insert(Uri uri, ContentValues initialValues) {
|
||||
throw new RuntimeException("Operation not supported");
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(Uri uri, ContentValues values, String where,
|
||||
String[] whereArgs) {
|
||||
throw new RuntimeException("Operation not supported");
|
||||
}
|
||||
@Override
|
||||
public String getType(Uri uri) {
|
||||
Log.w("kiwix", "ZimContentProvider.getType() (not implemented) called");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(Uri uri, String where, String[] whereArgs) {
|
||||
throw new RuntimeException("Operation not supported");
|
||||
}
|
||||
@Override
|
||||
public ParcelFileDescriptor openFile(Uri uri, String mode)
|
||||
throws FileNotFoundException {
|
||||
ParcelFileDescriptor[] pipe = null;
|
||||
|
||||
static class TransferThread extends Thread {
|
||||
try {
|
||||
pipe = ParcelFileDescriptor.createPipe();
|
||||
new TransferThread(jniKiwix, uri, new AutoCloseOutputStream(
|
||||
pipe[1])).start();
|
||||
} catch (IOException e) {
|
||||
Log.e(getClass().getSimpleName(), "Exception opening pipe", e);
|
||||
throw new FileNotFoundException("Could not open pipe for: "
|
||||
+ uri.toString());
|
||||
}
|
||||
|
||||
Uri articleUri;
|
||||
String articleZimUrl;
|
||||
OutputStream out;
|
||||
JNIKiwix jniKiwix;
|
||||
return (pipe[0]);
|
||||
}
|
||||
|
||||
TransferThread(JNIKiwix jniKiwix, Uri articleUri, OutputStream out) throws IOException {
|
||||
this.articleUri = articleUri;
|
||||
this.jniKiwix = jniKiwix;
|
||||
Log.d("kiwix",
|
||||
"Retrieving :"
|
||||
+ articleUri.toString());
|
||||
|
||||
String t = articleUri.toString();
|
||||
int pos = articleUri.toString().indexOf(CONTENT_URI.toString());
|
||||
if (pos != -1)
|
||||
t = articleUri.toString().substring(
|
||||
CONTENT_URI.toString().length());
|
||||
// Remove fragment (#...) as not supported by zimlib
|
||||
pos = t.indexOf("#");
|
||||
if (pos != -1) {
|
||||
t = t.substring(0, pos);
|
||||
}
|
||||
|
||||
this.out = out;
|
||||
this.articleZimUrl = t;
|
||||
}
|
||||
@Override
|
||||
public Cursor query(Uri url, String[] projection, String selection,
|
||||
String[] selectionArgs, String sort) {
|
||||
throw new RuntimeException("Operation not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
@Override
|
||||
public Uri insert(Uri uri, ContentValues initialValues) {
|
||||
throw new RuntimeException("Operation not supported");
|
||||
}
|
||||
|
||||
try {
|
||||
JNIKiwixString mime = new JNIKiwixString();
|
||||
JNIKiwixInt size = new JNIKiwixInt();
|
||||
byte[] data = jniKiwix.getContent(articleZimUrl, mime, size);
|
||||
// Log.d("kiwix","articleDataByteArray:"+articleDataByteArray.toString());
|
||||
// ByteArrayInputStream articleDataInputStream = new
|
||||
// ByteArrayInputStream(articleDataByteArray.toByteArray());
|
||||
// Log.d("kiwix","article data loaded from zime file");
|
||||
@Override
|
||||
public int update(Uri uri, ContentValues values, String where,
|
||||
String[] whereArgs) {
|
||||
throw new RuntimeException("Operation not supported");
|
||||
}
|
||||
|
||||
//ByteArrayInputStream articleDataInputStream = new ByteArrayInputStream(
|
||||
// articleDataByteArray.toByteArray());
|
||||
ByteArrayInputStream articleDataInputStream = new ByteArrayInputStream(data);
|
||||
while ((len = articleDataInputStream.read(buf)) > 0) {
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
@Override
|
||||
public int delete(Uri uri, String where, String[] whereArgs) {
|
||||
throw new RuntimeException("Operation not supported");
|
||||
}
|
||||
|
||||
articleDataInputStream.close();
|
||||
out.flush();
|
||||
static class TransferThread extends Thread {
|
||||
|
||||
Log.d("kiwix", "reading " + articleZimUrl
|
||||
+ "(mime "+mime.value+", size: "+size.value+") finished.");
|
||||
} catch (IOException e) {
|
||||
Log.e(getClass().getSimpleName(), "Exception reading article "
|
||||
+ articleZimUrl + " from zim file", e);
|
||||
} catch (NullPointerException e) {
|
||||
Log.e(getClass().getSimpleName(), "Exception reading article "
|
||||
+ articleZimUrl + " from zim file", e);
|
||||
Uri articleUri;
|
||||
|
||||
} finally {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
String articleZimUrl;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
OutputStream out;
|
||||
|
||||
JNIKiwix jniKiwix;
|
||||
|
||||
TransferThread(JNIKiwix jniKiwix, Uri articleUri, OutputStream out) throws IOException {
|
||||
this.articleUri = articleUri;
|
||||
this.jniKiwix = jniKiwix;
|
||||
Log.d("kiwix",
|
||||
"Retrieving :"
|
||||
+ articleUri.toString());
|
||||
|
||||
String t = articleUri.toString();
|
||||
int pos = articleUri.toString().indexOf(CONTENT_URI.toString());
|
||||
if (pos != -1) {
|
||||
t = articleUri.toString().substring(
|
||||
CONTENT_URI.toString().length());
|
||||
}
|
||||
// Remove fragment (#...) as not supported by zimlib
|
||||
pos = t.indexOf("#");
|
||||
if (pos != -1) {
|
||||
t = t.substring(0, pos);
|
||||
}
|
||||
|
||||
this.out = out;
|
||||
this.articleZimUrl = t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
|
||||
try {
|
||||
JNIKiwixString mime = new JNIKiwixString();
|
||||
JNIKiwixInt size = new JNIKiwixInt();
|
||||
byte[] data = jniKiwix.getContent(articleZimUrl, mime, size);
|
||||
// Log.d("kiwix","articleDataByteArray:"+articleDataByteArray.toString());
|
||||
// ByteArrayInputStream articleDataInputStream = new
|
||||
// ByteArrayInputStream(articleDataByteArray.toByteArray());
|
||||
// Log.d("kiwix","article data loaded from zime file");
|
||||
|
||||
//ByteArrayInputStream articleDataInputStream = new ByteArrayInputStream(
|
||||
// articleDataByteArray.toByteArray());
|
||||
ByteArrayInputStream articleDataInputStream = new ByteArrayInputStream(data);
|
||||
while ((len = articleDataInputStream.read(buf)) > 0) {
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
|
||||
articleDataInputStream.close();
|
||||
out.flush();
|
||||
|
||||
Log.d("kiwix", "reading " + articleZimUrl
|
||||
+ "(mime " + mime.value + ", size: " + size.value + ") finished.");
|
||||
} catch (IOException e) {
|
||||
Log.e(getClass().getSimpleName(), "Exception reading article "
|
||||
+ articleZimUrl + " from zim file", e);
|
||||
} catch (NullPointerException e) {
|
||||
Log.e(getClass().getSimpleName(), "Exception reading article "
|
||||
+ articleZimUrl + " from zim file", e);
|
||||
|
||||
} finally {
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
|
||||
package org.kiwix.kiwixmobile;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
@ -27,17 +28,18 @@ import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.widget.SimpleCursorAdapter;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AlphaAnimation;
|
||||
import android.widget.Adapter;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
@ -45,12 +47,13 @@ import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ZimFileSelectActivity extends FragmentActivity
|
||||
public class ZimFileSelectActivity extends ActionBarActivity
|
||||
implements LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener {
|
||||
|
||||
private static final int LOADER_ID = 0x02;
|
||||
@ -80,11 +83,12 @@ public class ZimFileSelectActivity extends FragmentActivity
|
||||
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
|
||||
mProgressBarMessage = (TextView) findViewById(R.id.progressbar_message);
|
||||
mZimFileList = (ListView) findViewById(R.id.zimfilelist);
|
||||
mFiles = new ArrayList<DataModel>();
|
||||
|
||||
mZimFileList.setOnItemClickListener(this);
|
||||
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
// mZimFileList.setAlpha(0.4f);
|
||||
|
||||
mFiles = new ArrayList<DataModel>();
|
||||
setAlpha(true);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
startQuery();
|
||||
@ -93,8 +97,10 @@ public class ZimFileSelectActivity extends FragmentActivity
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
|
||||
|
||||
Uri uri = MediaStore.Files.getContentUri("external");
|
||||
|
||||
String[] projection = {
|
||||
@ -137,7 +143,7 @@ public class ZimFileSelectActivity extends FragmentActivity
|
||||
|
||||
if (mProgressBarMessage.getVisibility() == View.GONE) {
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
// mZimFileList.setAlpha(1f);
|
||||
setAlpha(false);
|
||||
}
|
||||
|
||||
mCursorAdapter.notifyDataSetChanged();
|
||||
@ -241,8 +247,6 @@ public class ZimFileSelectActivity extends FragmentActivity
|
||||
// Flags for the Adapter
|
||||
Adapter.NO_SELECTION);
|
||||
|
||||
mZimFileList.setOnItemClickListener(this);
|
||||
|
||||
getSupportLoaderManager().initLoader(LOADER_ID, null, this);
|
||||
}
|
||||
|
||||
@ -290,6 +294,21 @@ public class ZimFileSelectActivity extends FragmentActivity
|
||||
}
|
||||
}
|
||||
|
||||
// Make the View transparent or opaque
|
||||
private void setAlpha(boolean transparent) {
|
||||
|
||||
float viewTransparency = transparent ? 0.4F : 1F;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
mZimFileList.setAlpha(viewTransparency);
|
||||
} else {
|
||||
AlphaAnimation alpha = new AlphaAnimation(viewTransparency, viewTransparency);
|
||||
alpha.setDuration(0);
|
||||
alpha.setFillAfter(true);
|
||||
mZimFileList.startAnimation(alpha);
|
||||
}
|
||||
}
|
||||
|
||||
// The Adapter for the ListView for when the ListView is populated with the rescanned files
|
||||
private class RescanDataAdapter extends ArrayAdapter<DataModel> {
|
||||
|
||||
@ -336,7 +355,7 @@ public class ZimFileSelectActivity extends FragmentActivity
|
||||
|
||||
mProgressBarMessage.setVisibility(View.VISIBLE);
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
// mZimFileList.setAlpha(0.4f);
|
||||
setAlpha(true);
|
||||
|
||||
super.onPreExecute();
|
||||
}
|
||||
@ -356,12 +375,11 @@ public class ZimFileSelectActivity extends FragmentActivity
|
||||
|
||||
mProgressBarMessage.setVisibility(View.GONE);
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
// mZimFileList.setAlpha(1f);
|
||||
setAlpha(false);
|
||||
|
||||
new FileWriter(ZimFileSelectActivity.this).saveArray(mFiles);
|
||||
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user