Added preferences screen and implemented (optional) caching

This commit is contained in:
Ciaran Gultnieks 2010-11-07 23:06:46 +00:00
parent 37182c04b1
commit 53a9e0e796
7 changed files with 224 additions and 99 deletions

View File

@ -14,6 +14,7 @@
<activity android:name="ManageRepo" />
<activity android:name="Settings" />
<activity android:name="AppDetails" />
<activity android:name="Preferences" />
</application>
<uses-permission android:name="android.permission.INTERNET" />

19
res/values/array.xml Normal file
View File

@ -0,0 +1,19 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string-array name="updateIntervalNames">
<item>Never</item>
<item>Hourly</item>
<item>Every 4 Hours</item>
<item>Every 12 Hours</item>
<item>Daily</item>
</string-array>
<string-array name="updateIntervalValues">
<item>0</item>
<item>1</item>
<item>4</item>
<item>12</item>
<item>24</item>
</string-array>
</resources>

View File

@ -2,13 +2,17 @@
<resources>
<string name="app_name">FDroid</string>
<string name="about_title">About FDroid</string>
<string name="about_desc">Based on Aptoide.\nReleased under the GNU GPL v2 license.</string>
<string name="about_desc">Based on Aptoide.\nReleased under the GNU GPL v2
license.</string>
<string name="about_site">Home: </string>
<string name="about_mail">e-Mail: </string>
<string name="about_website">Web Site</string>
<string name="no_repo">You have no repositories configured!\n\nA repository is a source of applications. To add one, press the MENU button now and enter the URL.\n\nA repository URL looks something like this: http://f-droid.org/repo</string>
<string name="no_repo">You have no repositories configured!\n\nA
repository is a source of applications. To add one, press the MENU
button now and enter the URL.\n\nA repository URL looks something like
this: http://f-droid.org/repo</string>
<string name="not_inst">Not Installed</string>
@ -60,20 +64,19 @@
<string name="uninstall">Uninstall </string>
<string name="update">Update!</string>
<string name="update_alrt">There updates available for some installed applications.\nDo you wish to see them?</string>
<string name="repo_alrt">The list of repositories in use has been changed.\nDo you wish to update them?</string>
<string name="update_alrt">There updates available for some installed
applications.\nDo you wish to see them?</string>
<string name="repo_alrt">The list of repositories in use has been
changed.\nDo you wish to update them?</string>
<string name="error_download_alrt">Could not connect to server or apk file is corrupt!</string>
<string name="error_download_alrt">Could not connect to server or apk file is corrupt!
</string>
<string name="download_alrt">Getting application from:\n </string>
<string name="menu_update_repo">Update</string>
<string name="menu_manage">Manage Repos</string>
<string name="menu_preferences">Preferences</string>
<string name="menu_about">About</string>
<string name="menu_add_repo">New Repository</string>
<string name="menu_rem_repo">Remove Repository</string>
@ -91,4 +94,6 @@
<string name="details_notinstalled">Not installed (%d available)</string>
<string name="inst">Installed</string>
<string name="corrupt_download">Downloaded file is corrupt</string>
</resources>

17
res/xml/preferences.xml Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="Storage">
<CheckBoxPreference android:title="Cache downloaded apps"
android:defaultValue="false" android:summary="Keep downloaded apk files on SD card"
android:key="cacheDownloaded" />
</PreferenceCategory>
<PreferenceCategory android:title="Updates">
<ListPreference android:title="Automatic repo scan"
android:summary="Update apps list from repositories automatically"
android:key="updateInterval" android:defaultValue="0"
android:entries="@array/updateIntervalNames" android:entryValues="@array/updateIntervalValues" />
<CheckBoxPreference android:title="Notify"
android:defaultValue="false" android:summary="Notify when new updates are available"
android:key="updateNotify" />
</PreferenceCategory>
</PreferenceScreen>

View File

