Settings + adding mutexes whenever possible.
This commit is contained in:
parent
6f234a435c
commit
75dd42a703
@ -23,9 +23,31 @@
|
||||
android:screenOrientation="portrait" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data android:name="android.app.searchable"
|
||||
android:resource="@xml/searchable" />
|
||||
|
||||
|
||||
</activity>
|
||||
<!--
|
||||
<activity
|
||||
android:name=".SearchResultActivity"
|
||||
android:label="@string/app_name"
|
||||
android:configChanges="orientation"
|
||||
android:screenOrientation="portrait" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEARCH" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data android:name="android.app.searchable"
|
||||
android:resource="@xml/searchable" />
|
||||
|
||||
|
||||
</activity>
|
||||
|
||||
-->
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 7.7 KiB |
Binary file not shown.
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 48 KiB |
@ -2,7 +2,6 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/background"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
|
@ -32,7 +32,6 @@
|
||||
android:background="@drawable/see_more_button"
|
||||
android:gravity="right|center_vertical"
|
||||
android:paddingRight="28dp"
|
||||
android:text="Узнать больше"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -9,7 +9,7 @@
|
||||
tools:context="fishrungames.bashgid.MainPageFragment" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView1"
|
||||
android:id="@+id/selectLanguageTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
|
@ -32,14 +32,12 @@
|
||||
android:gravity="left|center_vertical"
|
||||
android:minHeight="0dip"
|
||||
android:minWidth="0dip"
|
||||
android:text="yrrttedf"
|
||||
android:textColor="@color/text_grey" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="rtrrtrt" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto" >
|
||||
|
||||
<item android:id="@+id/search"
|
||||
<item android:id="@+id/action_search"
|
||||
android:title="@string/search_title"
|
||||
android:icon="@drawable/abc_ic_search_api_mtrl_alpha"
|
||||
app:showAsAction="always"
|
||||
|
@ -8,6 +8,9 @@
|
||||
|
||||
<string name="action_settings">Настройки</string>
|
||||
|
||||
<string name="select_language">Выберите язык:</string>
|
||||
|
||||
|
||||
<string name="search_title">Поиск</string>
|
||||
|
||||
<string name="news_record_not_available">Запись недоступна</string>
|
||||
|
@ -6,6 +6,9 @@
|
||||
<string name="navigation_drawer_close">关闭导航窗口</string>
|
||||
<string name="action_settings">设置</string>
|
||||
|
||||
<string name="select_language">选择语言:</string>
|
||||
|
||||
|
||||
<string name="search_title">搜索标题</string>
|
||||
|
||||
<string name="news_record_not_available">无法查看新闻记录</string>
|
||||
|
@ -7,14 +7,17 @@
|
||||
<string name="action_settings">Settings</string>
|
||||
|
||||
|
||||
<string name="select_language">Select language:</string>
|
||||
|
||||
<string name="lang_english">English</string>
|
||||
<string name="lang_russian">Русский</string>
|
||||
<string name="lang_chinese">中文</string>
|
||||
|
||||
|
||||
|
||||
|
||||
<string name="search_title">Search</string>
|
||||
<string name="search_hint">Search hint</string>
|
||||
|
||||
|
||||
<string name="news_record_not_available">Record is not available</string>
|
||||
<string name="other_news">Other news…</string>
|
||||
|
@ -6,103 +6,105 @@ import java.util.Locale;
|
||||
import fishrungames.bashgid.core.NewsManager.NewsRecord;
|
||||
import fishrungames.bashgid.core.db.NewsDataSource;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.widget.SearchView;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.app.SearchManager;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
|
||||
public class MainActivity extends ActionBarActivity implements NavigationDrawerFragment.NavigationDrawerCallbacks
|
||||
{
|
||||
|
||||
|
||||
|
||||
public class MainActivity extends ActionBarActivity
|
||||
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
|
||||
|
||||
|
||||
public static final String TAG_FROM_MAINFRAGMENT_TO_NEWSRECORDFRAGMENT = "TAG_FROM_MAINFRAGMENT_TO_NEWSRECORDFRAGMENT";
|
||||
public static final String TAG_FROM_NEWSLISTFRAGMENT_TO_NEWSRECORDFRAGMENT = "TAG_FROM_NEWSLISTFRAGMENT_TO_NEWSRECORDFRAGMENT";
|
||||
|
||||
static MainActivity instance = null;
|
||||
|
||||
private NavigationDrawerFragment mNavigationDrawerFragment = null;
|
||||
|
||||
public NewsDataSource newsDataSource;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
SetupDrawer();
|
||||
|
||||
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, new WelcomeFragment()).commit();
|
||||
|
||||
instance = this;
|
||||
|
||||
newsDataSource = new NewsDataSource(this);
|
||||
|
||||
newsDataSource.open();
|
||||
|
||||
}
|
||||
|
||||
public static MainActivity getInstance()
|
||||
{
|
||||
return instance;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void OnSelectEnglish(View view)
|
||||
static MainActivity instance = null;
|
||||
|
||||
private NavigationDrawerFragment mNavigationDrawerFragment = null;
|
||||
|
||||
public NewsDataSource newsDataSource = null;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
Locale.setDefault(Locale.US);
|
||||
Configuration config = new Configuration();
|
||||
config.locale = Locale.US;
|
||||
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
|
||||
|
||||
getSupportActionBar().setTitle(R.string.app_name);
|
||||
|
||||
SetupDrawer();
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
SetupDrawer();
|
||||
|
||||
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, new WelcomeFragment()).commit();
|
||||
|
||||
instance = this;
|
||||
|
||||
|
||||
newsDataSource = new NewsDataSource(this);
|
||||
|
||||
newsDataSource.open();
|
||||
|
||||
}
|
||||
|
||||
public static MainActivity getInstance()
|
||||
{
|
||||
return instance;
|
||||
|
||||
}
|
||||
|
||||
public void OnSelectEnglish(View view)
|
||||
{
|
||||
Locale.setDefault(Locale.US);
|
||||
Configuration config = new Configuration();
|
||||
config.locale = Locale.US;
|
||||
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
|
||||
|
||||
getSupportActionBar().setTitle(R.string.app_name);
|
||||
|
||||
SetupDrawer();
|
||||
|
||||
OpenMainScreen();
|
||||
}
|
||||
|
||||
|
||||
public void OnSelectRussian(View view)
|
||||
{
|
||||
Locale locale = new Locale("ru");
|
||||
Locale.setDefault(locale);
|
||||
Configuration config = new Configuration();
|
||||
config.locale = locale;
|
||||
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
|
||||
|
||||
getSupportActionBar().setTitle(R.string.app_name);
|
||||
SetupDrawer();
|
||||
|
||||
Locale locale = new Locale("ru");
|
||||
Locale.setDefault(locale);
|
||||
Configuration config = new Configuration();
|
||||
config.locale = locale;
|
||||
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
|
||||
|
||||
getSupportActionBar().setTitle(R.string.app_name);
|
||||
SetupDrawer();
|
||||
|
||||
OpenMainScreen();
|
||||
}
|
||||
|
||||
|
||||
public void OnSelectChinese(View view)
|
||||
{
|
||||
Locale.setDefault(Locale.CHINA);
|
||||
Configuration config = new Configuration();
|
||||
config.locale = Locale.CHINA;
|
||||
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
|
||||
|
||||
getSupportActionBar().setTitle(R.string.app_name);
|
||||
SetupDrawer();
|
||||
|
||||
Locale.setDefault(Locale.CHINA);
|
||||
Configuration config = new Configuration();
|
||||
config.locale = Locale.CHINA;
|
||||
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
|
||||
|
||||
getSupportActionBar().setTitle(R.string.app_name);
|
||||
SetupDrawer();
|
||||
|
||||
OpenMainScreen();
|
||||
}
|
||||
|
||||
|
||||
public void OnSelectSemiDetails(Integer pos)
|
||||
{
|
||||
//getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, new SemiDetailsFragment()).addToBackStack(null).commit();
|
||||
// getSupportFragmentManager().beginTransaction().add(R.id.fragment_container,
|
||||
// new SemiDetailsFragment()).addToBackStack(null).commit();
|
||||
}
|
||||
|
||||
|
||||
public void OpenMainScreen()
|
||||
{
|
||||
|
||||
@ -110,7 +112,7 @@ implements NavigationDrawerFragment.NavigationDrawerCallbacks {
|
||||
|
||||
mNavigationDrawerFragment.EnableDrawer();
|
||||
}
|
||||
|
||||
|
||||
public void OpenNewsScreen()
|
||||
{
|
||||
|
||||
@ -119,122 +121,145 @@ implements NavigationDrawerFragment.NavigationDrawerCallbacks {
|
||||
mNavigationDrawerFragment.EnableDrawer();
|
||||
}
|
||||
|
||||
public void OpenSettingsScreen()
|
||||
{
|
||||
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new SettingsFragment()).commit();
|
||||
|
||||
mNavigationDrawerFragment.EnableDrawer();
|
||||
}
|
||||
|
||||
public void OpenNewsRecordScreen(NewsRecord newsRecord, String tag)
|
||||
{
|
||||
//Xperimental -- addToBackStack provoke error "Class not found". Need to resolve somehow!
|
||||
//getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new NewsRecordFragment(newsRecord)).addToBackStack(null).commit();
|
||||
|
||||
//I added workaround:
|
||||
|
||||
// Xperimental -- addToBackStack provoke error "Class not found". Need
|
||||
// to resolve somehow!
|
||||
// getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
|
||||
// new NewsRecordFragment(newsRecord)).addToBackStack(null).commit();
|
||||
|
||||
// I added workaround:
|
||||
|
||||
NewsRecordFragment newsRecordFragment = new NewsRecordFragment(newsRecord);
|
||||
|
||||
|
||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, newsRecordFragment, tag).commit();
|
||||
|
||||
mNavigationDrawerFragment.EnableDrawer();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onAttachFragment(Fragment fragment)
|
||||
{
|
||||
super.onAttachFragment(fragment);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void SetupDrawer()
|
||||
{
|
||||
|
||||
|
||||
mNavigationDrawerFragment = (NavigationDrawerFragment)
|
||||
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
|
||||
|
||||
mNavigationDrawerFragment = (NavigationDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
|
||||
|
||||
if (mNavigationDrawerFragment != null)
|
||||
{
|
||||
|
||||
// Set up the drawer.
|
||||
mNavigationDrawerFragment.setUp(
|
||||
R.id.navigation_drawer,
|
||||
(DrawerLayout) findViewById(R.id.drawer_layout));
|
||||
|
||||
// Set up the drawer.
|
||||
mNavigationDrawerFragment.setUp(R.id.navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu)
|
||||
{
|
||||
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.global, menu);
|
||||
|
||||
/*
|
||||
SearchManager searchManager =
|
||||
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
|
||||
SearchView searchView =
|
||||
(SearchView) menu.findItem(R.id.action_search).getActionView();
|
||||
searchView.setSearchableInfo(
|
||||
searchManager.getSearchableInfo(getComponentName()));
|
||||
*/
|
||||
|
||||
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
int id = item.getItemId();
|
||||
if (id == R.id.action_settings)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNavigationDrawerItemSelected(int position)
|
||||
{
|
||||
if (position == 1)
|
||||
{
|
||||
OpenMainScreen();
|
||||
}
|
||||
else if (position == 2)
|
||||
{
|
||||
OpenNewsScreen();
|
||||
}
|
||||
else if (position == 8)
|
||||
{
|
||||
OpenSettingsScreen();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed()
|
||||
{
|
||||
|
||||
if (getSupportFragmentManager().findFragmentByTag(TAG_FROM_MAINFRAGMENT_TO_NEWSRECORDFRAGMENT) != null)
|
||||
{
|
||||
OpenMainScreen();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (getSupportFragmentManager().findFragmentByTag(TAG_FROM_NEWSLISTFRAGMENT_TO_NEWSRECORDFRAGMENT) != null)
|
||||
{
|
||||
OpenNewsScreen();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
super.onBackPressed();
|
||||
|
||||
/*
|
||||
* AddToBackStack is falling. Here is workaround
|
||||
* if(getSupportFragmentManager().getBackStackEntryCount() != 0) {
|
||||
* getSupportFragmentManager().popBackStack(); } else {
|
||||
* super.onBackPressed(); }
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
newsDataSource.open();
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause()
|
||||
{
|
||||
newsDataSource.close();
|
||||
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
int id = item.getItemId();
|
||||
if (id == R.id.action_settings) {
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onNavigationDrawerItemSelected(int position)
|
||||
{
|
||||
if (position == 1)
|
||||
{
|
||||
OpenMainScreen();
|
||||
}
|
||||
else if (position == 2)
|
||||
{
|
||||
OpenNewsScreen();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
|
||||
if ( getSupportFragmentManager().findFragmentByTag(TAG_FROM_MAINFRAGMENT_TO_NEWSRECORDFRAGMENT) != null)
|
||||
{
|
||||
OpenMainScreen();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( getSupportFragmentManager().findFragmentByTag(TAG_FROM_NEWSLISTFRAGMENT_TO_NEWSRECORDFRAGMENT) != null)
|
||||
{
|
||||
OpenNewsScreen();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
super.onBackPressed();
|
||||
|
||||
|
||||
/*
|
||||
* AddToBackStack is falling. Here is workaround
|
||||
if(getSupportFragmentManager().getBackStackEntryCount() != 0) {
|
||||
getSupportFragmentManager().popBackStack();
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}*/
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
//Xperimental -- opening and closing leads to fail
|
||||
//newsDataSource.open();
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
//Xperimental -- opening and closing leads to fail
|
||||
//newsDataSource.close();
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ public class MainPageFragment extends Fragment implements NewsUpdatedCallbackInt
|
||||
ListView listView;
|
||||
View header;
|
||||
|
||||
NewsManager.RemoveCallbackInterface downloadNewsCanceller;
|
||||
NewsManager.RemoveCallbackInterface downloadNewsCanceller = null;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
@ -84,7 +84,11 @@ public class MainPageFragment extends Fragment implements NewsUpdatedCallbackInt
|
||||
@Override
|
||||
public void onDestroyView()
|
||||
{
|
||||
downloadNewsCanceller.RemoveCallback();
|
||||
if (downloadNewsCanceller != null)
|
||||
{
|
||||
downloadNewsCanceller.RemoveCallback();
|
||||
downloadNewsCanceller = null;
|
||||
}
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
|
@ -3,9 +3,11 @@ package fishrungames.bashgid;
|
||||
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.app.Activity;
|
||||
import android.app.SearchManager;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.app.ActionBarDrawerToggle;
|
||||
import android.support.v7.widget.SearchView;
|
||||
import android.support.v4.view.GravityCompat;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.content.Context;
|
||||
@ -258,10 +260,11 @@ public class NavigationDrawerFragment extends Fragment {
|
||||
// showGlobalContextActionBar, which controls the top-left area of the action bar.
|
||||
|
||||
|
||||
inflater.inflate(R.menu.global, menu);
|
||||
//inflater.inflate(R.menu.global, menu);
|
||||
showGlobalContextActionBar();
|
||||
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -271,6 +274,11 @@ public class NavigationDrawerFragment extends Fragment {
|
||||
if (mDrawerToggle.onOptionsItemSelected(item)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (item.getItemId() == R.id.action_search) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (item.getItemId() == R.id.action_settings) {
|
||||
Toast.makeText(getActivity(), "Example action.", Toast.LENGTH_SHORT).show();
|
||||
|
@ -31,7 +31,7 @@ public class NewsListFragment extends Fragment implements NewsUpdatedCallbackInt
|
||||
|
||||
ArrayList<NewsRecord> newsRecordArr;
|
||||
|
||||
NewsManager.RemoveCallbackInterface downloadNewsCanceller;
|
||||
NewsManager.RemoveCallbackInterface downloadNewsCanceller = null;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
@ -57,7 +57,11 @@ public class NewsListFragment extends Fragment implements NewsUpdatedCallbackInt
|
||||
@Override
|
||||
public void onDestroyView()
|
||||
{
|
||||
downloadNewsCanceller.RemoveCallback();
|
||||
if (downloadNewsCanceller != null)
|
||||
{
|
||||
downloadNewsCanceller.RemoveCallback();
|
||||
downloadNewsCanceller = null;
|
||||
}
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
|
22
android/src/fishrungames/bashgid/SettingsFragment.java
Normal file
22
android/src/fishrungames/bashgid/SettingsFragment.java
Normal file
@ -0,0 +1,22 @@
|
||||
package fishrungames.bashgid;
|
||||
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
|
||||
public class SettingsFragment extends Fragment
|
||||
{
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
View rootView = inflater.inflate(R.layout.fragment_settings_page, container, false);
|
||||
|
||||
|
||||
return rootView;
|
||||
}
|
||||
}
|
@ -5,6 +5,8 @@ import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import fishrungames.bashgid.MainActivity;
|
||||
import fishrungames.bashgid.R;
|
||||
@ -20,6 +22,10 @@ public class ImageManager {
|
||||
|
||||
static ImageManager instance = null;
|
||||
|
||||
private volatile Semaphore downloadingFileNameSetMutex = new Semaphore(1, true);
|
||||
private volatile HashSet<String> downloadingFileNameSet = new HashSet<String>();
|
||||
|
||||
|
||||
public static ImageManager getInstance()
|
||||
{
|
||||
if (instance == null)
|
||||
@ -43,6 +49,8 @@ public class ImageManager {
|
||||
|
||||
public void ApplyImageToImageView(ImageView imageView, String imageId)
|
||||
{
|
||||
//Xperimental -- Should be called only in main thread
|
||||
|
||||
if (imageId.startsWith("R.drawable."))
|
||||
{
|
||||
Integer resourceId = PredefinedImageId.get(imageId);
|
||||
@ -64,14 +72,40 @@ public class ImageManager {
|
||||
|
||||
if (f.exists())
|
||||
{
|
||||
Bitmap bitmap = BitmapFactory.decodeFile( MainActivity.getInstance().getFileStreamPath(fileName).getAbsolutePath());
|
||||
|
||||
imageView.setImageBitmap(bitmap);
|
||||
boolean fileIsBusy = false;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
downloadingFileNameSetMutex.acquire();
|
||||
try
|
||||
{
|
||||
fileIsBusy = downloadingFileNameSet.contains(fileName);
|
||||
} finally
|
||||
{
|
||||
downloadingFileNameSetMutex.release();
|
||||
}
|
||||
} catch (InterruptedException ie)
|
||||
{
|
||||
Log.e("Error in ApplyImageToImageView", "Error in ApplyImageToImageView");
|
||||
}
|
||||
|
||||
|
||||
if (!fileIsBusy)
|
||||
{
|
||||
|
||||
Bitmap bitmap = BitmapFactory.decodeFile( MainActivity.getInstance().getFileStreamPath(fileName).getAbsolutePath());
|
||||
|
||||
imageView.setImageBitmap(bitmap);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.e("Error: ", "Image requested but not downloaded: " + imageId);
|
||||
|
||||
imageView.setImageResource(R.drawable.transparent);
|
||||
}
|
||||
}
|
||||
@ -97,26 +131,76 @@ public class ImageManager {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
InputStream is = (InputStream) new URL(imageUrl).getContent();
|
||||
|
||||
FileOutputStream out = null;
|
||||
|
||||
out = MainActivity.getInstance().openFileOutput(fileName, Context.MODE_PRIVATE);
|
||||
|
||||
byte [] buf = new byte[1024];
|
||||
|
||||
int numRead;
|
||||
|
||||
while ( (numRead = is.read(buf) ) >= 0) {
|
||||
out.write(buf, 0, numRead);
|
||||
}
|
||||
|
||||
out.close();
|
||||
boolean fileIsBusy = false;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
downloadingFileNameSetMutex.acquire();
|
||||
try
|
||||
{
|
||||
if (downloadingFileNameSet.contains(fileIsBusy))
|
||||
{
|
||||
fileIsBusy = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
downloadingFileNameSet.add(fileName);
|
||||
}
|
||||
} finally
|
||||
{
|
||||
downloadingFileNameSetMutex.release();
|
||||
}
|
||||
} catch (InterruptedException ie)
|
||||
{
|
||||
Log.e("Error in DownloadImageIfNeeded", "Error in DownloadImageIfNeeded");
|
||||
}
|
||||
|
||||
if (!fileIsBusy)
|
||||
{
|
||||
|
||||
try {
|
||||
InputStream is = (InputStream) new URL(imageUrl).getContent();
|
||||
|
||||
FileOutputStream out = null;
|
||||
|
||||
out = MainActivity.getInstance().openFileOutput(fileName, Context.MODE_PRIVATE);
|
||||
|
||||
byte [] buf = new byte[1024];
|
||||
|
||||
int numRead;
|
||||
|
||||
while ( (numRead = is.read(buf) ) >= 0) {
|
||||
out.write(buf, 0, numRead);
|
||||
}
|
||||
|
||||
out.close();
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
downloadingFileNameSetMutex.acquire();
|
||||
try
|
||||
{
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
downloadingFileNameSet.remove(fileName);
|
||||
|
||||
} finally
|
||||
{
|
||||
downloadingFileNameSetMutex.release();
|
||||
}
|
||||
} catch (InterruptedException ie)
|
||||
{
|
||||
Log.e("Error in DownloadImageIfNeeded", "Error in DownloadImageIfNeeded");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public String GetImageLocalUrl(String imageUrl)
|
||||
|
@ -4,16 +4,38 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
|
||||
import fishrungames.bashgid.MainActivity;
|
||||
import fishrungames.bashgid.core.db.BashgidSqliteHelper;
|
||||
|
||||
public class NewsManager {
|
||||
|
||||
private static NewsManager instance = null;
|
||||
private static final String [] urlArr = {
|
||||
"https://www.bashkortostan.ru/presscenter/news/rss/",
|
||||
"http://www.bashedu.ru/rss.xml",
|
||||
"http://www.bashinform.ru/rss/all.xml",
|
||||
"http://www.minkult-rb.ru/news/rss/",
|
||||
"http://02.mvd.ru/news/rss/"
|
||||
};
|
||||
|
||||
private static NewsManager instance = null;
|
||||
|
||||
private static volatile boolean SynchronizationInProcess = false; //Not strict, so don't need mutex
|
||||
|
||||
private volatile Semaphore newsRecordMutex = new Semaphore(1, true);
|
||||
private ArrayList<NewsRecord> newsRecord = new ArrayList<NewsRecord>();
|
||||
|
||||
|
||||
|
||||
public static boolean CanCallSynchronization()
|
||||
{
|
||||
return SynchronizationInProcess;
|
||||
}
|
||||
|
||||
//Xperimental -- need do something with this. Change to semaphore?
|
||||
public static volatile boolean SynchronizationInProcess = false;
|
||||
|
||||
|
||||
public static NewsManager GetInstance()
|
||||
@ -60,16 +82,18 @@ public class NewsManager {
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<NewsRecord> newsRecord = new ArrayList<NewsRecord>();
|
||||
|
||||
|
||||
public RemoveCallbackInterface DownloadNews(NewsUpdatedCallbackInterface callback)
|
||||
{
|
||||
|
||||
DownloadNewsRunnable downloadNewsRunnable = new DownloadNewsRunnable(callback);
|
||||
|
||||
Thread thread = new Thread(downloadNewsRunnable);
|
||||
|
||||
thread.start();
|
||||
DownloadNewsRunnable downloadNewsRunnable = null;
|
||||
if (CanCallSynchronization())
|
||||
{
|
||||
downloadNewsRunnable = new DownloadNewsRunnable(callback);
|
||||
|
||||
Thread thread = new Thread(downloadNewsRunnable);
|
||||
|
||||
thread.start();
|
||||
}
|
||||
|
||||
return downloadNewsRunnable;
|
||||
}
|
||||
@ -77,70 +101,123 @@ public class NewsManager {
|
||||
class DownloadNewsRunnable implements Runnable, RemoveCallbackInterface
|
||||
{
|
||||
|
||||
NewsUpdatedCallbackInterface callback;
|
||||
private volatile Semaphore callbackMutex = new Semaphore(1, true);
|
||||
NewsUpdatedCallbackInterface callback = null;
|
||||
|
||||
public DownloadNewsRunnable(NewsUpdatedCallbackInterface callback)
|
||||
{
|
||||
this.callback = callback;
|
||||
try
|
||||
{
|
||||
callbackMutex.acquire();
|
||||
try
|
||||
{
|
||||
|
||||
this.callback = callback;
|
||||
|
||||
} finally
|
||||
{
|
||||
callbackMutex.release();
|
||||
}
|
||||
} catch (InterruptedException ie)
|
||||
{
|
||||
Log.e("Error in DownloadNewsRunnable", "Error in DownloadNewsRunnable");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void RemoveCallback()
|
||||
{
|
||||
callback = null;
|
||||
|
||||
try
|
||||
{
|
||||
callbackMutex.acquire();
|
||||
try
|
||||
{
|
||||
|
||||
callback = null;
|
||||
|
||||
} finally
|
||||
{
|
||||
callbackMutex.release();
|
||||
}
|
||||
} catch (InterruptedException ie)
|
||||
{
|
||||
Log.e("Error in DownloadNewsRunnable", "Error in DownloadNewsRunnable");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (SynchronizationInProcess)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SynchronizationInProcess = true;
|
||||
|
||||
final String [] urlArr = {
|
||||
"https://www.bashkortostan.ru/presscenter/news/rss/",
|
||||
"http://www.bashedu.ru/rss.xml",
|
||||
"http://www.bashinform.ru/rss/all.xml",
|
||||
"http://www.minkult-rb.ru/news/rss/",
|
||||
"http://02.mvd.ru/news/rss/"
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
SynchronizationInProcess = true;
|
||||
|
||||
|
||||
ArrayList<NewsRecord> localNewsRecord = MainActivity.getInstance().newsDataSource.getNews();
|
||||
|
||||
ArrayList<String> imageToDownloadList = new ArrayList<String>();
|
||||
|
||||
for (int i = 0; i < urlArr.length; i++)
|
||||
{
|
||||
|
||||
|
||||
LoadNewsAndImagesFromRss2(urlArr[i], localNewsRecord, imageToDownloadList);
|
||||
|
||||
Collections.sort(localNewsRecord, new NewsSortComparator());
|
||||
|
||||
//NewsSortComparator
|
||||
|
||||
//Xperimental -- need mutex right here
|
||||
newsRecord = localNewsRecord;
|
||||
|
||||
MainActivity.getInstance().newsDataSource.replaceNews(newsRecord);
|
||||
|
||||
//Xperimental -- need mutex here, too
|
||||
if (callback != null)
|
||||
{
|
||||
callback.OnNewsUpdated();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Collections.sort(localNewsRecord, new NewsSortComparator());
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
newsRecordMutex.acquire();
|
||||
try
|
||||
{
|
||||
|
||||
newsRecord = localNewsRecord;
|
||||
|
||||
MainActivity.getInstance().newsDataSource.replaceNews(newsRecord);
|
||||
|
||||
} finally
|
||||
{
|
||||
newsRecordMutex.release();
|
||||
}
|
||||
} catch (InterruptedException ie)
|
||||
{
|
||||
Log.e("Error in DownloadNewsRunnable", "Error in DownloadNewsRunnable");
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
callbackMutex.acquire();
|
||||
try
|
||||
{
|
||||
|
||||
if (callback != null)
|
||||
{
|
||||
callback.OnNewsUpdated();
|
||||
}
|
||||
|
||||
} finally
|
||||
{
|
||||
callbackMutex.release();
|
||||
}
|
||||
} catch (InterruptedException ie)
|
||||
{
|
||||
Log.e("Error in DownloadNewsRunnable", "Error in DownloadNewsRunnable");
|
||||
}
|
||||
|
||||
|
||||
for (String imageToDownload : imageToDownloadList)
|
||||
{
|
||||
ImageManager.getInstance().DownloadImageIfNeeded(imageToDownload);
|
||||
}
|
||||
|
||||
SynchronizationInProcess = false;
|
||||
|
||||
SynchronizationInProcess = false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,14 +234,46 @@ public class NewsManager {
|
||||
|
||||
public NewsManager()
|
||||
{
|
||||
newsRecord = MainActivity.getInstance().newsDataSource.getNews();
|
||||
try
|
||||
{
|
||||
newsRecordMutex.acquire();
|
||||
try
|
||||
{
|
||||
newsRecord = MainActivity.getInstance().newsDataSource.getNews();
|
||||
|
||||
} finally
|
||||
{
|
||||
newsRecordMutex.release();
|
||||
}
|
||||
} catch (InterruptedException ie)
|
||||
{
|
||||
Log.e("Error in NewsManager constructor", "Error in NewsManager constructor");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<NewsRecord> getNews()
|
||||
{
|
||||
return newsRecord;
|
||||
ArrayList<NewsRecord> result = new ArrayList<NewsRecord>();
|
||||
|
||||
try
|
||||
{
|
||||
newsRecordMutex.acquire();
|
||||
try
|
||||
{
|
||||
result.addAll(newsRecord);
|
||||
|
||||
} finally
|
||||
{
|
||||
newsRecordMutex.release();
|
||||
}
|
||||
} catch (InterruptedException ie)
|
||||
{
|
||||
Log.e("Error in NewsManager constructor", "Error in NewsManager constructor");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,6 +7,7 @@ import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
@ -36,6 +37,11 @@ public class XmlProcessor
|
||||
{
|
||||
Log.e("Error: ", e.getMessage());
|
||||
return null;
|
||||
} catch (DOMException e)
|
||||
{
|
||||
//Xperimental -- need to learn more about this exception
|
||||
Log.e("Error: ", e.getMessage());
|
||||
return null;
|
||||
} catch (SAXException e)
|
||||
{
|
||||
Log.e("Error: ", e.getMessage());
|
||||
|
@ -4,6 +4,7 @@ import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import fishrungames.bashgid.core.NewsManager;
|
||||
|
||||
@ -12,6 +13,7 @@ import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.SQLException;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.util.Log;
|
||||
|
||||
public class NewsDataSource
|
||||
{
|
||||
@ -19,25 +21,82 @@ public class NewsDataSource
|
||||
//Xperimental -- move somewhere
|
||||
public static final SimpleDateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
|
||||
|
||||
private SQLiteDatabase database;
|
||||
private SQLiteDatabase database = null;
|
||||
|
||||
private BashgidSqliteHelper dbHelper;
|
||||
private BashgidSqliteHelper dbHelper = null;
|
||||
|
||||
private String[] allColumns = { BashgidSqliteHelper.COLUMN_ID, BashgidSqliteHelper.COLUMN_TITLE, BashgidSqliteHelper.COLUMN_DESCRIPTION,
|
||||
BashgidSqliteHelper.COLUMN_IMAGE_ID, BashgidSqliteHelper.COLUMN_PUBDATE };
|
||||
|
||||
|
||||
private final Semaphore mutex = new Semaphore(1, true);
|
||||
|
||||
public NewsDataSource(Context context) {
|
||||
dbHelper = new BashgidSqliteHelper(context);
|
||||
public NewsDataSource(Context context)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
mutex.acquire();
|
||||
try
|
||||
{
|
||||
|
||||
dbHelper = new BashgidSqliteHelper(context);
|
||||
|
||||
} finally
|
||||
{
|
||||
mutex.release();
|
||||
}
|
||||
} catch (InterruptedException ie)
|
||||
{
|
||||
Log.e("Error when creating BashgidSqliteHelper", "Error when creating BashgidSqliteHelper");
|
||||
}
|
||||
}
|
||||
|
||||
public void open() throws SQLException
|
||||
{
|
||||
database = dbHelper.getWritableDatabase();
|
||||
try
|
||||
{
|
||||
mutex.acquire();
|
||||
try
|
||||
{
|
||||
|
||||
database = dbHelper.getWritableDatabase();
|
||||
|
||||
} finally
|
||||
{
|
||||
mutex.release();
|
||||
}
|
||||
} catch (InterruptedException ie)
|
||||
{
|
||||
Log.e("Error when opening NewsDataSource", "Error when opening NewsDataSource");
|
||||
|
||||
database = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
dbHelper.close();
|
||||
try
|
||||
{
|
||||
mutex.acquire();
|
||||
try
|
||||
{
|
||||
if (dbHelper != null)
|
||||
{
|
||||
dbHelper.close();
|
||||
database = null;
|
||||
}
|
||||
|
||||
} finally
|
||||
{
|
||||
mutex.release();
|
||||
}
|
||||
} catch (InterruptedException ie)
|
||||
{
|
||||
Log.e("Error when closing NewsDataSource", "Error when closing NewsDataSource");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void createNewsRecord(NewsManager.NewsRecord newsRecord)
|
||||
@ -50,14 +109,52 @@ public class NewsDataSource
|
||||
values.put(BashgidSqliteHelper.COLUMN_IMAGE_ID, newsRecord.imageId);
|
||||
values.put(BashgidSqliteHelper.COLUMN_PUBDATE, iso8601Format.format(newsRecord.pubDate));
|
||||
|
||||
database.insert(BashgidSqliteHelper.TABLE_NEWS, null, values);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
mutex.acquire();
|
||||
try
|
||||
{
|
||||
|
||||
if (database != null)
|
||||
{
|
||||
database.insert(BashgidSqliteHelper.TABLE_NEWS, null, values);
|
||||
}
|
||||
|
||||
} finally
|
||||
{
|
||||
mutex.release();
|
||||
}
|
||||
} catch (InterruptedException ie)
|
||||
{
|
||||
Log.e("Error when calling createNewsRecord", "Error when calling createNewsRecord");
|
||||
}
|
||||
}
|
||||
|
||||
public void replaceNews(ArrayList<NewsManager.NewsRecord> newsRecordArr)
|
||||
{
|
||||
|
||||
database.delete(BashgidSqliteHelper.TABLE_NEWS, null, null);
|
||||
try
|
||||
{
|
||||
mutex.acquire();
|
||||
try
|
||||
{
|
||||
|
||||
if (database != null)
|
||||
{
|
||||
database.delete(BashgidSqliteHelper.TABLE_NEWS, null, null);
|
||||
}
|
||||
|
||||
} finally
|
||||
{
|
||||
mutex.release();
|
||||
}
|
||||
} catch (InterruptedException ie)
|
||||
{
|
||||
Log.e("Error when calling replaceNews", "Error when calling replaceNews");
|
||||
}
|
||||
|
||||
|
||||
for (NewsManager.NewsRecord newsRecord : newsRecordArr)
|
||||
{
|
||||
@ -70,18 +167,39 @@ public class NewsDataSource
|
||||
{
|
||||
|
||||
ArrayList<NewsManager.NewsRecord> newsRecordArr = new ArrayList<NewsManager.NewsRecord>();
|
||||
|
||||
Cursor cursor = database.query(BashgidSqliteHelper.TABLE_NEWS, allColumns, null, null, null, null, null);
|
||||
|
||||
cursor.moveToFirst();
|
||||
while (!cursor.isAfterLast())
|
||||
/*
|
||||
try
|
||||
{
|
||||
NewsManager.NewsRecord newsRecord = cursorToNewsRecord(cursor);
|
||||
newsRecordArr.add(newsRecord);
|
||||
cursor.moveToNext();
|
||||
mutex.acquire();
|
||||
try
|
||||
{
|
||||
*/
|
||||
if (database != null)
|
||||
{
|
||||
Cursor cursor = database.query(BashgidSqliteHelper.TABLE_NEWS, allColumns, null, null, null, null, null);
|
||||
|
||||
cursor.moveToFirst();
|
||||
|
||||
while (!cursor.isAfterLast())
|
||||
{
|
||||
NewsManager.NewsRecord newsRecord = cursorToNewsRecord(cursor);
|
||||
newsRecordArr.add(newsRecord);
|
||||
cursor.moveToNext();
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
/*
|
||||
} finally
|
||||
{
|
||||
mutex.release();
|
||||
}
|
||||
} catch (InterruptedException ie)
|
||||
{
|
||||
Log.e("Error when calling replaceNews", "Error when calling replaceNews");
|
||||
}
|
||||
// make sure to close the cursor
|
||||
cursor.close();
|
||||
*/
|
||||
return newsRecordArr;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user