Merge branch 'master' into experimental/refactor-update
This commit is contained in:
commit
b863802479
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,11 +1,9 @@
|
||||
/local.properties
|
||||
/build.properties
|
||||
.classpath
|
||||
/bin/
|
||||
/gen/
|
||||
/build
|
||||
/.gradle
|
||||
/proguard.cfg
|
||||
/build.xml
|
||||
*~
|
||||
.idea
|
||||
|
@ -18,6 +18,14 @@
|
||||
android:layout_marginRight="4dp"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="false"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/header"
|
||||
android:layout_width="fill_parent"
|
||||
@ -25,41 +33,48 @@
|
||||
android:layout_marginBottom="4dp"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:singleLine="false"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_below="@id/title"
|
||||
android:layout_marginRight="6dp"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:padding="4dp"
|
||||
android:scaleType="fitCenter" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/license"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/title"
|
||||
android:layout_toRightOf="@id/icon"
|
||||
android:textSize="13sp" />
|
||||
<RelativeLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="4dp"
|
||||
android:layout_toRightOf="@id/icon"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/license"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:textSize="13sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/categories"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/license"
|
||||
android:layout_above="@id/status"
|
||||
android:layout_centerVertical="true"
|
||||
android:textSize="13sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:textSize="13sp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/license"
|
||||
android:layout_toRightOf="@id/icon"
|
||||
android:textSize="13sp" />
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<ListView
|
||||
|
@ -15,7 +15,7 @@
|
||||
android:textSize="18sp" />
|
||||
|
||||
<TextView android:id="@+id/status"
|
||||
android:textSize="12sp"
|
||||
android:textSize="13sp"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
android:layout_below="@id/version"
|
||||
@ -23,28 +23,36 @@
|
||||
android:layout_width="wrap_content" />
|
||||
|
||||
<TextView android:id="@+id/added"
|
||||
android:textSize="12sp"
|
||||
android:textSize="13sp"
|
||||
android:layout_below="@id/status"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content" />
|
||||
|
||||
<TextView android:id="@+id/buildtype"
|
||||
android:textSize="12sp"
|
||||
android:textSize="13sp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_marginBottom="4sp" />
|
||||
|
||||
<TextView android:id="@+id/size"
|
||||
android:textSize="12sp"
|
||||
android:textSize="13sp"
|
||||
android:layout_below="@id/buildtype"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_marginBottom="4sp" />
|
||||
|
||||
<TextView android:id="@+id/api"
|
||||
android:textSize="13sp"
|
||||
android:layout_below="@id/buildtype"
|
||||
android:layout_toLeftOf="@id/size"
|
||||
android:layout_marginRight="16sp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content" />
|
||||
|
||||
<TextView android:id="@+id/nativecode"
|
||||
android:textSize="12sp"
|
||||
android:textSize="13sp"
|
||||
android:layout_below="@id/size"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -22,9 +22,8 @@
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_height="56dp"
|
||||
android:padding="6dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
@ -33,9 +32,9 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:paddingTop="2sp"
|
||||
android:paddingBottom="2sp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:paddingTop="3sp"
|
||||
android:paddingBottom="3sp"
|
||||
android:layout_marginLeft="8sp"
|
||||
android:textSize="13sp" />
|
||||
|
||||
<TextView
|
||||
@ -44,7 +43,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginLeft="8sp"
|
||||
android:textSize="13sp" />
|
||||
|
||||
<TextView
|
||||
|
@ -27,11 +27,11 @@
|
||||
<TextView android:id="@+id/status"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:paddingTop="2sp"
|
||||
android:paddingBottom="2sp"
|
||||
android:paddingTop="3sp"
|
||||
android:paddingBottom="3sp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginLeft="10sp"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentRight="true" />
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
android:ellipsize="end"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginLeft="10sp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentRight="true" />
|
||||
|
||||
|
@ -163,5 +163,6 @@
|
||||
<string name="compactlayout_on">Show icons at a smaller size</string>
|
||||
<string name="compactlayout_off">Show icons at regular size</string>
|
||||
<string name="theme">Theme</string>
|
||||
<string name="minsdk_or_later">Android %s or later</string>
|
||||
|
||||
</resources>
|
||||
|
@ -76,6 +76,9 @@ import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
|
||||
import com.nostra13.universalimageloader.utils.StorageUtils;
|
||||
|
||||
import android.os.Environment;
|
||||
|
||||
public class AppDetails extends ListActivity {
|
||||
|
||||
@ -140,10 +143,11 @@ public class AppDetails extends ListActivity {
|
||||
|
||||
tv = (TextView) v.findViewById(R.id.status);
|
||||
if (apk.vercode == app.installedVerCode
|
||||
&& apk.sig.equals(mInstalledSigID))
|
||||
&& apk.sig.equals(mInstalledSigID)) {
|
||||
tv.setText(getString(R.string.inst));
|
||||
else
|
||||
} else {
|
||||
tv.setText(getString(R.string.not_inst));
|
||||
}
|
||||
tv.setEnabled(apk.compatible);
|
||||
|
||||
tv = (TextView) v.findViewById(R.id.size);
|
||||
@ -153,6 +157,16 @@ public class AppDetails extends ListActivity {
|
||||
tv.setText(Utils.getFriendlySize(apk.detail_size));
|
||||
tv.setEnabled(apk.compatible);
|
||||
}
|
||||
|
||||
tv = (TextView) v.findViewById(R.id.api);
|
||||
if (apk.minSdkVersion == 0) {
|
||||
tv.setText("");
|
||||
} else {
|
||||
tv.setText(getString(R.string.minsdk_or_later,
|
||||
Utils.getAndroidVersionName(apk.minSdkVersion)));
|
||||
tv.setEnabled(apk.compatible);
|
||||
}
|
||||
|
||||
tv = (TextView) v.findViewById(R.id.buildtype);
|
||||
if (apk.srcname != null) {
|
||||
tv.setText("source");
|
||||
@ -160,6 +174,7 @@ public class AppDetails extends ListActivity {
|
||||
tv.setText("bin");
|
||||
}
|
||||
tv.setEnabled(apk.compatible);
|
||||
|
||||
tv = (TextView) v.findViewById(R.id.added);
|
||||
if (apk.added != null) {
|
||||
tv.setVisibility(View.VISIBLE);
|
||||
@ -168,6 +183,7 @@ public class AppDetails extends ListActivity {
|
||||
} else {
|
||||
tv.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
tv = (TextView) v.findViewById(R.id.nativecode);
|
||||
if (pref_expert && apk.nativecode != null) {
|
||||
tv.setVisibility(View.VISIBLE);
|
||||
@ -457,26 +473,6 @@ public class AppDetails extends ListActivity {
|
||||
|
||||
tv = (TextView) infoView.findViewById(R.id.description);
|
||||
|
||||
/*
|
||||
The following is a quick solution to enable both text selection and
|
||||
links. Causes glitches and crashes:
|
||||
java.lang.IndexOutOfBoundsException: setSpan (-1 ... -1) starts before 0
|
||||
|
||||
class CustomMovementMethod extends LinkMovementMethod {
|
||||
@Override
|
||||
public boolean canSelectArbitrarily () {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (Utils.hasApi(11)) {
|
||||
tv.setTextIsSelectable(true);
|
||||
tv.setMovementMethod(new CustomMovementMethod());
|
||||
} else {
|
||||
tv.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
*/
|
||||
|
||||
tv.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
|
||||
// Need this to add the unimplemented support for ordered and unordered
|
||||
@ -848,8 +844,8 @@ public class AppDetails extends ListActivity {
|
||||
public void onClick(DialogInterface dialog,
|
||||
int whichButton) {
|
||||
downloadHandler = new DownloadHandler(app.curApk,
|
||||
repoaddress, DB
|
||||
.getDataPath(getBaseContext()));
|
||||
repoaddress, Utils
|
||||
.getApkCacheDir(getBaseContext()));
|
||||
}
|
||||
});
|
||||
ask_alrt.setNegativeButton(getString(R.string.no),
|
||||
@ -879,7 +875,7 @@ public class AppDetails extends ListActivity {
|
||||
return;
|
||||
}
|
||||
downloadHandler = new DownloadHandler(app.curApk, repoaddress,
|
||||
DB.getDataPath(this));
|
||||
Utils.getApkCacheDir(getBaseContext()));
|
||||
}
|
||||
|
||||
private void removeApk(String id) {
|
||||
|
@ -105,7 +105,7 @@ public class DB {
|
||||
+ "lastUpdated string," + "compatible int not null,"
|
||||
+ "ignoreAllUpdates int not null,"
|
||||
+ "ignoreThisUpdate int not null,"
|
||||
+ "provides string," + "primary key(id));";
|
||||
+ "primary key(id));";
|
||||
|
||||
public static class App implements Comparable<App> {
|
||||
|
||||
@ -123,7 +123,6 @@ public class DB {
|
||||
detail_dogecoinAddr = null;
|
||||
detail_webURL = null;
|
||||
categories = null;
|
||||
provides = null;
|
||||
antiFeatures = null;
|
||||
requirements = null;
|
||||
hasUpdates = false;
|
||||
@ -198,9 +197,6 @@ public class DB {
|
||||
public int installedVerCode;
|
||||
public boolean userInstalled;
|
||||
|
||||
// List of app IDs that this app provides or null if there aren't any.
|
||||
public CommaSeparatedList provides;
|
||||
|
||||
// List of categories (as defined in the metadata
|
||||
// documentation) or null if there aren't any.
|
||||
public CommaSeparatedList categories;
|
||||
@ -374,10 +370,11 @@ public class DB {
|
||||
}
|
||||
}
|
||||
|
||||
cpuAbis = new ArrayList<String>();
|
||||
if (hasApi(8))
|
||||
cpuAbis.add(android.os.Build.CPU_ABI2);
|
||||
cpuAbis = new ArrayList<String>(2);
|
||||
cpuAbis.add(android.os.Build.CPU_ABI);
|
||||
if (hasApi(8)) {
|
||||
cpuAbis.add(android.os.Build.CPU_ABI2);
|
||||
}
|
||||
|
||||
Log.d("FDroid", logMsg.toString());
|
||||
}
|
||||
@ -410,8 +407,7 @@ public class DB {
|
||||
}
|
||||
if (!compatibleApi(apk.nativecode)) {
|
||||
Log.d("FDroid", apk.id + " vercode " + apk.vercode
|
||||
+ " makes use of incompatible native code: "
|
||||
+ CommaSeparatedList.str(apk.nativecode)
|
||||
+ " only supports " + CommaSeparatedList.str(apk.nativecode)
|
||||
+ " while your architecture is " + cpuAbis.get(0));
|
||||
return false;
|
||||
}
|
||||
@ -434,6 +430,7 @@ public class DB {
|
||||
public String address;
|
||||
public String name;
|
||||
public String description;
|
||||
public int version; // index version, i.e. what fdroidserver built it - 0 if not specified
|
||||
public boolean inuse;
|
||||
public int priority;
|
||||
public String pubkey; // null for an unsigned repo
|
||||
@ -442,7 +439,7 @@ public class DB {
|
||||
public String lastetag; // last etag we updated from, null forces update
|
||||
}
|
||||
|
||||
private final int DBVersion = 32;
|
||||
private final int DBVersion = 34;
|
||||
|
||||
private static void createAppApk(SQLiteDatabase db) {
|
||||
db.execSQL(CREATE_TABLE_APP);
|
||||
@ -508,6 +505,7 @@ public class DB {
|
||||
mContext.getString(R.string.default_repo_name));
|
||||
values.put("description",
|
||||
mContext.getString(R.string.default_repo_description));
|
||||
values.put("version", 0);
|
||||
String pubkey = mContext.getString(R.string.default_repo_pubkey);
|
||||
String fingerprint = DB.calcFingerprint(pubkey);
|
||||
values.put("pubkey", pubkey);
|
||||
@ -525,9 +523,11 @@ public class DB {
|
||||
mContext.getString(R.string.default_repo_name2));
|
||||
values.put("description",
|
||||
mContext.getString(R.string.default_repo_description2));
|
||||
values.put("version", 0);
|
||||
// default #2 is /archive which has the same key as /repo
|
||||
values.put("pubkey", pubkey);
|
||||
values.put("fingerprint", fingerprint);
|
||||
values.put("maxage", 0);
|
||||
values.put("inuse", 0);
|
||||
values.put("priority", 20);
|
||||
values.put("lastetag", (String) null);
|
||||
@ -615,18 +615,14 @@ public class DB {
|
||||
if (oldVersion < 30) {
|
||||
db.execSQL("alter table " + TABLE_REPO + " add column maxage integer not null default 0");
|
||||
}
|
||||
|
||||
if (oldVersion < 34) {
|
||||
db.execSQL("alter table " + TABLE_REPO + " add column version integer not null default 0");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the local storage (cache) path. This will also create it if
|
||||
* it doesn't exist. It can return null if it's currently unavailable.
|
||||
*/
|
||||
public static File getDataPath(Context ctx) {
|
||||
return ContextCompat.create(ctx).getExternalCacheDir();
|
||||
}
|
||||
|
||||
private Context mContext;
|
||||
private Apk.CompatibilityChecker compatChecker = null;
|
||||
|
||||
@ -803,16 +799,23 @@ public class DB {
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, App> apps = new HashMap<String, App>();
|
||||
Cursor c = null;
|
||||
// Start the map at the actual number of apps we will have
|
||||
Cursor c = db.rawQuery("select count(*) from "+TABLE_APP, null);
|
||||
c.moveToFirst();
|
||||
int count = c.getInt(0);
|
||||
c.close();
|
||||
c = null;
|
||||
|
||||
Log.d("FDroid", "Will be fetching " + count + " apps, and this took us ");
|
||||
|
||||
Map<String, App> apps = new HashMap<String, App>(count);
|
||||
long startTime = System.currentTimeMillis();
|
||||
try {
|
||||
|
||||
String cols[] = new String[] { "antiFeatures", "requirements",
|
||||
"categories", "id", "name", "summary", "icon", "license",
|
||||
"curVersion", "curVercode", "added", "lastUpdated",
|
||||
"compatible", "ignoreAllUpdates", "ignoreThisUpdate",
|
||||
"provides" };
|
||||
"compatible", "ignoreAllUpdates", "ignoreThisUpdate" };
|
||||
c = db.query(TABLE_APP, cols, null, null, null, null, null);
|
||||
c.moveToFirst();
|
||||
while (!c.isAfterLast()) {
|
||||
@ -838,7 +841,6 @@ public class DB {
|
||||
app.compatible = c.getInt(12) == 1;
|
||||
app.ignoreAllUpdates = c.getInt(13) == 1;
|
||||
app.ignoreThisUpdate = c.getInt(14);
|
||||
app.provides = DB.CommaSeparatedList.make(c.getString(15));
|
||||
app.hasUpdates = false;
|
||||
|
||||
if (getinstalledinfo && systemApks.containsKey(app.id)) {
|
||||
@ -858,18 +860,13 @@ public class DB {
|
||||
}
|
||||
|
||||
apps.put(app.id, app);
|
||||
if (app.provides != null) {
|
||||
for (String id : app.provides) {
|
||||
apps.put(id, app);
|
||||
}
|
||||
}
|
||||
|
||||
c.moveToNext();
|
||||
}
|
||||
c.close();
|
||||
c = null;
|
||||
|
||||
Log.d("FDroid", "Read app data from database " + " (took "
|
||||
Log.d("FDroid", "Read app data from database (took "
|
||||
+ (System.currentTimeMillis() - startTime) + " ms)");
|
||||
|
||||
List<Repo> repos = getRepos();
|
||||
@ -928,7 +925,7 @@ public class DB {
|
||||
c.close();
|
||||
}
|
||||
|
||||
Log.d("FDroid", "Read app and apk data from database " + " (took "
|
||||
Log.d("FDroid", "Read app and apk data from database (took "
|
||||
+ (System.currentTimeMillis() - startTime) + " ms)");
|
||||
}
|
||||
|
||||
@ -1020,7 +1017,7 @@ public class DB {
|
||||
try {
|
||||
String filter = "%" + query + "%";
|
||||
c = db.query(TABLE_APP, new String[] { "id" },
|
||||
"id like ? or provides like ? or name like ? or summary like ? or description like ?",
|
||||
"id like ? or name like ? or summary like ? or description like ?",
|
||||
new String[] { filter, filter, filter, filter }, null, null, null);
|
||||
c.moveToFirst();
|
||||
while (!c.isAfterLast()) {
|
||||
@ -1291,8 +1288,8 @@ public class DB {
|
||||
Cursor c = null;
|
||||
try {
|
||||
c = db.query(TABLE_REPO, new String[] { "address", "name",
|
||||
"description", "inuse", "priority", "pubkey", "fingerprint",
|
||||
"maxage", "lastetag" },
|
||||
"description", "version", "inuse", "priority", "pubkey",
|
||||
"fingerprint", "maxage", "lastetag" },
|
||||
"id = ?", new String[] { Integer.toString(id) }, null, null, null);
|
||||
if (!c.moveToFirst())
|
||||
return null;
|
||||
@ -1301,12 +1298,13 @@ public class DB {
|
||||
repo.address = c.getString(0);
|
||||
repo.name = c.getString(1);
|
||||
repo.description = c.getString(2);
|
||||
repo.inuse = (c.getInt(3) == 1);
|
||||
repo.priority = c.getInt(4);
|
||||
repo.pubkey = c.getString(5);
|
||||
repo.fingerprint = c.getString(6);
|
||||
repo.maxage = c.getInt(7);
|
||||
repo.lastetag = c.getString(8);
|
||||
repo.version = c.getInt(3);
|
||||
repo.inuse = (c.getInt(4) == 1);
|
||||
repo.priority = c.getInt(5);
|
||||
repo.pubkey = c.getString(6);
|
||||
repo.fingerprint = c.getString(7);
|
||||
repo.maxage = c.getInt(8);
|
||||
repo.lastetag = c.getString(9);
|
||||
return repo;
|
||||
} finally {
|
||||
if (c != null)
|
||||
@ -1320,8 +1318,8 @@ public class DB {
|
||||
Cursor c = null;
|
||||
try {
|
||||
c = db.query(TABLE_REPO, new String[] { "id", "address", "name",
|
||||
"description", "inuse", "priority", "pubkey", "fingerprint",
|
||||
"maxage", "lastetag" },
|
||||
"description", "version", "inuse", "priority", "pubkey",
|
||||
"fingerprint", "maxage", "lastetag" },
|
||||
null, null, null, null, "priority");
|
||||
c.moveToFirst();
|
||||
while (!c.isAfterLast()) {
|
||||
@ -1330,12 +1328,13 @@ public class DB {
|
||||
repo.address = c.getString(1);
|
||||
repo.name = c.getString(2);
|
||||
repo.description = c.getString(3);
|
||||
repo.inuse = (c.getInt(4) == 1);
|
||||
repo.priority = c.getInt(5);
|
||||
repo.pubkey = c.getString(6);
|
||||
repo.fingerprint = c.getString(7);
|
||||
repo.maxage = c.getInt(8);
|
||||
repo.lastetag = c.getString(9);
|
||||
repo.version = c.getInt(4);
|
||||
repo.inuse = (c.getInt(5) == 1);
|
||||
repo.priority = c.getInt(6);
|
||||
repo.pubkey = c.getString(7);
|
||||
repo.fingerprint = c.getString(8);
|
||||
repo.maxage = c.getInt(9);
|
||||
repo.lastetag = c.getString(10);
|
||||
repos.add(repo);
|
||||
c.moveToNext();
|
||||
}
|
||||
@ -1365,6 +1364,7 @@ public class DB {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("name", repo.name);
|
||||
values.put("description", repo.description);
|
||||
values.put("version", repo.version);
|
||||
values.put("inuse", repo.inuse);
|
||||
values.put("priority", repo.priority);
|
||||
values.put("pubkey", repo.pubkey);
|
||||
@ -1388,12 +1388,14 @@ public class DB {
|
||||
}
|
||||
|
||||
public void addRepo(String address, String name, String description,
|
||||
int priority, String pubkey, String fingerprint, int maxage, boolean inuse)
|
||||
int version, int priority, String pubkey, String fingerprint,
|
||||
int maxage, boolean inuse)
|
||||
throws SecurityException {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put("address", address);
|
||||
values.put("name", name);
|
||||
values.put("description", description);
|
||||
values.put("version", version);
|
||||
values.put("inuse", inuse ? 1 : 0);
|
||||
values.put("priority", priority);
|
||||
values.put("pubkey", pubkey);
|
||||
|
@ -132,8 +132,11 @@ public class FDroid extends FragmentActivity {
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
|
||||
super.onCreateOptionsMenu(menu);
|
||||
menu.add(Menu.NONE, UPDATE_REPO, 1, R.string.menu_update_repo).setIcon(
|
||||
MenuItem update = menu.add(Menu.NONE, UPDATE_REPO, 1, R.string.menu_update_repo).setIcon(
|
||||
android.R.drawable.ic_menu_rotate);
|
||||
MenuItemCompat.setShowAsAction(update,
|
||||
MenuItemCompat.SHOW_AS_ACTION_ALWAYS |
|
||||
MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
|
||||
menu.add(Menu.NONE, MANAGE_REPO, 2, R.string.menu_manage).setIcon(
|
||||
android.R.drawable.ic_menu_agenda);
|
||||
MenuItem search = menu.add(Menu.NONE, SEARCH, 3, R.string.menu_search).setIcon(
|
||||
|
@ -31,11 +31,13 @@ import android.util.Log;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import com.nostra13.universalimageloader.utils.StorageUtils;
|
||||
import org.fdroid.fdroid.Utils;
|
||||
|
||||
import com.nostra13.universalimageloader.cache.disc.impl.LimitedAgeDiscCache;
|
||||
import com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
|
||||
import com.nostra13.universalimageloader.utils.StorageUtils;
|
||||
|
||||
public class FDroidApp extends Application {
|
||||
|
||||
@ -78,14 +80,14 @@ public class FDroidApp extends Application {
|
||||
curTheme = Theme.valueOf(prefs.getString("theme", "dark"));
|
||||
if (!prefs.getBoolean("cacheDownloaded", false)) {
|
||||
|
||||
File local_path = DB.getDataPath(this);
|
||||
File local_path = Utils.getApkCacheDir(this);
|
||||
// Things can be null if the SD card is not ready - we'll just
|
||||
// ignore that and do it next time.
|
||||
if(local_path != null) {
|
||||
if (local_path != null) {
|
||||
File[] files = local_path.listFiles();
|
||||
if(files != null) {
|
||||
for(File f : files) {
|
||||
if(f.getName().endsWith(".apk")) {
|
||||
if (files != null) {
|
||||
for (File f : files) {
|
||||
if (f.getName().endsWith(".apk")) {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
@ -101,7 +103,8 @@ public class FDroidApp extends Application {
|
||||
|
||||
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(ctx)
|
||||
.discCache(new LimitedAgeDiscCache(
|
||||
new File(StorageUtils.getCacheDirectory(ctx), "icons"),
|
||||
new File(StorageUtils.getCacheDirectory(ctx, true),
|
||||
"icons"),
|
||||
new FileNameGenerator() {
|
||||
@Override
|
||||
public String generate(String imageUri) {
|
||||
|
@ -218,7 +218,7 @@ public class ManageRepo extends ListActivity {
|
||||
protected void addRepo(String repoUri, String fingerprint) {
|
||||
try {
|
||||
DB db = DB.getDB();
|
||||
db.addRepo(repoUri, null, null, 10, null, fingerprint, 0, true);
|
||||
db.addRepo(repoUri, null, null, 0, 10, null, fingerprint, 0, true);
|
||||
} finally {
|
||||
DB.releaseDB();
|
||||
}
|
||||
|
@ -89,8 +89,9 @@ public class RepoXMLHandler extends DefaultHandler {
|
||||
private DB.Apk curapk = null;
|
||||
private StringBuilder curchars = new StringBuilder();
|
||||
|
||||
// After processing the XML, this will be null if the index didn't specify
|
||||
// a maximum age - otherwise it will be the value specified.
|
||||
// After processing the XML, these will be null if the index didn't specify
|
||||
// them - otherwise it will be the value specified.
|
||||
private String version;
|
||||
private String maxage;
|
||||
|
||||
// After processing the XML, this will be null if the index specified a
|
||||
@ -278,8 +279,6 @@ public class RepoXMLHandler extends DefaultHandler {
|
||||
} catch (NumberFormatException ex) {
|
||||
curapp.curVercode = -1;
|
||||
}
|
||||
} else if (curel.equals("provides")) {
|
||||
curapp.provides = DB.CommaSeparatedList.make(str);
|
||||
} else if (curel.equals("categories")) {
|
||||
curapp.categories = DB.CommaSeparatedList.make(str);
|
||||
} else if (curel.equals("antifeatures")) {
|
||||
@ -294,10 +293,12 @@ public class RepoXMLHandler extends DefaultHandler {
|
||||
public void startElement(String uri, String localName, String qName,
|
||||
Attributes attributes) throws SAXException {
|
||||
super.startElement(uri, localName, qName, attributes);
|
||||
|
||||
if (localName.equals("repo")) {
|
||||
String pk = attributes.getValue("", "pubkey");
|
||||
if (pk != null)
|
||||
pubkey = pk;
|
||||
version = attributes.getValue("", "version");
|
||||
maxage = attributes.getValue("", "maxage");
|
||||
String nm = attributes.getValue("", "name");
|
||||
if (nm != null)
|
||||
@ -305,6 +306,7 @@ public class RepoXMLHandler extends DefaultHandler {
|
||||
String dc = attributes.getValue("", "description");
|
||||
if (dc != null)
|
||||
description = dc;
|
||||
|
||||
} else if (localName.equals("application") && curapp == null) {
|
||||
curapp = new DB.App();
|
||||
curapp.detail_Populated = true;
|
||||
@ -315,11 +317,13 @@ public class RepoXMLHandler extends DefaultHandler {
|
||||
new ProgressListener.Event(
|
||||
RepoUpdater.PROGRESS_TYPE_PROCESS_XML, progressCounter,
|
||||
totalAppCount, progressData));
|
||||
|
||||
} else if (localName.equals("package") && curapp != null && curapk == null) {
|
||||
curapk = new DB.Apk();
|
||||
curapk.id = curapp.id;
|
||||
curapk.repo = repo.id;
|
||||
hashType = null;
|
||||
|
||||
} else if (localName.equals("hash") && curapk != null) {
|
||||
hashType = attributes.getValue("", "type");
|
||||
}
|
||||
@ -726,6 +730,17 @@ public class RepoXMLHandler extends DefaultHandler {
|
||||
DB.releaseDB();
|
||||
}
|
||||
}
|
||||
boolean updateRepo = false;
|
||||
|
||||
if (handler.version != null) {
|
||||
int version = Integer.parseInt(handler.version);
|
||||
if (version != repo.version) {
|
||||
Log.d("FDroid", "Repo specified a new version: from "
|
||||
+ repo.version + " to " + version);
|
||||
repo.version = version;
|
||||
updateRepo = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (handler.maxage != null) {
|
||||
int maxage = Integer.parseInt(handler.maxage);
|
||||
@ -733,12 +748,16 @@ public class RepoXMLHandler extends DefaultHandler {
|
||||
Log.d("FDroid",
|
||||
"Repo specified a new maximum age - updated");
|
||||
repo.maxage = maxage;
|
||||
try {
|
||||
DB db = DB.getDB();
|
||||
db.updateRepoByAddress(repo);
|
||||
} finally {
|
||||
DB.releaseDB();
|
||||
}
|
||||
updateRepo = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (updateRepo) {
|
||||
try {
|
||||
DB db = DB.getDB();
|
||||
db.updateRepoByAddress(repo);
|
||||
} finally {
|
||||
DB.releaseDB();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,10 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.nostra13.universalimageloader.utils.StorageUtils;
|
||||
|
||||
public final class Utils {
|
||||
|
||||
public static final int BUFFER_SIZE = 4096;
|
||||
@ -86,6 +90,30 @@ public final class Utils {
|
||||
return String.format(FRIENDLY_SIZE_FORMAT[i], s);
|
||||
}
|
||||
|
||||
public static String getAndroidVersionName(int sdkLevel) {
|
||||
switch (sdkLevel) {
|
||||
case 19: return "4.4";
|
||||
case 18: return "4.3";
|
||||
case 17: return "4.2";
|
||||
case 16: return "4.1";
|
||||
case 15: return "4.0.3";
|
||||
case 14: return "4.0";
|
||||
case 13: return "3.2";
|
||||
case 12: return "3.1";
|
||||
case 11: return "3.0";
|
||||
case 10: return "2.3.3";
|
||||
case 9: return "2.3";
|
||||
case 8: return "2.2";
|
||||
case 7: return "2.1";
|
||||
case 6: return "2.0.1";
|
||||
case 5: return "2.0";
|
||||
case 4: return "1.6";
|
||||
case 3: return "1.5";
|
||||
case 2: return "1.1";
|
||||
default: return "1.0";
|
||||
}
|
||||
}
|
||||
|
||||
public static int countSubstringOccurrence(File file, String substring) throws IOException {
|
||||
int count = 0;
|
||||
BufferedReader reader = null;
|
||||
@ -123,4 +151,13 @@ public final class Utils {
|
||||
return count;
|
||||
}
|
||||
|
||||
public static File getApkCacheDir(Context context) {
|
||||
File apkCacheDir = new File(
|
||||
StorageUtils.getCacheDirectory(context, true), "apks");
|
||||
if (!apkCacheDir.exists()) {
|
||||
apkCacheDir.mkdir();
|
||||
}
|
||||
return apkCacheDir;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ class OldContextCompatImpl extends ContextCompat {
|
||||
public File getExternalCacheDir() {
|
||||
File file = new File(Environment.getExternalStorageDirectory(),
|
||||
"Android/data/org.fdroid.fdroid/cache");
|
||||
if(!file.exists())
|
||||
if (!file.exists())
|
||||
file.mkdirs();
|
||||
return file;
|
||||
}
|
||||
|
@ -27,10 +27,13 @@ abstract public class AppListAdapter extends BaseAdapter {
|
||||
|
||||
private List<DB.App> items = new ArrayList<DB.App>();
|
||||
private Context mContext;
|
||||
private LayoutInflater mInflater;
|
||||
private DisplayImageOptions displayImageOptions;
|
||||
|
||||
public AppListAdapter(Context context) {
|
||||
mContext = context;
|
||||
mInflater = (LayoutInflater) mContext.getSystemService(
|
||||
Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
displayImageOptions = new DisplayImageOptions.Builder()
|
||||
.cacheInMemory(true)
|
||||
@ -76,38 +79,55 @@ abstract public class AppListAdapter extends BaseAdapter {
|
||||
return position;
|
||||
}
|
||||
|
||||
static class ViewHolder {
|
||||
TextView name;
|
||||
TextView summary;
|
||||
TextView status;
|
||||
TextView license;
|
||||
ImageView icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
|
||||
boolean compact = Preferences.get().hasCompactLayout();
|
||||
DB.App app = items.get(position);
|
||||
ViewHolder holder;
|
||||
|
||||
if (convertView == null) {
|
||||
convertView = ((LayoutInflater) mContext.getSystemService(
|
||||
Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.applistitem, null);
|
||||
convertView = mInflater.inflate(R.layout.applistitem, null);
|
||||
|
||||
holder = new ViewHolder();
|
||||
holder.name = (TextView) convertView.findViewById(R.id.name);
|
||||
holder.summary = (TextView) convertView.findViewById(R.id.summary);
|
||||
holder.status = (TextView) convertView.findViewById(R.id.status);
|
||||
holder.license = (TextView) convertView.findViewById(R.id.license);
|
||||
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
|
||||
|
||||
convertView.setTag(holder);
|
||||
} else {
|
||||
holder = (ViewHolder) convertView.getTag();
|
||||
}
|
||||
|
||||
TextView name = (TextView) convertView.findViewById(R.id.name);
|
||||
TextView summary = (TextView) convertView.findViewById(R.id.summary);
|
||||
TextView status = (TextView) convertView.findViewById(R.id.status);
|
||||
TextView license = (TextView) convertView.findViewById(R.id.license);
|
||||
ImageView icon = (ImageView) convertView.findViewById(R.id.icon);
|
||||
holder.name.setText(app.name);
|
||||
holder.summary.setText(app.summary);
|
||||
|
||||
name.setText(app.name);
|
||||
summary.setText(app.summary);
|
||||
|
||||
int visibleOnCompact = compact ? View.VISIBLE : View.GONE;
|
||||
int notVisibleOnCompact = compact ? View.GONE : View.VISIBLE;
|
||||
|
||||
layoutIcon(icon, compact);
|
||||
ImageLoader.getInstance().displayImage(app.iconUrl, icon,
|
||||
layoutIcon(holder.icon, compact);
|
||||
ImageLoader.getInstance().displayImage(app.iconUrl, holder.icon,
|
||||
displayImageOptions);
|
||||
|
||||
status.setText(getVersionInfo(app));
|
||||
license.setText(app.license);
|
||||
holder.status.setText(getVersionInfo(app));
|
||||
holder.license.setText(app.license);
|
||||
|
||||
// Disable it all if it isn't compatible...
|
||||
View[] views = { convertView, status, summary, license, name };
|
||||
View[] views = {
|
||||
convertView,
|
||||
holder.status,
|
||||
holder.summary,
|
||||
holder.license,
|
||||
holder.name
|
||||
};
|
||||
|
||||
for (View view : views) {
|
||||
view.setEnabled(app.compatible && !app.filtered);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user