Merge commit 'refs/merge-requests/25' of git://gitorious.org/f-droid/fdroidclient into merge-requests/25

Conflicts:
	src/org/fdroid/fdroid/FDroid.java
This commit is contained in:
Ciaran Gultnieks 2013-04-16 09:43:18 +01:00
commit 0680899a94
7 changed files with 258 additions and 143 deletions

View File

@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.List;
import android.support.v4.view.MenuItemCompat;
import org.fdroid.fdroid.compat.MenuManager;
import org.xml.sax.XMLReader;
import android.app.AlertDialog;
@ -248,7 +249,9 @@ public class AppDetails extends ListActivity {
resetRequired = false;
}
resetViews();
invalidateOptionsMenu();
MenuManager.create(this).invalidateOptionsMenu();
if (downloadHandler != null) {
downloadHandler.startUpdates();
}
@ -796,4 +799,5 @@ public class AppDetails extends ListActivity {
break;
}
}
}

View File

@ -278,28 +278,23 @@ public class DB {
// check if an APK is compatible with the user's device.
public static abstract class CompatibilityChecker {
// Because Build.VERSION.SDK_INT requires API level 5
@SuppressWarnings("deprecation")
protected final static int SDK_INT = Integer
.parseInt(Build.VERSION.SDK);
public abstract boolean isCompatible(Apk apk);
public static CompatibilityChecker getChecker(Context ctx) {
CompatibilityChecker checker;
if (SDK_INT >= 5)
if (Utils.hasApi(5))
checker = new EclairChecker(ctx);
else
checker = new BasicChecker();
Log.d("FDroid", "Compatibility checker for API level "
+ SDK_INT + ": " + checker.getClass().getName());
+ Utils.getApi() + ": " + checker.getClass().getName());
return checker;
}
}
private static class BasicChecker extends CompatibilityChecker {
public boolean isCompatible(Apk apk) {
return (apk.minSdkVersion <= SDK_INT);
return (apk.minSdkVersion <= Utils.getApi());
}
}
@ -329,7 +324,7 @@ public class DB {
}
public boolean isCompatible(Apk apk) {
if (apk.minSdkVersion > SDK_INT)
if (apk.minSdkVersion > Utils.getApi())
return false;
if (apk.features != null) {
for (String feat : apk.features) {

View File

@ -34,18 +34,17 @@ import org.fdroid.fdroid.R;
import android.R.drawable;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.FragmentTransaction;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
@ -53,7 +52,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.*;
import android.widget.TabHost.TabSpec;
import org.fdroid.fdroid.compat.TabManager;
import org.fdroid.fdroid.views.AppListFragmentPageAdapter;
public class FDroid extends FragmentActivity {
@ -76,8 +75,7 @@ public class FDroid extends FragmentActivity {
private AppListManager manager = null;
// Used by pre 3.0 devices which don't have an ActionBar...
private TabHost tabHost;
private TabManager tabManager = null;
public AppListManager getManager() {
return manager;
@ -90,7 +88,7 @@ public class FDroid extends FragmentActivity {
manager = new AppListManager(this);
setContentView(R.layout.fdroid);
createViews();
createTabs();
getTabManager().createTabs();
// Must be done *after* createViews, because it will involve a
// callback to update the tab label for the "update" tab. This
@ -105,7 +103,7 @@ public class FDroid extends FragmentActivity {
} else if (i.hasExtra(EXTRA_TAB_UPDATE)) {
boolean showUpdateTab = i.getBooleanExtra(EXTRA_TAB_UPDATE, false);
if (showUpdateTab) {
selectTab(2);
getTabManager().selectTab(2);
}
}
}
@ -251,127 +249,7 @@ public class FDroid extends FragmentActivity {
viewPager.setAdapter(viewPageAdapter);
viewPager.setOnPageChangeListener( new ViewPager.SimpleOnPageChangeListener() {
public void onPageSelected(int position) {
selectTab(position);
}
});
}
private void createTabs() {
if (Build.VERSION.SDK_INT >= 11) {
createActionBarTabs();
} else {
createOldTabs();
}
}
private void selectTab(int index) {
if (Build.VERSION.SDK_INT >= 11) {
getActionBar().setSelectedNavigationItem(index);
} else {
tabHost.setCurrentTab(index);
}
}
public void refreshUpdateTabLabel() {
final int INDEX = 2;
CharSequence text = viewPager.getAdapter().getPageTitle(INDEX);
if ( Build.VERSION.SDK_INT >= 11) {
getActionBar().getTabAt(INDEX).setText(text);
} else {
// Update the count on the 'Updates' tab to show the number available.
// This is quite unpleasant, but seems to be the only way to do it.
TextView textView = (TextView) tabHost.getTabWidget().getChildAt(2)
.findViewById(android.R.id.title);
textView.setText(text);
}
}
private void createActionBarTabs() {
final ActionBar actionBar = getActionBar();
final ViewPager pager = viewPager;
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
for (int i = 0; i < viewPager.getAdapter().getCount(); i ++) {
CharSequence label = viewPager.getAdapter().getPageTitle(i);
actionBar.addTab(
actionBar.newTab()
.setText(label)
.setTabListener(new ActionBar.TabListener() {
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction ft) {
pager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
}));
}
}
/**
* There is a bit of boiler-plate code required to get a TabWidget showing,
* which includes creating a TabHost, populating it with the TabWidget,
* and giving it a FrameLayout as a child. This will make the tabs have
* dummy empty contents and then hook them up to our ViewPager.
*/
private void createOldTabs() {
tabHost = new TabHost(this);
tabHost.setLayoutParams(new TabHost.LayoutParams(
TabHost.LayoutParams.MATCH_PARENT, TabHost.LayoutParams.WRAP_CONTENT));
TabWidget tabWidget = new TabWidget(this);
tabWidget.setId(android.R.id.tabs);
tabHost.setLayoutParams(new TabHost.LayoutParams(
TabWidget.LayoutParams.MATCH_PARENT, TabWidget.LayoutParams.WRAP_CONTENT));
FrameLayout layout = new FrameLayout(this);
layout.setId(android.R.id.tabcontent);
layout.setLayoutParams(new TabWidget.LayoutParams(0, 0));
tabHost.addView(tabWidget);
tabHost.addView(layout);
tabHost.setup();
TabHost.TabContentFactory factory = new TabHost.TabContentFactory() {
@Override
public View createTabContent(String tag) {
return new View(FDroid.this);
}
};
TabSpec availableTabSpec = tabHost.newTabSpec("available")
.setIndicator(
getString(R.string.tab_noninstalled),
getResources().getDrawable(android.R.drawable.ic_input_add))
.setContent(factory);
TabSpec installedTabSpec = tabHost.newTabSpec("installed")
.setIndicator(
getString(R.string.tab_installed),
getResources().getDrawable(android.R.drawable.star_off))
.setContent(factory);
TabSpec canUpdateTabSpec = tabHost.newTabSpec("canUpdate")
.setIndicator(
getString(R.string.tab_updates),
getResources().getDrawable(android.R.drawable.star_on))
.setContent(factory);
tabHost.addTab(availableTabSpec);
tabHost.addTab(installedTabSpec);
tabHost.addTab(canUpdateTabSpec);
LinearLayout contentView = (LinearLayout)findViewById(R.id.fdroid_layout);
contentView.addView(tabHost, 0);
tabHost.setOnTabChangedListener( new TabHost.OnTabChangeListener() {
@Override
public void onTabChanged(String tabId) {
viewPager.setCurrentItem(tabHost.getCurrentTab());
getTabManager().selectTab(position);
}
});
}
@ -410,7 +288,7 @@ public class FDroid extends FragmentActivity {
boolean hasTriedEmptyUpdate = getPreferences(MODE_PRIVATE).getBoolean(TRIED_EMPTY_UPDATE, false);
if (!hasTriedEmptyUpdate) {
Log.d("FDroid", "Empty app list, and we haven't done an update yet. Forcing repo update.");
getPreferences(MODE_PRIVATE).edit().putBoolean(TRIED_EMPTY_UPDATE, true).apply();
getPreferences(MODE_PRIVATE).edit().putBoolean(TRIED_EMPTY_UPDATE, true).commit();
updateRepos();
return true;
} else {
@ -435,4 +313,15 @@ public class FDroid extends FragmentActivity {
startService(intent);
}
private TabManager getTabManager() {
if (tabManager == null) {
tabManager = TabManager.create(this, viewPager);
}
return tabManager;
}
public void refreshUpdateTabLabel() {
getTabManager().refreshTabLabel(TabManager.INDEX_CAN_UPDATE);
}
}

View File

@ -18,6 +18,8 @@
package org.fdroid.fdroid;
import android.os.Build;
import java.io.Closeable;
import java.io.InputStream;
import java.io.IOException;
@ -52,4 +54,12 @@ public final class Utils {
// ignore
}
}
public static boolean hasApi(int apiLevel) {
return Build.VERSION.SDK_INT >= apiLevel;
}
public static int getApi() {
return Build.VERSION.SDK_INT;
}
}

View File

@ -0,0 +1,48 @@
package org.fdroid.fdroid.compat;
import android.app.Activity;
import org.fdroid.fdroid.Utils;
abstract public class MenuManager {
public static MenuManager create(Activity activity) {
if (Utils.hasApi(11)) {
return new HoneycombMenuManagerImpl(activity);
} else {
return new OldMenuManagerImpl(activity);
}
}
protected final Activity activity;
protected MenuManager(Activity activity) {
this.activity = activity;
}
abstract public void invalidateOptionsMenu();
}
class OldMenuManagerImpl extends MenuManager {
protected OldMenuManagerImpl(Activity activity) {
super(activity);
}
@Override
public void invalidateOptionsMenu() {
}
}
class HoneycombMenuManagerImpl extends MenuManager {
protected HoneycombMenuManagerImpl(Activity activity) {
super(activity);
}
@Override
public void invalidateOptionsMenu() {
activity.invalidateOptionsMenu();
}
}

View File

@ -0,0 +1,173 @@
package org.fdroid.fdroid.compat;
import android.app.ActionBar;
import android.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.*;
import org.fdroid.fdroid.FDroid;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils;
public abstract class TabManager {
public static final int INDEX_AVAILABLE = 0;
public static final int INDEX_INSTALLED = 1;
public static final int INDEX_CAN_UPDATE = 2;
public static TabManager create(FDroid parent, ViewPager pager) {
if (Utils.hasApi(11)) {
return new HoneycombTabManagerImpl(parent, pager);
} else {
return new OldTabManagerImpl(parent, pager);
}
}
protected final ViewPager pager;
protected final FDroid parent;
protected TabManager(FDroid parent, ViewPager pager) {
this.parent = parent;
this.pager = pager;
}
abstract public void createTabs();
abstract public void selectTab(int index);
abstract public void refreshTabLabel(int index);
protected CharSequence getLabel(int index) {
return pager.getAdapter().getPageTitle(index);
}
}
class OldTabManagerImpl extends TabManager {
private TabHost tabHost;
public OldTabManagerImpl(FDroid parent, ViewPager pager) {
super(parent, pager);
}
/**
* There is a bit of boiler-plate code required to get a TabWidget showing,
* which includes creating a TabHost, populating it with the TabWidget,
* and giving it a FrameLayout as a child. This will make the tabs have
* dummy empty contents and then hook them up to our ViewPager.
*/
public void createTabs() {
tabHost = new TabHost(parent);
tabHost.setLayoutParams(new TabHost.LayoutParams(
TabHost.LayoutParams.MATCH_PARENT, TabHost.LayoutParams.WRAP_CONTENT));
TabWidget tabWidget = new TabWidget(parent);
tabWidget.setId(android.R.id.tabs);
tabHost.setLayoutParams(new TabHost.LayoutParams(
TabWidget.LayoutParams.MATCH_PARENT, TabWidget.LayoutParams.WRAP_CONTENT));
FrameLayout layout = new FrameLayout(parent);
layout.setId(android.R.id.tabcontent);
layout.setLayoutParams(new TabWidget.LayoutParams(0, 0));
tabHost.addView(tabWidget);
tabHost.addView(layout);
tabHost.setup();
TabHost.TabContentFactory factory = new TabHost.TabContentFactory() {
@Override
public View createTabContent(String tag) {
return new View(parent);
}
};
TabHost.TabSpec availableTabSpec = tabHost.newTabSpec("available")
.setIndicator(
parent.getString(R.string.tab_noninstalled),
parent.getResources().getDrawable(android.R.drawable.ic_input_add))
.setContent(factory);
TabHost.TabSpec installedTabSpec = tabHost.newTabSpec("installed")
.setIndicator(
parent.getString(R.string.tab_installed),
parent.getResources().getDrawable(android.R.drawable.star_off))
.setContent(factory);
TabHost.TabSpec canUpdateTabSpec = tabHost.newTabSpec("canUpdate")
.setIndicator(
parent.getString(R.string.tab_updates),
parent.getResources().getDrawable(android.R.drawable.star_on))
.setContent(factory);
tabHost.addTab(availableTabSpec);
tabHost.addTab(installedTabSpec);
tabHost.addTab(canUpdateTabSpec);
LinearLayout contentView = (LinearLayout)parent.findViewById(R.id.fdroid_layout);
contentView.addView(tabHost, 0);
tabHost.setOnTabChangedListener( new TabHost.OnTabChangeListener() {
@Override
public void onTabChanged(String tabId) {
pager.setCurrentItem(tabHost.getCurrentTab());
}
});
}
public void selectTab(int index) {
tabHost.setCurrentTab(index);
}
public void refreshTabLabel(int index) {
CharSequence text = getLabel(index);
// Update the count on the 'Updates' tab to show the number available.
// This is quite unpleasant, but seems to be the only way to do it.
TextView textView = (TextView) tabHost.getTabWidget().getChildAt(index)
.findViewById(android.R.id.title);
textView.setText(text);
}
}
class HoneycombTabManagerImpl extends TabManager {
protected final ActionBar actionBar;
public HoneycombTabManagerImpl(FDroid parent, ViewPager pager) {
super(parent, pager);
actionBar = parent.getActionBar();
}
public void createTabs() {
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
for (int i = 0; i < pager.getAdapter().getCount(); i ++) {
CharSequence label = pager.getAdapter().getPageTitle(i);
actionBar.addTab(
actionBar.newTab()
.setText(label)
.setTabListener(new ActionBar.TabListener() {
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction ft) {
pager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
}));
}
}
public void selectTab(int index) {
actionBar.setSelectedNavigationItem(index);
}
public void refreshTabLabel(int index) {
CharSequence text = getLabel(index);
actionBar.getTabAt(index).setText(text);
}
}

View File

@ -27,10 +27,6 @@ public class AppListView extends LinearLayout {
super(context, attrs);
}
public AppListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setAppList(ListView appList) {
this.appList = appList;
}