Formatting fixes only - seems I had the wrong settings on one of my machines at some point

This commit is contained in:
Ciaran Gultnieks 2011-01-16 12:21:35 +00:00
parent c629a6884f
commit 3aa6d5a7a9
5 changed files with 1271 additions and 1271 deletions

File diff suppressed because it is too large Load Diff

View File

@ -60,423 +60,423 @@ import android.widget.TabHost.TabSpec;
public class FDroid extends TabActivity implements OnItemClickListener { public class FDroid extends TabActivity implements OnItemClickListener {
private class AppListAdapter extends BaseAdapter { private class AppListAdapter extends BaseAdapter {
private List<DB.App> items = new ArrayList<DB.App>(); private List<DB.App> items = new ArrayList<DB.App>();
public AppListAdapter(Context context) { public AppListAdapter(Context context) {
} }
public void addItem(DB.App app) { public void addItem(DB.App app) {
items.add(app); items.add(app);
} }
public void clear() { public void clear() {
items.clear(); items.clear();
} }
@Override @Override
public int getCount() { public int getCount() {
return items.size(); return items.size();
} }
@Override @Override
public Object getItem(int position) { public Object getItem(int position) {
return items.get(position); return items.get(position);
} }
@Override @Override
public long getItemId(int position) { public long getItemId(int position) {
return position; return position;
} }
@Override @Override
public View getView(int position, View convertView, ViewGroup parent) { public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView; View v = convertView;
if (v == null) { if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.applistitem, null); v = vi.inflate(R.layout.applistitem, null);
} }
DB.App app = items.get(position); DB.App app = items.get(position);
TextView name = (TextView) v.findViewById(R.id.name); TextView name = (TextView) v.findViewById(R.id.name);
name.setText(app.name); name.setText(app.name);
String vs; String vs;
int numav = app.apks.size(); int numav = app.apks.size();
if (numav == 1) if (numav == 1)
vs = getString(R.string.n_version_available); vs = getString(R.string.n_version_available);
else else
vs = getString(R.string.n_versions_available); vs = getString(R.string.n_versions_available);
TextView status = (TextView) v.findViewById(R.id.status); TextView status = (TextView) v.findViewById(R.id.status);
status.setText(String.format(vs, numav)); status.setText(String.format(vs, numav));
TextView license = (TextView) v.findViewById(R.id.license); TextView license = (TextView) v.findViewById(R.id.license);
license.setText(app.license); license.setText(app.license);
TextView summary = (TextView) v.findViewById(R.id.summary); TextView summary = (TextView) v.findViewById(R.id.summary);
summary.setText(app.summary); summary.setText(app.summary);
ImageView icon = (ImageView) v.findViewById(R.id.icon); ImageView icon = (ImageView) v.findViewById(R.id.icon);
String iconpath = new String(DB.getIconsPath() + app.icon); String iconpath = new String(DB.getIconsPath() + app.icon);
File icn = new File(iconpath); File icn = new File(iconpath);
if (icn.exists() && icn.length() > 0) { if (icn.exists() && icn.length() > 0) {
new Uri.Builder().build(); new Uri.Builder().build();
icon.setImageURI(Uri.parse(iconpath)); icon.setImageURI(Uri.parse(iconpath));
} else { } else {
icon.setImageResource(android.R.drawable.sym_def_app_icon); icon.setImageResource(android.R.drawable.sym_def_app_icon);
} }
return v; return v;
} }
} }
private String LOCAL_PATH = "/sdcard/.fdroid"; private String LOCAL_PATH = "/sdcard/.fdroid";
private static final int REQUEST_APPDETAILS = 0; private static final int REQUEST_APPDETAILS = 0;
private static final int REQUEST_MANAGEREPOS = 1; private static final int REQUEST_MANAGEREPOS = 1;
private static final int REQUEST_PREFS = 2; private static final int REQUEST_PREFS = 2;
private static final int UPDATE_REPO = Menu.FIRST; private static final int UPDATE_REPO = Menu.FIRST;
private static final int MANAGE_REPO = Menu.FIRST + 1; private static final int MANAGE_REPO = Menu.FIRST + 1;
private static final int PREFERENCES = Menu.FIRST + 2; private static final int PREFERENCES = Menu.FIRST + 2;
private static final int ABOUT = Menu.FIRST + 3; private static final int ABOUT = Menu.FIRST + 3;
private DB db = null; private DB db = null;
// Apps that are available to be installed // Apps that are available to be installed
private AppListAdapter apps_av = new AppListAdapter(this); private AppListAdapter apps_av = new AppListAdapter(this);
// Apps that are installed // Apps that are installed
private AppListAdapter apps_in = new AppListAdapter(this); private AppListAdapter apps_in = new AppListAdapter(this);
// Apps that can be upgraded // Apps that can be upgraded
private AppListAdapter apps_up = new AppListAdapter(this); private AppListAdapter apps_up = new AppListAdapter(this);
private ProgressDialog pd; private ProgressDialog pd;
private static final String TAB_IN = "INST"; private static final String TAB_IN = "INST";
private static final String TAB_UN = "UNIN"; private static final String TAB_UN = "UNIN";
private static final String TAB_UP = "UPDT"; private static final String TAB_UP = "UPDT";
private TabHost tabHost; private TabHost tabHost;
private TabSpec ts; private TabSpec ts;
private TabSpec ts1; private TabSpec ts1;
private TabSpec tsUp; private TabSpec tsUp;
private boolean triedEmptyUpdate; private boolean triedEmptyUpdate;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.fdroid); setContentView(R.layout.fdroid);
File local_path = new File(LOCAL_PATH); File local_path = new File(LOCAL_PATH);
if (!local_path.exists()) if (!local_path.exists())
local_path.mkdir(); local_path.mkdir();
File icon_path = new File(DB.getIconsPath()); File icon_path = new File(DB.getIconsPath());
if (!icon_path.exists()) if (!icon_path.exists())
icon_path.mkdir(); icon_path.mkdir();
tabHost = getTabHost(); tabHost = getTabHost();
createTabs(); createTabs();
Intent i = getIntent(); Intent i = getIntent();
if (i.hasExtra("uri")) { if (i.hasExtra("uri")) {
Intent call = new Intent(this, ManageRepo.class); Intent call = new Intent(this, ManageRepo.class);
call.putExtra("uri", i.getStringExtra("uri")); call.putExtra("uri", i.getStringExtra("uri"));
startActivityForResult(call, REQUEST_MANAGEREPOS); startActivityForResult(call, REQUEST_MANAGEREPOS);
} }
} }
@Override @Override
protected void onStart() { protected void onStart() {
super.onStart(); super.onStart();
((FDroidApp) getApplication()).inActivity++; ((FDroidApp) getApplication()).inActivity++;
db = new DB(this); db = new DB(this);
triedEmptyUpdate = false; triedEmptyUpdate = false;
populateLists(true); populateLists(true);
} }
@Override @Override
protected void onStop() { protected void onStop() {
db.close(); db.close();
((FDroidApp) getApplication()).inActivity--; ((FDroidApp) getApplication()).inActivity--;
super.onStop(); super.onStop();
} }
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu); super.onCreateOptionsMenu(menu);
menu.add(Menu.NONE, UPDATE_REPO, 1, R.string.menu_update_repo).setIcon( menu.add(Menu.NONE, UPDATE_REPO, 1, R.string.menu_update_repo).setIcon(
android.R.drawable.ic_menu_rotate); android.R.drawable.ic_menu_rotate);
menu.add(Menu.NONE, MANAGE_REPO, 2, R.string.menu_manage).setIcon( menu.add(Menu.NONE, MANAGE_REPO, 2, R.string.menu_manage).setIcon(
android.R.drawable.ic_menu_agenda); android.R.drawable.ic_menu_agenda);
menu.add(Menu.NONE, PREFERENCES, 3, R.string.menu_preferences).setIcon( menu.add(Menu.NONE, PREFERENCES, 3, R.string.menu_preferences).setIcon(
android.R.drawable.ic_menu_preferences); android.R.drawable.ic_menu_preferences);
menu.add(Menu.NONE, ABOUT, 4, R.string.menu_about).setIcon( menu.add(Menu.NONE, ABOUT, 4, R.string.menu_about).setIcon(
android.R.drawable.ic_menu_help); android.R.drawable.ic_menu_help);
return true; return true;
} }
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case UPDATE_REPO: case UPDATE_REPO:
updateRepos(); updateRepos();
return true; return true;
case MANAGE_REPO: case MANAGE_REPO:
Intent i = new Intent(this, ManageRepo.class); Intent i = new Intent(this, ManageRepo.class);
startActivityForResult(i, REQUEST_MANAGEREPOS); startActivityForResult(i, REQUEST_MANAGEREPOS);
return true; return true;
case PREFERENCES: case PREFERENCES:
Intent prefs = new Intent(getBaseContext(), Preferences.class); Intent prefs = new Intent(getBaseContext(), Preferences.class);
startActivityForResult(prefs, REQUEST_PREFS); startActivityForResult(prefs, REQUEST_PREFS);
return true; return true;
case ABOUT: case ABOUT:
LayoutInflater li = LayoutInflater.from(this); LayoutInflater li = LayoutInflater.from(this);
View view = li.inflate(R.layout.about, null); View view = li.inflate(R.layout.about, null);
// Fill in the version... // Fill in the version...
TextView tv = (TextView) view.findViewById(R.id.version); TextView tv = (TextView) view.findViewById(R.id.version);
PackageManager pm = getPackageManager(); PackageManager pm = getPackageManager();
PackageInfo pi; PackageInfo pi;
try { try {
pi = pm.getPackageInfo( pi = pm.getPackageInfo(
getApplicationContext().getPackageName(), 0); getApplicationContext().getPackageName(), 0);
tv.setText(pi.versionName); tv.setText(pi.versionName);
} catch (Exception e) { } catch (Exception e) {
} }
Builder p = new AlertDialog.Builder(this).setView(view); Builder p = new AlertDialog.Builder(this).setView(view);
final AlertDialog alrt = p.create(); final AlertDialog alrt = p.create();
alrt.setIcon(R.drawable.icon); alrt.setIcon(R.drawable.icon);
alrt.setTitle(getString(R.string.about_title)); alrt.setTitle(getString(R.string.about_title));
alrt.setButton(AlertDialog.BUTTON_NEUTRAL, alrt.setButton(AlertDialog.BUTTON_NEUTRAL,
getString(R.string.about_website), getString(R.string.about_website),
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, public void onClick(DialogInterface dialog,
int whichButton) { int whichButton) {
Uri uri = Uri.parse("http://f-droid.org"); Uri uri = Uri.parse("http://f-droid.org");
startActivity(new Intent(Intent.ACTION_VIEW, uri)); startActivity(new Intent(Intent.ACTION_VIEW, uri));
} }
}); });
alrt.setButton(AlertDialog.BUTTON_NEGATIVE, getString(R.string.ok), alrt.setButton(AlertDialog.BUTTON_NEGATIVE, getString(R.string.ok),
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, public void onClick(DialogInterface dialog,
int whichButton) { int whichButton) {
} }
}); });
alrt.show(); alrt.show();
return true; return true;
} }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@Override @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) { switch (requestCode) {
case REQUEST_APPDETAILS: case REQUEST_APPDETAILS:
break; break;
case REQUEST_MANAGEREPOS: case REQUEST_MANAGEREPOS:
if (data.hasExtra("update")) { if (data.hasExtra("update")) {
AlertDialog.Builder ask_alrt = new AlertDialog.Builder(this); AlertDialog.Builder ask_alrt = new AlertDialog.Builder(this);
ask_alrt.setTitle(getString(R.string.repo_update_title)); ask_alrt.setTitle(getString(R.string.repo_update_title));
ask_alrt.setIcon(android.R.drawable.ic_menu_rotate); ask_alrt.setIcon(android.R.drawable.ic_menu_rotate);
ask_alrt.setMessage(getString(R.string.repo_alrt)); ask_alrt.setMessage(getString(R.string.repo_alrt));
ask_alrt.setPositiveButton(getString(R.string.yes), ask_alrt.setPositiveButton(getString(R.string.yes),
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, public void onClick(DialogInterface dialog,
int whichButton) { int whichButton) {
updateRepos(); updateRepos();
} }
}); });
ask_alrt.setNegativeButton(getString(R.string.no), ask_alrt.setNegativeButton(getString(R.string.no),
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, public void onClick(DialogInterface dialog,
int whichButton) { int whichButton) {
return; return;
} }
}); });
AlertDialog alert = ask_alrt.create(); AlertDialog alert = ask_alrt.create();
alert.show(); alert.show();
} }
break; break;
case REQUEST_PREFS: case REQUEST_PREFS:
// The automatic update settings may have changed, so reschedule (or // The automatic update settings may have changed, so reschedule (or
// unschedule) the // unschedule) the
// service accordingly. It's cheap, so no need to check if the // service accordingly. It's cheap, so no need to check if the
// particular setting has // particular setting has
// actually been changed. // actually been changed.
UpdateService.schedule(getBaseContext()); UpdateService.schedule(getBaseContext());
break; break;
} }
} }
private void createTabs() { private void createTabs() {
tabHost.clearAllTabs(); tabHost.clearAllTabs();
// TabContentFactory that can generate the appropriate list for each // TabContentFactory that can generate the appropriate list for each
// tab... // tab...
TabHost.TabContentFactory tf = new TabHost.TabContentFactory() { TabHost.TabContentFactory tf = new TabHost.TabContentFactory() {
@Override @Override
public View createTabContent(String tag) { public View createTabContent(String tag) {
AppListAdapter ad; AppListAdapter ad;
if (tag.equals(TAB_IN)) if (tag.equals(TAB_IN))
ad = apps_in; ad = apps_in;
else if (tag.equals(TAB_UP)) else if (tag.equals(TAB_UP))
ad = apps_up; ad = apps_up;
else else
ad = apps_av; ad = apps_av;
ListView lst = new ListView(FDroid.this); ListView lst = new ListView(FDroid.this);
lst.setOnItemClickListener(FDroid.this); lst.setOnItemClickListener(FDroid.this);
lst.setAdapter(ad); lst.setAdapter(ad);
return lst; return lst;
} }
}; };
// Create the tab of installed apps... // Create the tab of installed apps...
ts = tabHost.newTabSpec(TAB_IN); ts = tabHost.newTabSpec(TAB_IN);
ts.setIndicator(getString(R.string.tab_installed), getResources() ts.setIndicator(getString(R.string.tab_installed), getResources()
.getDrawable(drawable.star_off)); .getDrawable(drawable.star_off));
ts.setContent(tf); ts.setContent(tf);
// Create the tab of apps with updates... // Create the tab of apps with updates...
tsUp = tabHost.newTabSpec(TAB_UP); tsUp = tabHost.newTabSpec(TAB_UP);
tsUp.setIndicator(getString(R.string.tab_updates), getResources() tsUp.setIndicator(getString(R.string.tab_updates), getResources()
.getDrawable(drawable.star_on)); .getDrawable(drawable.star_on));
tsUp.setContent(tf); tsUp.setContent(tf);
// Create the tab of available apps... // Create the tab of available apps...
ts1 = tabHost.newTabSpec(TAB_UN); ts1 = tabHost.newTabSpec(TAB_UN);
ts1.setIndicator(getString(R.string.tab_noninstalled), getResources() ts1.setIndicator(getString(R.string.tab_noninstalled), getResources()
.getDrawable(drawable.ic_input_add)); .getDrawable(drawable.ic_input_add));
ts1.setContent(tf); ts1.setContent(tf);
tabHost.addTab(ts1); tabHost.addTab(ts1);
tabHost.addTab(ts); tabHost.addTab(ts);
tabHost.addTab(tsUp); tabHost.addTab(tsUp);
} }
// Populate the lists. // Populate the lists.
// 'update' - true to update the installed status of the applications // 'update' - true to update the installed status of the applications
// by asking the system. // by asking the system.
private void populateLists(boolean update) { private void populateLists(boolean update) {
apps_in.clear(); apps_in.clear();
apps_av.clear(); apps_av.clear();
apps_up.clear(); apps_up.clear();
Vector<DB.App> apps = db.getApps(null, null, update); Vector<DB.App> apps = db.getApps(null, null, update);
if (apps.isEmpty()) { if (apps.isEmpty()) {
// Don't attempt this more than once - we may have invalid // Don't attempt this more than once - we may have invalid
// repositories. // repositories.
if (triedEmptyUpdate) if (triedEmptyUpdate)
return; return;
// If there are no apps, update from the repos - it must be a // If there are no apps, update from the repos - it must be a
// new installation. // new installation.
Log.d("FDroid", "Empty app list forces repo update"); Log.d("FDroid", "Empty app list forces repo update");
updateRepos(); updateRepos();
triedEmptyUpdate = true; triedEmptyUpdate = true;
return; return;
} }
Log.d("FDroid", "Updating lists - " + apps.size() + " apps in total"); Log.d("FDroid", "Updating lists - " + apps.size() + " apps in total");
for (DB.App app : apps) { for (DB.App app : apps) {
if (app.installedVersion == null) { if (app.installedVersion == null) {
apps_av.addItem(app); apps_av.addItem(app);
} else { } else {
apps_in.addItem(app); apps_in.addItem(app);
if (app.hasUpdates) if (app.hasUpdates)
apps_up.addItem(app); apps_up.addItem(app);
} }
} }
// Update the count on the 'Updates' tab to show the number available. // 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. // This is quite unpleasant, but seems to be the only way to do it.
TextView uptext = (TextView) tabHost.getTabWidget().getChildAt(2) TextView uptext = (TextView) tabHost.getTabWidget().getChildAt(2)
.findViewById(android.R.id.title); .findViewById(android.R.id.title);
uptext.setText(getString(R.string.tab_updates) + " (" uptext.setText(getString(R.string.tab_updates) + " ("
+ Integer.toString(apps_up.getCount()) + ")"); + Integer.toString(apps_up.getCount()) + ")");
// Tell the lists that the data behind the adapter has changed, so // Tell the lists that the data behind the adapter has changed, so
// they can refresh... // they can refresh...
apps_av.notifyDataSetChanged(); apps_av.notifyDataSetChanged();
apps_in.notifyDataSetChanged(); apps_in.notifyDataSetChanged();
apps_up.notifyDataSetChanged(); apps_up.notifyDataSetChanged();
} }
public boolean updateRepos() { public boolean updateRepos() {
pd = ProgressDialog.show(this, getString(R.string.process_wait_title), pd = ProgressDialog.show(this, getString(R.string.process_wait_title),
getString(R.string.process_update_msg), true); getString(R.string.process_update_msg), true);
pd.setIcon(android.R.drawable.ic_dialog_info); pd.setIcon(android.R.drawable.ic_dialog_info);
// Check for connection first! // Check for connection first!
ConnectivityManager netstate = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); ConnectivityManager netstate = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (netstate.getNetworkInfo(1).getState() == NetworkInfo.State.CONNECTED if (netstate.getNetworkInfo(1).getState() == NetworkInfo.State.CONNECTED
|| netstate.getNetworkInfo(0).getState() == NetworkInfo.State.CONNECTED) { || netstate.getNetworkInfo(0).getState() == NetworkInfo.State.CONNECTED) {
new Thread() { new Thread() {
public void run() { public void run() {
RepoXMLHandler.doUpdates(FDroid.this, db); RepoXMLHandler.doUpdates(FDroid.this, db);
update_handler.sendEmptyMessage(0); update_handler.sendEmptyMessage(0);
} }
}.start(); }.start();
return true; return true;
} else { } else {
pd.dismiss(); pd.dismiss();
Toast.makeText(FDroid.this, getString(R.string.connection_error), Toast.makeText(FDroid.this, getString(R.string.connection_error),
Toast.LENGTH_LONG).show(); Toast.LENGTH_LONG).show();
return false; return false;
} }
} }
/* /*
* Handlers for thread functions that need to access GUI * Handlers for thread functions that need to access GUI
*/ */
private Handler update_handler = new Handler() { private Handler update_handler = new Handler() {
@Override @Override
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
populateLists(true); populateLists(true);
if (pd.isShowing()) if (pd.isShowing())
pd.dismiss(); pd.dismiss();
} }
}; };
// Handler for a click on one of the items in an application list. Pops // Handler for a click on one of the items in an application list. Pops
// up a dialog that shows the details of the application and all its // up a dialog that shows the details of the application and all its
// available versions, with buttons to allow installation etc. // available versions, with buttons to allow installation etc.
public void onItemClick(AdapterView<?> arg0, View arg1, final int arg2, public void onItemClick(AdapterView<?> arg0, View arg1, final int arg2,
long arg3) { long arg3) {
final DB.App app; final DB.App app;
String curtab = tabHost.getCurrentTabTag(); String curtab = tabHost.getCurrentTabTag();
if (curtab.equalsIgnoreCase(TAB_IN)) { if (curtab.equalsIgnoreCase(TAB_IN)) {
app = (DB.App) apps_in.getItem(arg2); app = (DB.App) apps_in.getItem(arg2);
} else if (curtab.equalsIgnoreCase(TAB_UP)) { } else if (curtab.equalsIgnoreCase(TAB_UP)) {
app = (DB.App) apps_up.getItem(arg2); app = (DB.App) apps_up.getItem(arg2);
} else { } else {
app = (DB.App) apps_av.getItem(arg2); app = (DB.App) apps_av.getItem(arg2);
} }
Intent intent = new Intent(this, AppDetails.class); Intent intent = new Intent(this, AppDetails.class);
intent.putExtra("appid", app.id); intent.putExtra("appid", app.id);
startActivityForResult(intent, REQUEST_APPDETAILS); startActivityForResult(intent, REQUEST_APPDETAILS);
} }
} }