@ -36,6 +36,7 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
@ -46,6 +47,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@ -163,6 +165,18 @@ public class AppDetails extends ListActivity {
}
private boolean pref_cacheDownloaded;
@Override
protected void onStart() {
super.onStart();
// Get the preferences we're going to use in this Activity...
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(getBaseContext());
pref_cacheDownloaded = prefs.getBoolean("cacheDownloaded", true);
}
// Reset the display and list contents. Used when entering the activity, and
// also when something has been installed/uninstalled. In the latter case,
// 'update' is true to make the installed status get refreshed.
@ -347,14 +361,42 @@ public class AppDetails extends ListActivity {
public void run() {
// Download the apk file from the repository...
File f;
String apk_file = null;
try {
String apkname = curapk.apkName;
String localfile = new String(LOCAL_PATH + "/" + apkname);
try {
// See if we already have this apk cached...
f = new File(localfile);
if (f.exists()) {
// We do - if its hash matches, we'll use it...
Md5Handler hash = new Md5Handler();
String calcedhash = hash.md5Calc(f);
if (curapk.hash.equalsIgnoreCase(calcedhash)) {
apk_file = localfile;
Log.d("FDroid", "Using cached apk at " + localfile);
Message msg = new Message();
msg.arg1 = 0;
msg.arg2 = 1;
msg.obj = new String(localfile);
download_handler.sendMessage(msg);
msg=new Message();
msg.arg1 = 1;
download_handler.sendMessage(msg);
} else {
Log.d("FDroid", "Not using cached apk at "
+ localfile);
f.delete();
}
}
// If we haven't got the apk locally, we'll have to download
// it...
if (apk_file == null) {
String remotefile = curapk.server + "/"
+ apkname.replace(" ", "%20");
Log.d("FDroid", "Downloading apk from " + remotefile);
Message msg = new Message();
@ -366,7 +408,8 @@ public class AppDetails extends ListActivity {
BufferedInputStream getit = new BufferedInputStream(
new URL(remotefile).openStream(), 8192);
FileOutputStream saveit = new FileOutputStream(localfile);
FileOutputStream saveit = new FileOutputStream(
localfile);
BufferedOutputStream bout = new BufferedOutputStream(
saveit, 1024);
byte data[] = new byte[1024];
@ -384,7 +427,7 @@ public class AppDetails extends ListActivity {
bout.close();
getit.close();
saveit.close();
File f = new File(localfile);
f = new File(localfile);
Md5Handler hash = new Md5Handler();
String calcedhash = hash.md5Calc(f);
if (curapk.hash.equalsIgnoreCase(calcedhash)) {
@ -393,15 +436,24 @@ public class AppDetails extends ListActivity {
msg = new Message();
msg.obj = getString(R.string.corrupt_download);
download_error_handler.sendMessage(msg);
Log.d("FDroid", "Downloaded file hash of " + calcedhash
+ " did not match repo's " + curapk.hash);
Log.d("FDroid", "Downloaded file hash of "
+ calcedhash + " 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();
}
}
} catch (Exception e) {
Log.d("FDroid", "Download failed - " + e.getMessage());
Message msg = new Message();
msg.obj = e.getMessage();
download_error_handler.sendMessage(msg);
// Get rid of any partial download...
f = new File(localfile);
f.delete();
}
if (apk_file != null) {
@ -445,6 +497,7 @@ public class AppDetails extends ListActivity {
public void handleMessage(Message msg) {
String apk_file = (String) msg.obj;
installApk(apk_file);
pd.dismiss();
}
};
@ -462,21 +515,29 @@ public class AppDetails extends ListActivity {
startActivityForResult(intent, REQUEST_UNINSTALL);
}
private void installApk(String id) {
private void installApk(String file) {
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + id),
intent.setDataAndType(Uri.parse("file://" + file),
"application/vnd.android.package-archive");
Message msg = new Message();
msg.arg1 = 1;
download_handler.sendMessage(msg);
startActivityForResult(intent, REQUEST_INSTALL);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode==REQUEST_INSTALL) {
// If we're not meant to be caching, delete the apk file we just
// installed (or maybe the user cancelled the install - doesn't matter)
// from the SD card...
if (!pref_cacheDownloaded) {
String apkname = curapk.apkName;
String apk_file = new String(LOCAL_PATH + "/" + apkname);
File file = new File(apk_file);
file.delete();
}
}
reset(true);
}

View File

@ -152,7 +152,8 @@ public class FDroid extends TabActivity implements OnItemClickListener {
private static final int UPDATE_REPO = Menu.FIRST;
private static final int MANAGE_REPO = Menu.FIRST + 1;
private static final int RESET_DB = Menu.FIRST + 2;
private static final int ABOUT = Menu.FIRST + 3;
private static final int PREFERENCES = Menu.FIRST + 3;
private static final int ABOUT = Menu.FIRST + 4;
private DB db = null;
@ -222,7 +223,9 @@ public class FDroid extends TabActivity implements OnItemClickListener {
android.R.drawable.ic_menu_agenda);
menu.add(Menu.NONE, RESET_DB, 3, "Reset DB").setIcon(
android.R.drawable.ic_menu_revert);
menu.add(Menu.NONE, ABOUT, 4, R.string.menu_about).setIcon(
menu.add(Menu.NONE, PREFERENCES, 4, R.string.menu_preferences).setIcon(
android.R.drawable.ic_menu_preferences);
menu.add(Menu.NONE, ABOUT, 5, R.string.menu_about).setIcon(
android.R.drawable.ic_menu_help);
return true;
}
@ -246,6 +249,11 @@ public class FDroid extends TabActivity implements OnItemClickListener {
populateLists(true);
return true;
case PREFERENCES:
Intent prefs = new Intent(getBaseContext(), Preferences.class);
startActivity(prefs);
return true;
case ABOUT:
LayoutInflater li = LayoutInflater.from(this);
View view = li.inflate(R.layout.about, null);

View File

@ -0,0 +1,14 @@
package org.fdroid.fdroid;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class Preferences extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}