Android local ZIM files are stored in Database #278

This commit is contained in:
mhutti1 2016-08-20 22:17:21 +01:00
parent 35a9749cf7
commit cdc095c69c
10 changed files with 171 additions and 165 deletions

View File

@ -1,8 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/progress_background"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/progressbar_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_marginTop="300dp">
<View
android:layout_width="match_parent"
android:layout_height="5dp"
android:orientation="horizontal">
android:layout_height="wrap_content"
android:background="?android:attr/listDivider"
android:layout_marginTop="-1dp"
/>
</LinearLayout>
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleLarge"
android:padding="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"></ProgressBar>
<TextView
android:id="@+id/progressbar_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/progressBar"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:paddingTop="10px"
android:text="@string/rescan_fs_warning"
android:textStyle="bold" />
</RelativeLayout>

View File

@ -25,7 +25,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar"
android:paddingBottom="60dp">
android:paddingBottom="60dp"
android:footerDividersEnabled="false">
</ListView>
<TextView
@ -39,38 +40,6 @@
android:paddingRight="10dp"
android:text="@string/error_nozimfilesfound"
android:visibility="gone"/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/progressbar_layout"
android:visibility="gone"
android:layout_centerInParent="true"
android:layout_marginTop="300dp">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
</ProgressBar>
<TextView
android:id="@+id/progressbar_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/rescan_fs_warning"
android:paddingTop="10px"
android:textStyle="bold"
android:layout_below="@id/progressBar"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
/>
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>

View File

@ -95,6 +95,7 @@
<string name="menu_library">Download ZIM files</string>
<string name="local_zims">Local</string>
<string name="remote_zims">Remote</string>
<string name="zim_downloads">Downloads</string>
<string name="zim_manager">ZIM Management</string>
<string name="delete_specific_zim">Delete this ZIM?</string>
<string name="delete_specific_zim_toast">ZIM file deleted</string>

View File