View File

@ -26,6 +26,6 @@ public class FDroidApp extends Application {
// don't want a database update to run. Incremented when entering // don't want a database update to run. Incremented when entering
// one, and decremented when leaving, so if it's 0 it ought to be // one, and decremented when leaving, so if it's 0 it ought to be
// ok! // ok!
public int inActivity=0; public int inActivity = 0;
} }

View File

@ -42,203 +42,203 @@ import android.util.Log;
public class RepoXMLHandler extends DefaultHandler { public class RepoXMLHandler extends DefaultHandler {
String mserver; String mserver;
private DB db; private DB db;
private DB.App curapp = null; private DB.App curapp = null;
private DB.Apk curapk = null; private DB.Apk curapk = null;
private String curchars = null; private String curchars = null;
public RepoXMLHandler(String srv, DB db) { public RepoXMLHandler(String srv, DB db) {
mserver = srv; mserver = srv;
this.db = db; this.db = db;
} }
@Override @Override
public void characters(char[] ch, int start, int length) public void characters(char[] ch, int start, int length)
throws SAXException { throws SAXException {
super.characters(ch, start, length); super.characters(ch, start, length);
String str = new String(ch).substring(start, start + length); String str = new String(ch).substring(start, start + length);
if (curchars == null) if (curchars == null)
curchars = str; curchars = str;
else else
curchars += str; curchars += str;
} }
@Override @Override
public void endElement(String uri, String localName, String qName) public void endElement(String uri, String localName, String qName)
throws SAXException { throws SAXException {
super.endElement(uri, localName, qName); super.endElement(uri, localName, qName);
String curel = localName; String curel = localName;
String str = curchars; String str = curchars;
if (curel == "application" && curapp != null) { if (curel == "application" && curapp != null) {
Log.d("FDroid", "Repo: Updating application " + curapp.id); Log.d("FDroid", "Repo: Updating application " + curapp.id);
db.updateApplication(curapp); db.updateApplication(curapp);
getIcon(curapp); getIcon(curapp);
curapp = null; curapp = null;
} else if (curel == "package" && curapk != null && curapp != null) { } else if (curel == "package" && curapk != null && curapp != null) {
Log.d("FDroid", "Repo: Package added (" + curapk.version + ")"); Log.d("FDroid", "Repo: Package added (" + curapk.version + ")");
curapp.apks.add(curapk); curapp.apks.add(curapk);
curapk = null; curapk = null;
} else if (curapk != null && str != null) { } else if (curapk != null && str != null) {
if (curel == "version") { if (curel == "version") {
curapk.version = str; curapk.version = str;
} else if (curel == "versioncode") { } else if (curel == "versioncode") {
try { try {
curapk.vercode = Integer.parseInt(str); curapk.vercode = Integer.parseInt(str);
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
curapk.vercode = 0; curapk.vercode = 0;
} }
} else if (curel == "size") { } else if (curel == "size") {
try { try {
curapk.size = Integer.parseInt(str); curapk.size = Integer.parseInt(str);
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
curapk.size = 0; curapk.size = 0;
} }
} else if (curel == "hash") { } else if (curel == "hash") {
curapk.hash = str; curapk.hash = str;
} else if (curel == "apkname") { } else if (curel == "apkname") {
curapk.apkName = str; curapk.apkName = str;
} else if (curel == "apksource") { } else if (curel == "apksource") {
curapk.apkSource = str; curapk.apkSource = str;
} }
} else if (curapp != null && str != null) { } else if (curapp != null && str != null) {
if (curel == "id") { if (curel == "id") {
Log.d("FDroid", "App id is " + str); Log.d("FDroid", "App id is " + str);
curapp.id = str; curapp.id = str;
} else if (curel == "name") { } else if (curel == "name") {
curapp.name = str; curapp.name = str;
} else if (curel == "icon") { } else if (curel == "icon") {
curapp.icon = str; curapp.icon = str;
} else if (curel == "description") { } else if (curel == "description") {
curapp.description = str; curapp.description = str;
} else if (curel == "summary") { } else if (curel == "summary") {
curapp.summary = str; curapp.summary = str;
} else if (curel == "license") { } else if (curel == "license") {
curapp.license = str; curapp.license = str;
} else if (curel == "source") { } else if (curel == "source") {
curapp.sourceURL = str; curapp.sourceURL = str;
} else if (curel == "web") { } else if (curel == "web") {
curapp.webURL = str; curapp.webURL = str;
} else if (curel == "tracker") { } else if (curel == "tracker") {
curapp.trackerURL = str; curapp.trackerURL = str;
} else if (curel == "marketversion") { } else if (curel == "marketversion") {
curapp.marketVersion = str; curapp.marketVersion = str;
} else if (curel == "marketvercode") { } else if (curel == "marketvercode") {
try { try {
curapp.marketVercode = Integer.parseInt(str); curapp.marketVercode = Integer.parseInt(str);
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
curapp.marketVercode = 0; curapp.marketVercode = 0;
} }
} else if (curel == "antifeatures") { } else if (curel == "antifeatures") {
curapp.antiFeatures = str; curapp.antiFeatures = str;
} }
} }
} }
@Override @Override
public void startElement(String uri, String localName, String qName, public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException { Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes); super.startElement(uri, localName, qName, attributes);
if (localName == "application" && curapp == null) { if (localName == "application" && curapp == null) {
Log.d("FDroid", "Repo: Found application at " + mserver); Log.d("FDroid", "Repo: Found application at " + mserver);
curapp = new DB.App(); curapp = new DB.App();
} else if (localName == "package" && curapp != null && curapk == null) { } else if (localName == "package" && curapp != null && curapk == null) {
Log.d("FDroid", "Repo: Found package for " + curapp.id); Log.d("FDroid", "Repo: Found package for " + curapp.id);
curapk = new DB.Apk(); curapk = new DB.Apk();
curapk.id = curapp.id; curapk.id = curapp.id;
curapk.server = mserver; curapk.server = mserver;
} }
curchars = null; curchars = null;
} }
private void getIcon(DB.App app) { private void getIcon(DB.App app) {
try { try {
String destpath = DB.getIconsPath() + app.icon; String destpath = DB.getIconsPath() + app.icon;
File f = new File(destpath); File f = new File(destpath);
if (f.exists()) if (f.exists())
return; return;
BufferedInputStream getit = new BufferedInputStream(new URL(mserver BufferedInputStream getit = new BufferedInputStream(new URL(mserver
+ "/icons/" + app.icon).openStream()); + "/icons/" + app.icon).openStream());
FileOutputStream saveit = new FileOutputStream(destpath); FileOutputStream saveit = new FileOutputStream(destpath);
BufferedOutputStream bout = new BufferedOutputStream(saveit, 1024); BufferedOutputStream bout = new BufferedOutputStream(saveit, 1024);
byte data[] = new byte[1024]; byte data[] = new byte[1024];
int readed = getit.read(data, 0, 1024); int readed = getit.read(data, 0, 1024);
while (readed != -1) { while (readed != -1) {
bout.write(data, 0, readed); bout.write(data, 0, readed);
readed = getit.read(data, 0, 1024); readed = getit.read(data, 0, 1024);
} }
bout.close(); bout.close();
getit.close(); getit.close();
saveit.close(); saveit.close();
} catch (Exception e) { } catch (Exception e) {
} }
} }
public static void doUpdates(Context ctx, DB db) { public static void doUpdates(Context ctx, DB db) {
db.beginUpdate(); db.beginUpdate();
Vector<DB.Repo> repos = db.getRepos(); Vector<DB.Repo> repos = db.getRepos();
for (DB.Repo repo : repos) { for (DB.Repo repo : repos) {
if (repo.inuse) { if (repo.inuse) {
try { try {
FileOutputStream f = ctx.openFileOutput("tempindex.xml", FileOutputStream f = ctx.openFileOutput("tempindex.xml",
Context.MODE_PRIVATE); Context.MODE_PRIVATE);
// Download the index file from the repo... // Download the index file from the repo...
BufferedInputStream getit = new BufferedInputStream( BufferedInputStream getit = new BufferedInputStream(
new URL(repo.address + "/index.xml").openStream()); new URL(repo.address + "/index.xml").openStream());
BufferedOutputStream bout = new BufferedOutputStream(f, BufferedOutputStream bout = new BufferedOutputStream(f,
1024); 1024);
byte data[] = new byte[1024]; byte data[] = new byte[1024];
int readed = getit.read(data, 0, 1024); int readed = getit.read(data, 0, 1024);
while (readed != -1) { while (readed != -1) {
bout.write(data, 0, readed); bout.write(data, 0, readed);
readed = getit.read(data, 0, 1024); readed = getit.read(data, 0, 1024);
} }
bout.close(); bout.close();
getit.close(); getit.close();
f.close(); f.close();
// Process the index... // Process the index...
SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser(); SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader(); XMLReader xr = sp.getXMLReader();
RepoXMLHandler handler = new RepoXMLHandler(repo.address, RepoXMLHandler handler = new RepoXMLHandler(repo.address,
db); db);
xr.setContentHandler(handler); xr.setContentHandler(handler);
InputStreamReader isr = new FileReader(new File(ctx InputStreamReader isr = new FileReader(new File(ctx
.getFilesDir() .getFilesDir()
+ "/tempindex.xml")); + "/tempindex.xml"));
InputSource is = new InputSource(isr); InputSource is = new InputSource(isr);
xr.parse(is); xr.parse(is);
} catch (Exception e) { } catch (Exception e) {
Log.d("FDroid", "Exception updating from " + repo.address Log.d("FDroid", "Exception updating from " + repo.address
+ " - " + e.getMessage()); + " - " + e.getMessage());
} finally { } finally {
ctx.deleteFile("tempindex.xml"); ctx.deleteFile("tempindex.xml");
} }
} }
} }
db.endUpdate(); db.endUpdate();
} }
} }

