diff --git a/src/org/fdroid/fdroid/AppDetails.java b/src/org/fdroid/fdroid/AppDetails.java index c629af1e4..027e4aadb 100644 --- a/src/org/fdroid/fdroid/AppDetails.java +++ b/src/org/fdroid/fdroid/AppDetails.java @@ -314,10 +314,9 @@ public class AppDetails extends ListActivity { private void resetViews() { // Set the icon... ImageView iv = (ImageView) findViewById(R.id.icon); - String icon_path = DB.getIconsPath() + app.icon; - File test_icon = new File(icon_path); - if (test_icon.exists()) { - iv.setImageDrawable(new BitmapDrawable(icon_path)); + File icon = new File(DB.getIconsPath(), app.icon); + if (icon.exists()) { + iv.setImageDrawable(new BitmapDrawable(icon.getPath())); } else { iv.setImageResource(android.R.drawable.sym_def_app_icon); } @@ -473,10 +472,10 @@ public class AppDetails extends ListActivity { } - private void installApk(String file) { + private void installApk(File file) { Intent intent = new Intent(); intent.setAction(android.content.Intent.ACTION_VIEW); - intent.setDataAndType(Uri.parse("file://" + file), + intent.setDataAndType(Uri.parse("file://" + file.getPath()), "application/vnd.android.package-archive"); startActivityForResult(intent, REQUEST_INSTALL); ((FDroidApp) getApplication()).invalidateApps(); @@ -509,7 +508,7 @@ public class AppDetails extends ListActivity { private Downloader download; private ProgressDialog pd; private boolean updating; - private String localFile; + private File localFile; public DownloadHandler(DB.Apk apk) { download = new Downloader(apk); @@ -589,9 +588,8 @@ public class AppDetails extends ListActivity { // installed (or maybe the user cancelled the install - doesn't // matter) from the SD card... if (!pref_cacheDownloaded) { - File file = new File(localFile); - Log.d("FDroid", "Cleaning up: " + file); - file.delete(); + Log.d("FDroid", "Cleaning up: " + localFile.getPath()); + localFile.delete(); localFile = null; } } diff --git a/src/org/fdroid/fdroid/AppListAdapter.java b/src/org/fdroid/fdroid/AppListAdapter.java index d57964bb7..efdb0d18a 100644 --- a/src/org/fdroid/fdroid/AppListAdapter.java +++ b/src/org/fdroid/fdroid/AppListAdapter.java @@ -82,11 +82,10 @@ public class AppListAdapter extends BaseAdapter { summary.setText(app.summary); ImageView icon = (ImageView) v.findViewById(R.id.icon); - String iconpath = new String(DB.getIconsPath() + app.icon); - File icn = new File(iconpath); + File icn = new File(DB.getIconsPath(), app.icon); if (icn.exists() && icn.length() > 0) { new Uri.Builder().build(); - icon.setImageURI(Uri.parse(iconpath)); + icon.setImageURI(Uri.parse(icn.getPath())); } else { icon.setImageResource(android.R.drawable.sym_def_app_icon); } diff --git a/src/org/fdroid/fdroid/DB.java b/src/org/fdroid/fdroid/DB.java index 061b5da8b..3f79348be 100644 --- a/src/org/fdroid/fdroid/DB.java +++ b/src/org/fdroid/fdroid/DB.java @@ -19,10 +19,10 @@ package org.fdroid.fdroid; +import java.io.File; import java.text.SimpleDateFormat; import java.util.Collections; import java.util.Date; -import java.util.Dictionary; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -42,6 +42,7 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.os.Build; +import android.os.Environment; import android.preference.PreferenceManager; import android.text.TextUtils.SimpleStringSplitter; import android.util.Log; @@ -419,8 +420,12 @@ public class DB { } - public static String getIconsPath() { - return "/sdcard/.fdroid/icons/"; + public static File getDataPath() { + return new File(Environment.getExternalStorageDirectory(), ".fdroid"); + } + + public static File getIconsPath() { + return new File(getDataPath(), "icons"); } private PackageManager mPm; diff --git a/src/org/fdroid/fdroid/Downloader.java b/src/org/fdroid/fdroid/Downloader.java index 0cdb3bbcb..27a4158a6 100644 --- a/src/org/fdroid/fdroid/Downloader.java +++ b/src/org/fdroid/fdroid/Downloader.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 Ciaran Gultnieks + * Copyright (C) 2010-2012 Ciaran Gultnieks * Copyright (C) 2011 Henrik Tunedal * * This program is free software; you can redistribute it and/or @@ -29,14 +29,17 @@ import java.net.URL; public class Downloader extends Thread { - private static final String LOCAL_PATH = "/sdcard/.fdroid"; - private DB.Apk curapk; private String filename; - private String localfile; + private File localfile; - public static enum Status { STARTING, RUNNING, ERROR, DONE, CANCELLED }; - public static enum Error { CORRUPT, UNKNOWN }; + public static enum Status { + STARTING, RUNNING, ERROR, DONE, CANCELLED + }; + + public static enum Error { + CORRUPT, UNKNOWN + }; private Status status = Status.STARTING; private Error error; @@ -58,6 +61,7 @@ public class Downloader extends Thread { public synchronized int getProgress() { return progress; } + public synchronized int getMax() { return max; } @@ -66,6 +70,7 @@ public class Downloader extends Thread { public synchronized Error getErrorType() { return error; } + public synchronized String getErrorMessage() { return errorMessage; } @@ -75,8 +80,8 @@ public class Downloader extends Thread { return filename; } - // Path to the downloaded APK - public synchronized String localFile() { + // The downloaded APK. Valid only when getStatus() has returned STATUS.DONE. + public File localFile() { return localfile; } @@ -87,125 +92,103 @@ public class Downloader extends Thread { public void run() { - // Download the apk file from the repository... - File f; - String apk_file = null; String apkname = curapk.apkName; - synchronized (this) { - localfile = new String(LOCAL_PATH + "/" + apkname); - } + localfile = new File(DB.getDataPath(), apkname); try { // See if we already have this apk cached... - f = new File(localfile); - if (f.exists()) { + if (localfile.exists()) { // We do - if its hash matches, we'll use it... - Hasher hash = new Hasher(curapk.hashType, f); + Hasher hash = new Hasher(curapk.hashType, localfile); if (hash.match(curapk.hash)) { Log.d("FDroid", "Using cached apk at " + localfile); synchronized (this) { - filename = apk_file = localfile; progress = 1; max = 1; - status = Status.RUNNING; + status = Status.DONE; + return; } } else { - Log.d("FDroid", "Not using cached apk at " - + localfile); - f.delete(); + Log.d("FDroid", "Not using cached apk at " + localfile); + localfile.delete(); } } - // If we haven't got the apk locally, we'll have to download - // it... - if (apk_file == null) { + // If we haven't got the apk locally, we'll have to download it... + String remotefile; + if (curapk.apkSource == null) { + remotefile = curapk.server + "/" + apkname.replace(" ", "%20"); + } else { + remotefile = curapk.apkSource; + } + Log.d("FDroid", "Downloading apk from " + remotefile); + synchronized (this) { + filename = remotefile; + progress = 0; + max = curapk.size; + status = Status.RUNNING; + } - String remotefile; - if (curapk.apkSource == null) { - remotefile = curapk.server + "/" - + apkname.replace(" ", "%20"); - } else { - remotefile = curapk.apkSource; - } - Log.d("FDroid", "Downloading apk from " + remotefile); - synchronized (this) { - filename = remotefile; - progress = 0; - max = curapk.size; - status = Status.RUNNING; - } + BufferedInputStream getit = new BufferedInputStream(new URL( + remotefile).openStream(), 8192); - BufferedInputStream getit = - new BufferedInputStream(new URL(remotefile).openStream(), - 8192); + FileOutputStream saveit = new FileOutputStream(localfile); + BufferedOutputStream bout = new BufferedOutputStream(saveit, 1024); + byte data[] = new byte[1024]; - FileOutputStream saveit = - new FileOutputStream(localfile); - BufferedOutputStream bout = - new BufferedOutputStream(saveit, 1024); - byte data[] = new byte[1024]; - - int totalRead = 0; - int bytesRead = getit.read(data, 0, 1024); - while (bytesRead != -1) { - if (isInterrupted()) { - Log.d("FDroid", "Download cancelled!"); - break; - } - bout.write(data, 0, bytesRead); - totalRead += bytesRead; - synchronized (this) { - progress = totalRead; - } - bytesRead = getit.read(data, 0, 1024); - } - bout.close(); - getit.close(); - saveit.close(); - f = new File(localfile); + int totalRead = 0; + int bytesRead = getit.read(data, 0, 1024); + while (bytesRead != -1) { if (isInterrupted()) { - f.delete(); - synchronized (this) { - status = Status.CANCELLED; - } - return; + Log.d("FDroid", "Download cancelled!"); + break; } - Hasher hash = new Hasher(curapk.hashType, f); - if (hash.match(curapk.hash)) { - apk_file = localfile; - } else { - synchronized (this) { - error = Error.CORRUPT; - errorMessage = null; - status = Status.ERROR; - } - Log.d("FDroid", "Downloaded file hash of " - + hash.getHash() + " did not match repo's " - + curapk.hash); + bout.write(data, 0, bytesRead); + totalRead += bytesRead; + synchronized (this) { + progress = totalRead; + } + bytesRead = getit.read(data, 0, 1024); + } + bout.close(); + getit.close(); + saveit.close(); + + if (isInterrupted()) { + localfile.delete(); + synchronized (this) { + status = Status.CANCELLED; + } + return; + } + Hasher hash = new Hasher(curapk.hashType, localfile); + if (!hash.match(curapk.hash)) { + synchronized (this) { + Log.d("FDroid", "Downloaded file hash of " + hash.getHash() + + " did not match repo's " + curapk.hash); // No point keeping a bad file, whether we're // caching or not. - f = new File(localfile); - f.delete(); + localfile.delete(); + error = Error.CORRUPT; + errorMessage = null; + status = Status.ERROR; + return; } } } catch (Exception e) { - Log.e("FDroid", "Download failed:\n" - + Log.getStackTraceString(e)); + Log.e("FDroid", "Download failed:\n" + Log.getStackTraceString(e)); synchronized (this) { + localfile.delete(); error = Error.UNKNOWN; errorMessage = e.toString(); status = Status.ERROR; + return; } - // Get rid of any partial download... - f = new File(localfile); - f.delete(); } - if (apk_file != null) { - synchronized (this) { - status = Status.DONE; - } - Log.d("FDroid", "Download finished: " + apk_file); + Log.d("FDroid", "Download finished: " + localfile); + synchronized (this) { + status = Status.DONE; } } } diff --git a/src/org/fdroid/fdroid/FDroid.java b/src/org/fdroid/fdroid/FDroid.java index 291017851..ea9ef8b9f 100644 --- a/src/org/fdroid/fdroid/FDroid.java +++ b/src/org/fdroid/fdroid/FDroid.java @@ -19,7 +19,6 @@ package org.fdroid.fdroid; -import java.io.File; import java.util.Calendar; import java.util.Date; import java.util.Vector; @@ -33,14 +32,12 @@ import android.app.TabActivity; import android.app.AlertDialog.Builder; import android.content.DialogInterface; import android.content.Intent; -import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.ResultReceiver; -import android.preference.PreferenceManager; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; @@ -60,8 +57,6 @@ import android.widget.TabHost.TabSpec; public class FDroid extends TabActivity implements OnItemClickListener, OnItemSelectedListener { - private String LOCAL_PATH = "/sdcard/.fdroid"; - private static final int REQUEST_APPDETAILS = 0; private static final int REQUEST_MANAGEREPOS = 1; private static final int REQUEST_PREFS = 2; @@ -109,14 +104,6 @@ public class FDroid extends TabActivity implements OnItemClickListener, setContentView(R.layout.fdroid); - File local_path = new File(LOCAL_PATH); - if (!local_path.exists()) - local_path.mkdir(); - - File icon_path = new File(DB.getIconsPath()); - if (!icon_path.exists()) - icon_path.mkdir(); - Spinner spinner = (Spinner) findViewById(R.id.category); categories = new ArrayAdapter(this, android.R.layout.simple_spinner_item, new Vector()); diff --git a/src/org/fdroid/fdroid/FDroidApp.java b/src/org/fdroid/fdroid/FDroidApp.java index ce4756900..dc8ed9629 100644 --- a/src/org/fdroid/fdroid/FDroidApp.java +++ b/src/org/fdroid/fdroid/FDroidApp.java @@ -18,10 +18,12 @@ package org.fdroid.fdroid; +import java.io.File; import java.util.Vector; import java.util.concurrent.Semaphore; import android.app.Application; +import android.util.Log; public class FDroidApp extends Application { @@ -29,8 +31,19 @@ public class FDroidApp extends Application { public void onCreate() { super.onCreate(); + File local_path = DB.getDataPath(); + Log.d("FDroid", "Data path is " + local_path.getPath()); + if (!local_path.exists()) + local_path.mkdir(); + + File icon_path = DB.getIconsPath(); + Log.d("FDroid", "Icon path is " + icon_path.getPath()); + if (!icon_path.exists()) + icon_path.mkdir(); + apps = null; DB.initDB(getApplicationContext()); + } // Global list of all known applications. diff --git a/src/org/fdroid/fdroid/RepoXMLHandler.java b/src/org/fdroid/fdroid/RepoXMLHandler.java index 10a717637..c772722ac 100644 --- a/src/org/fdroid/fdroid/RepoXMLHandler.java +++ b/src/org/fdroid/fdroid/RepoXMLHandler.java @@ -242,8 +242,7 @@ public class RepoXMLHandler extends DefaultHandler { private void getIcon(DB.App app) { try { - String destpath = DB.getIconsPath() + app.icon; - File f = new File(destpath); + File f = new File(DB.getIconsPath(), app.icon); if (f.exists()) return; @@ -252,7 +251,7 @@ public class RepoXMLHandler extends DefaultHandler { if (uc.getResponseCode() == 200) { BufferedInputStream getit = new BufferedInputStream( uc.getInputStream()); - FileOutputStream saveit = new FileOutputStream(destpath); + FileOutputStream saveit = new FileOutputStream(f); BufferedOutputStream bout = new BufferedOutputStream(saveit, 1024); byte data[] = new byte[1024]; @@ -296,8 +295,7 @@ public class RepoXMLHandler extends DefaultHandler { // APKs are merged into the existing one). // Returns null if successful, otherwise an error message to be displayed // to the user (if there is an interactive user!) - public static String doUpdate(Context ctx, DB.Repo repo, - Vector apps) { + public static String doUpdate(Context ctx, DB.Repo repo, Vector apps) { try { if (repo.pubkey != null) { @@ -394,8 +392,8 @@ public class RepoXMLHandler extends DefaultHandler { } } catch (SSLHandshakeException sslex) { - Log.e("FDroid", "SSLHandShakeException updating from " + repo.address + ":\n" - + Log.getStackTraceString(sslex)); + Log.e("FDroid", "SSLHandShakeException updating from " + + repo.address + ":\n" + Log.getStackTraceString(sslex)); return "A problem occurred while establishing an SSL connection. If this problem persists, AND you have a very old device, you could try using http instead of https for the repo URL."; } catch (Exception e) { Log.e("FDroid", "Exception updating from " + repo.address + ":\n"