@ -189,7 +189,6 @@ public class LibraryFragment extends Fragment implements AdapterView.OnItemClick
+ bytesToHuman(getSpaceAvailable()), Toast.LENGTH_LONG).show();
return;
}
bookDao.saveBook((LibraryNetworkEntity.Book) parent.getAdapter().getItem(position));
if (isWiFi()){
downloadFile((LibraryNetworkEntity.Book) parent.getAdapter().getItem(position));
} else {
@ -259,7 +258,6 @@ public class LibraryFragment extends Fragment implements AdapterView.OnItemClick
}
public void downloadFile(LibraryNetworkEntity.Book book) {
bookDao.saveBook(book);
Toast.makeText(super.getActivity(), stringsGetter(R.string.download_started_library, super.getActivity()), Toast.LENGTH_LONG).show();
Intent service = new Intent(super.getActivity(), DownloadService.class);
service.putExtra(DownloadIntent.DOWNLOAD_URL_PARAMETER, book.getUrl());

View File

@ -64,6 +64,9 @@ import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.kiwix.kiwixmobile.database.BookDao;
@ -85,17 +88,16 @@ public class ZimFileSelectFragment extends Fragment
private static final int LOADER_ID = 0x02;
public static Context context;
public RelativeLayout llLayout;
// Adapter of the Data populated by the MediaStore
private SimpleCursorAdapter mCursorAdapter;
// Adapter of the Data populated by recanning the Filesystem by ourselves
private RescanDataAdapter mRescanAdapter;
private ArrayList<LibraryNetworkEntity.Book> mFiles;
private ListView mZimFileList;
private RelativeLayout mProgressBar;
private RelativeLayout progressBar;
private TextView mFileMessage;
private TextView mProgressBarMessage;
private BookDao bookDao;
public static void finishResult(String path) {
ZimManageActivity zimManageActivity = (ZimManageActivity) context;
if (path != null) {
@ -110,42 +112,53 @@ public class ZimFileSelectFragment extends Fragment
}
}
public void refreshFragment(){
// Of course you will want to faActivity and llLayout in the class and not this method to access them in the rest of
// the class, just initialize them here
if (mZimFileList == null)
return;
mZimFileList.addFooterView(progressBar);
mZimFileList.setOnItemClickListener(this);
mZimFileList.setOnItemLongClickListener(this);
bookDao = new BookDao(new KiwixDatabase(context));
mFiles = bookDao.getBooks();
Collections.sort(mFiles, new fileComparator());
mRescanAdapter = new RescanDataAdapter(ZimFileSelectFragment.context, 0, mFiles);
mZimFileList.setAdapter(mRescanAdapter);
mRescanAdapter.notifyDataSetChanged();
checkPermissions();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
FragmentActivity faActivity = (FragmentActivity) super.getActivity();
context = super.getActivity();
// Replace LinearLayout by the type of the root element of the layout you're trying to load
llLayout = (RelativeLayout) inflater.inflate(R.layout.zim_list, container, false);
// Of course you will want to faActivity and llLayout in the class and not this method to access them in the rest of
// the class, just initialize them here
new LanguageUtils(super.getActivity()).changeFont(super.getActivity().getLayoutInflater());
mFiles = new ArrayList<LibraryNetworkEntity.Book>();
mProgressBar = (RelativeLayout) llLayout.findViewById(R.id.progressbar_layout);
mFileMessage = (TextView) llLayout.findViewById(R.id.file_management_no_files);
// mProgressBarMessage = (TextView) llLayout.findViewById(R.id.progressbar_message);
mZimFileList = (ListView) llLayout.findViewById(R.id.zimfilelist);
mZimFileList.setOnItemClickListener(this);
mZimFileList.setOnItemLongClickListener(this);
mProgressBar.setVisibility(View.VISIBLE);
mFiles = new ArrayList<LibraryNetworkEntity.Book>();
progressBar = (RelativeLayout) super.getActivity().getLayoutInflater().inflate(R.layout.progress_bar, null);
refreshFragment();
bookDao = new BookDao(new KiwixDatabase(context));
checkPermissions();
// Don't use this method, it's handled by inflater.inflate() above :
// setContentView(R.layout.activity_layout);
// The FragmentActivity doesn't contain the layout directly so we must use our instance of LinearLayout :
//llLayout.findViewById(R.id.someGuiElement);
// Instead of :
// findViewById(R.id.someGuiElement);
return llLayout; // We must return the loaded Layout
}
private class fileComparator implements Comparator<LibraryNetworkEntity.Book> {
@Override
public int compare(LibraryNetworkEntity.Book b1, LibraryNetworkEntity.Book b2) {
return b1.getTitle().compareTo(b2.getTitle());
}
}
public void checkPermissions(){
if (ContextCompat.checkSelfPermission(super.getActivity(),
Manifest.permission.READ_EXTERNAL_STORAGE)
@ -384,8 +397,6 @@ public class ZimFileSelectFragment extends Fragment
@Override
protected void onPreExecute() {
mProgressBar.setVisibility(View.VISIBLE);
super.onPreExecute();
}
@ -393,6 +404,8 @@ public class ZimFileSelectFragment extends Fragment
protected Void doInBackground(Void... params) {
mFiles = new FileSearch().findFiles();
Collections.sort(mFiles, new fileComparator());
bookDao.saveBooks(mFiles);
return null;
}
@Override
@ -401,12 +414,11 @@ public class ZimFileSelectFragment extends Fragment
mZimFileList.setAdapter(mRescanAdapter);
mProgressBar.setVisibility(View.GONE);
mZimFileList.removeFooterView(progressBar);
//mZimFileList.addFooterView(emptyView);
checkEmpty();
new FileWriter(ZimFileSelectFragment.context).saveArray(mFiles);
super.onPostExecute(result);
}
}

View File

@ -6,6 +6,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.database.DataSetObserver;
import android.support.design.widget.TabLayout;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
@ -63,6 +64,10 @@ public class ZimManageActivity extends AppCompatActivity {
public Toolbar toolbar;
public MenuItem refeshItem;
private MenuItem searchItem;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -82,11 +87,43 @@ public class ZimManageActivity extends AppCompatActivity {
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
getIntent().getIntExtra(TAB_EXTRA,0);
mViewPager.setCurrentItem(getIntent().getIntExtra(TAB_EXTRA,0));
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
updateMenu(position);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
private void updateMenu(int position){
if (searchItem == null)
return;
switch (position){
case 0:
refeshItem.setVisible(true);
searchItem.setVisible(false);
break;
case 1:
refeshItem.setVisible(false);
searchItem.setVisible(true);
break;
case 2:
refeshItem.setVisible(false);
searchItem.setVisible(false);
break;
}
}
private void setUpToolbar() {
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
@ -130,19 +167,15 @@ public class ZimManageActivity extends AppCompatActivity {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_zim_manager, menu);
mMenu = menu;
SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
menu.findItem(R.id.action_search).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener(){
@Override
public boolean onMenuItemClick(MenuItem v) {
mViewPager.setCurrentItem(1);
return true;
}
});
refeshItem = (MenuItem) menu.findItem(R.id.menu_rescan_fs);
searchItem = (MenuItem) menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
updateMenu(mViewPager.getCurrentItem());
toolbar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mViewPager.setCurrentItem(1);
MenuItemCompat.expandActionView(menu.findItem(R.id.action_search));
if (mViewPager.getCurrentItem() == 1)
MenuItemCompat.expandActionView(menu.findItem(R.id.action_search));
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@ -173,10 +206,8 @@ public class ZimManageActivity extends AppCompatActivity {
if (id == R.id.menu_rescan_fs){
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
int position = mViewPager.getCurrentItem();
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setCurrentItem(position);
ZimFileSelectFragment fragment = (ZimFileSelectFragment) mSectionsPagerAdapter.getItem(0);
fragment.refreshFragment();
// mViewPager.notify();
}
//noinspection SimplifiableIfStatement
@ -191,6 +222,12 @@ public class ZimManageActivity extends AppCompatActivity {
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private ZimFileSelectFragment zimFileSelectFragment = new ZimFileSelectFragment();
private LibraryFragment libraryFragment = new LibraryFragment();
private DownloadFragment downloadFragment = new DownloadFragment();
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@ -200,11 +237,11 @@ public class ZimManageActivity extends AppCompatActivity {
// getItem is called to instantiate the fragment for the given page.
switch (position) {
case 0:
return new ZimFileSelectFragment();
return zimFileSelectFragment;
case 1:
return new LibraryFragment();
return libraryFragment;
case 2:
return new DownloadFragment();
return downloadFragment;
default:
return null;
}
@ -223,7 +260,7 @@ public class ZimManageActivity extends AppCompatActivity {
case 1:
return getResources().getString(R.string.remote_zims);
case 2:
return "Downloads";
return getResources().getString(R.string.zim_downloads);
}
return null;
}

View File

@ -8,7 +8,10 @@ import org.kiwix.kiwixmobile.database.entity.BookDataSource;
import org.kiwix.kiwixmobile.database.entity.BookDatabaseEntity;
import org.kiwix.kiwixmobile.database.entity.Bookmarks;
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity;
import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity.Book;
import java.io.File;
import java.util.ArrayList;
/**
@ -24,13 +27,13 @@ public class BookDao {
}
public LibraryNetworkEntity.Book getBook(String fileName) {
public ArrayList<Book> getBooks() {
SquidCursor<BookDatabaseEntity> bookCursor = mDb.query(
BookDatabaseEntity.class,
Query.select());
LibraryNetworkEntity.Book book = new LibraryNetworkEntity.Book();
ArrayList<Book> books = new ArrayList<>();
while (bookCursor.moveToNext()){
if (bookCursor.get(BookDatabaseEntity.URL).contains("/" + fileName + ".")) {
Book book = new Book();
book.id = bookCursor.get(BookDatabaseEntity.BOOK_ID);
book.title = bookCursor.get(BookDatabaseEntity.TITLE);
book.description = bookCursor.get(BookDatabaseEntity.DESCRIPTION);
@ -38,38 +41,41 @@ public class BookDao {
book.creator = bookCursor.get(BookDatabaseEntity.BOOK_CREATOR);
book.publisher = bookCursor.get(BookDatabaseEntity.PUBLISHER);
book.date = bookCursor.get(BookDatabaseEntity.DATE);
book.url = bookCursor.get(BookDatabaseEntity.URL);
book.file = new File(bookCursor.get(BookDatabaseEntity.URL));
book.articleCount = bookCursor.get(BookDatabaseEntity.ARTICLE_COUNT);
book.mediaCount = bookCursor.get(BookDatabaseEntity.MEDIA_COUNT);
book.size = bookCursor.get(BookDatabaseEntity.SIZE);
book.favicon = bookCursor.get(BookDatabaseEntity.FAVICON);
book.downloaded = bookCursor.get(BookDatabaseEntity.DOWNLOADED);
bookCursor.close();
return book;
if (book.file.exists()) {
books.add(book);
} else {
String path = bookCursor.get(BookDatabaseEntity.URL);
mDb.deleteWhere(BookDatabaseEntity.class, BookDatabaseEntity.URL.eq(path));
}
}
}
bookCursor.close();
return null;
return books;
}
public void saveBook(LibraryNetworkEntity.Book book) {
BookDatabaseEntity bookDatabaseEntity = new BookDatabaseEntity();
bookDatabaseEntity.setBookId(book.getId());
bookDatabaseEntity.setTitle(book.getTitle());
bookDatabaseEntity.setDescription(book.getTitle());
bookDatabaseEntity.setLanguage(book.getLanguage());
bookDatabaseEntity.setBookCreator(book.getCreator());
bookDatabaseEntity.setPublisher(book.getPublisher());
bookDatabaseEntity.setDate(book.getDate());
bookDatabaseEntity.setUrl(book.getUrl());
bookDatabaseEntity.setArticleCount(book.getArticleCount());
bookDatabaseEntity.setMediaCount(book.getMediaCount());
bookDatabaseEntity.setSize(book.getSize());
bookDatabaseEntity.setFavicon(book.getFavicon());
bookDatabaseEntity.setIsDownloaded(book.downloaded);
mDb.deleteWhere(BookDatabaseEntity.class, BookDatabaseEntity.URL.eq(book.getUrl()));
mDb.persist(bookDatabaseEntity);
public void saveBooks(ArrayList<Book> books) {
for (Book book : books){
BookDatabaseEntity bookDatabaseEntity = new BookDatabaseEntity();
bookDatabaseEntity.setBookId(book.getId());
bookDatabaseEntity.setTitle(book.getTitle());
bookDatabaseEntity.setDescription(book.getDescription());
bookDatabaseEntity.setLanguage(book.getLanguage());
bookDatabaseEntity.setBookCreator(book.getCreator());
bookDatabaseEntity.setPublisher(book.getPublisher());
bookDatabaseEntity.setDate(book.getDate());
bookDatabaseEntity.setUrl(book.file.getPath());
bookDatabaseEntity.setArticleCount(book.getArticleCount());
bookDatabaseEntity.setMediaCount(book.getMediaCount());
bookDatabaseEntity.setSize(book.getSize());
bookDatabaseEntity.setFavicon(book.getFavicon());
String filePath = book.file.getPath();
mDb.deleteWhere(BookDatabaseEntity.class, BookDatabaseEntity.URL.eq(filePath));
mDb.persist(bookDatabaseEntity);
}
}
}

View File

@ -51,7 +51,7 @@ import java.util.List;
public class KiwixDatabase extends SquidDatabase {
private static final int VERSION = 8;
private static final int VERSION = 9;
private Context context;
@ -113,6 +113,10 @@ public class KiwixDatabase extends SquidDatabase {
if (newVersion >= 6) {
tryCreateTable(Bookmarks.TABLE);
}
if (newVersion >= 9) {
db.execSQL("DROP TABLE IF EXISTS book");
tryCreateTable(BookDatabaseEntity.TABLE);
}
return true;
}

View File

@ -154,7 +154,6 @@ public class DownloadService extends Service {
target, PendingIntent.FLAG_CANCEL_CURRENT);
book.downloaded = true;
notification.get(notificationID).setContentIntent(pendingIntent);
bookDao.saveBook(book);
updateForeground();
} else if (progress == 0) {
// Tells android to not kill the service

View File

@ -52,23 +52,6 @@ public class FileWriter {
mContext = context;
}
// Build a CSV list from the file paths
public void saveArray(ArrayList<LibraryNetworkEntity.Book> files) {
ArrayList<String> list = new ArrayList<>();
for (LibraryNetworkEntity.Book file : files) {
list.add(file.file.getPath());
}
StringBuilder sb = new StringBuilder();
for (String s : list) {
sb.append(s);
sb.append(",");
}
saveCsvToPrefrences(sb.toString());
}
// Read the locales.txt file in the assets folder, that has been created at compile time by the
// build script
@ -91,15 +74,6 @@ public class FileWriter {
return readCsv(content);
}
// Split the CSV by the comma and return an ArrayList with the file paths
private ArrayList<String> readCsv() {
String csv = getCsvFromPrefrences();
return readCsv(csv);
}
private ArrayList<String> readCsv(String csv) {
String[] csvArray = csv.split(",");
@ -107,27 +81,6 @@ public class FileWriter {
return new ArrayList<String>(Arrays.asList(csvArray));
}
// Save a CSV file to the prefrences
private void saveCsvToPrefrences(String csv) {
SharedPreferences preferences = mContext.getSharedPreferences(PREF_NAME, 0);
SharedPreferences.Editor editor = preferences.edit();
editor.putString(CSV_PREF_NAME, csv);
editor.apply();
}
// Load the CSV from the prefrences
private String getCsvFromPrefrences() {
SharedPreferences preferences = mContext.getSharedPreferences(PREF_NAME, 0);
return preferences.getString(CSV_PREF_NAME, "");
}
// Remove the file path and the extension and return a file name for the given file path
private String getTitleFromFilePath(String path) {
return new File(path).getName().replaceFirst("[.][^.]+$", "");
}
}