View File

@ -35,129 +35,129 @@ import android.util.Log;
public class UpdateService extends Service { public class UpdateService extends Service {
// Schedule (or cancel schedule for) this service, according to the // Schedule (or cancel schedule for) this service, according to the
// current preferences. Should be called a) at boot, or b) if the preference // current preferences. Should be called a) at boot, or b) if the preference
// is changed. // is changed.
// TODO: What if we get upgraded? // TODO: What if we get upgraded?
public static void schedule(Context ctx) { public static void schedule(Context ctx) {
SharedPreferences prefs = PreferenceManager SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(ctx); .getDefaultSharedPreferences(ctx);
String sint = prefs.getString("updateInterval", "0"); String sint = prefs.getString("updateInterval", "0");
int interval = Integer.parseInt(sint); int interval = Integer.parseInt(sint);
Intent intent = new Intent(ctx, UpdateService.class); Intent intent = new Intent(ctx, UpdateService.class);
PendingIntent pending = PendingIntent.getService(ctx, 0, intent, 0); PendingIntent pending = PendingIntent.getService(ctx, 0, intent, 0);
AlarmManager alarm = (AlarmManager) ctx AlarmManager alarm = (AlarmManager) ctx
.getSystemService(Context.ALARM_SERVICE); .getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pending); alarm.cancel(pending);
if (interval > 0) { if (interval > 0) {
alarm.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, alarm.setInexactRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 5000, SystemClock.elapsedRealtime() + 5000,
AlarmManager.INTERVAL_HOUR, pending); AlarmManager.INTERVAL_HOUR, pending);
} }
} }
// For API levels <5 // For API levels <5
@Override @Override
public void onStart(Intent intent, int startId) { public void onStart(Intent intent, int startId) {
handleCommand(); handleCommand();
} }
// For API levels >=5 // For API levels >=5
@Override @Override
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(Intent intent, int flags, int startId) {
handleCommand(); handleCommand();
return START_REDELIVER_INTENT; return START_REDELIVER_INTENT;
} }
private void handleCommand() { private void handleCommand() {
new Thread() { new Thread() {
public void run() { public void run() {
// If we're in one of our list activities, we don't want // If we're in one of our list activities, we don't want
// to run an update because the database will be out of // to run an update because the database will be out of
// sync with the display. // sync with the display.
if (((FDroidApp) getApplication()).inActivity != 0) if (((FDroidApp) getApplication()).inActivity != 0)
return; return;
// See if it's time to actually do anything yet... // See if it's time to actually do anything yet...
SharedPreferences prefs = PreferenceManager SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(getBaseContext()); .getDefaultSharedPreferences(getBaseContext());
long lastUpdate = prefs.getLong("lastUpdateCheck", 0); long lastUpdate = prefs.getLong("lastUpdateCheck", 0);
String sint = prefs.getString("updateInterval", "0"); String sint = prefs.getString("updateInterval", "0");
int interval = Integer.parseInt(sint); int interval = Integer.parseInt(sint);
if (interval == 0) if (interval == 0)
return; return;
if (lastUpdate + (interval * 60 * 60) > System if (lastUpdate + (interval * 60 * 60) > System
.currentTimeMillis()) .currentTimeMillis())
return; return;
// Make sure we have a connection... // Make sure we have a connection...
ConnectivityManager netstate = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); ConnectivityManager netstate = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (netstate.getNetworkInfo(1).getState() != NetworkInfo.State.CONNECTED if (netstate.getNetworkInfo(1).getState() != NetworkInfo.State.CONNECTED
&& netstate.getNetworkInfo(0).getState() != NetworkInfo.State.CONNECTED) && netstate.getNetworkInfo(0).getState() != NetworkInfo.State.CONNECTED)
return; return;
// Do the update... // Do the update...
DB db = null; DB db = null;
try { try {
db = new DB(getBaseContext()); db = new DB(getBaseContext());
boolean notify = prefs.getBoolean("updateNotify", false); boolean notify = prefs.getBoolean("updateNotify", false);
// Get the number of updates available before we // Get the number of updates available before we
// start, so we can notify if there are new ones. // start, so we can notify if there are new ones.
// (But avoid doing it if the user doesn't want // (But avoid doing it if the user doesn't want
// notifications, since it may be time consuming) // notifications, since it may be time consuming)
int prevUpdates = 0; int prevUpdates = 0;
if (notify) if (notify)
prevUpdates = db.getNumUpdates(); prevUpdates = db.getNumUpdates();
RepoXMLHandler.doUpdates(getBaseContext(), db); RepoXMLHandler.doUpdates(getBaseContext(), db);
if (notify) { if (notify) {
if (db.getNumUpdates() > prevUpdates) { if (db.getNumUpdates() > prevUpdates) {
// And the user wants to know. // And the user wants to know.
NotificationManager n = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager n = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification( Notification notification = new Notification(
R.drawable.icon, R.drawable.icon,
"FDroid Updates Available", System "FDroid Updates Available", System
.currentTimeMillis()); .currentTimeMillis());
Context context = getApplicationContext(); Context context = getApplicationContext();
CharSequence contentTitle = "FDroid"; CharSequence contentTitle = "FDroid";
CharSequence contentText = "Updates are available."; CharSequence contentText = "Updates are available.";
Intent notificationIntent = new Intent( Intent notificationIntent = new Intent(
UpdateService.this, FDroid.class); UpdateService.this, FDroid.class);
PendingIntent contentIntent = PendingIntent PendingIntent contentIntent = PendingIntent
.getActivity(UpdateService.this, 0, .getActivity(UpdateService.this, 0,
notificationIntent, 0); notificationIntent, 0);
notification.setLatestEventInfo(context, notification.setLatestEventInfo(context,
contentTitle, contentText, contentIntent); contentTitle, contentText, contentIntent);
notification.flags |= Notification.FLAG_AUTO_CANCEL; notification.flags |= Notification.FLAG_AUTO_CANCEL;
n.notify(1, notification); n.notify(1, notification);
} }
} }
} catch (Exception e) { } catch (Exception e) {
Log.d("FDroid", "Exception during handleCommand() - " Log.d("FDroid", "Exception during handleCommand() - "
+ e.getMessage()); + e.getMessage());
} finally { } finally {
if (db != null) if (db != null)
db.close(); db.close();
stopSelf(); stopSelf();
} }
} }
}.start(); }.start();
} }
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
return null; return null;
} }
} }