Merge remote-tracking branch 'upstream/master' into improvement/16/manage-repos
Conflicts: res/values/strings.xml src/org/fdroid/fdroid/DB.java src/org/fdroid/fdroid/ManageRepo.java src/org/fdroid/fdroid/RepoXMLHandler.java src/org/fdroid/fdroid/Utils.java
This commit is contained in:
commit
3731ed8f23
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,11 +1,9 @@
|
|||||||
/local.properties
|
/local.properties
|
||||||
/build.properties
|
|
||||||
.classpath
|
.classpath
|
||||||
/bin/
|
/bin/
|
||||||
/gen/
|
/gen/
|
||||||
/build
|
/build
|
||||||
/.gradle
|
/.gradle
|
||||||
/proguard.cfg
|
|
||||||
/build.xml
|
/build.xml
|
||||||
*~
|
*~
|
||||||
.idea
|
.idea
|
||||||
|
@ -18,6 +18,14 @@
|
|||||||
android:layout_marginRight="4dp"
|
android:layout_marginRight="4dp"
|
||||||
android:orientation="vertical" >
|
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
|
<RelativeLayout
|
||||||
android:id="@+id/header"
|
android:id="@+id/header"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
@ -25,41 +33,48 @@
|
|||||||
android:layout_marginBottom="4dp"
|
android:layout_marginBottom="4dp"
|
||||||
android:orientation="horizontal" >
|
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
|
<ImageView
|
||||||
android:id="@+id/icon"
|
android:id="@+id/icon"
|
||||||
android:layout_width="48dp"
|
android:layout_width="56dp"
|
||||||
android:layout_height="48dp"
|
android:layout_height="56dp"
|
||||||
android:layout_below="@id/title"
|
android:padding="4dp"
|
||||||
android:layout_marginRight="6dp"
|
|
||||||
android:scaleType="fitCenter" />
|
android:scaleType="fitCenter" />
|
||||||
|
|
||||||
<TextView
|
<RelativeLayout
|
||||||
android:id="@+id/license"
|
android:layout_width="fill_parent"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:padding="4dp"
|
||||||
android:layout_below="@id/title"
|
android:layout_toRightOf="@id/icon"
|
||||||
android:layout_toRightOf="@id/icon"
|
android:orientation="vertical" >
|
||||||
android:textSize="13sp" />
|
|
||||||
|
<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>
|
</RelativeLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
<ListView
|
<ListView
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
android:textSize="18sp" />
|
android:textSize="18sp" />
|
||||||
|
|
||||||
<TextView android:id="@+id/status"
|
<TextView android:id="@+id/status"
|
||||||
android:textSize="12sp"
|
android:textSize="13sp"
|
||||||
android:maxLines="2"
|
android:maxLines="2"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:layout_below="@id/version"
|
android:layout_below="@id/version"
|
||||||
@ -23,28 +23,36 @@
|
|||||||
android:layout_width="wrap_content" />
|
android:layout_width="wrap_content" />
|
||||||
|
|
||||||
<TextView android:id="@+id/added"
|
<TextView android:id="@+id/added"
|
||||||
android:textSize="12sp"
|
android:textSize="13sp"
|
||||||
android:layout_below="@id/status"
|
android:layout_below="@id/status"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="wrap_content" />
|
android:layout_width="wrap_content" />
|
||||||
|
|
||||||
<TextView android:id="@+id/buildtype"
|
<TextView android:id="@+id/buildtype"
|
||||||
android:textSize="12sp"
|
android:textSize="13sp"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_marginBottom="4sp" />
|
android:layout_marginBottom="4sp" />
|
||||||
|
|
||||||
<TextView android:id="@+id/size"
|
<TextView android:id="@+id/size"
|
||||||
android:textSize="12sp"
|
android:textSize="13sp"
|
||||||
android:layout_below="@id/buildtype"
|
android:layout_below="@id/buildtype"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_marginBottom="4sp" />
|
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"
|
<TextView android:id="@+id/nativecode"
|
||||||
android:textSize="12sp"
|
android:textSize="13sp"
|
||||||
android:layout_below="@id/size"
|
android:layout_below="@id/size"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -22,9 +22,8 @@
|
|||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="56dp"
|
||||||
android:padding="6dp"
|
android:padding="6dp"
|
||||||
android:layout_centerVertical="true"
|
|
||||||
android:orientation="vertical" >
|
android:orientation="vertical" >
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@ -33,9 +32,9 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:paddingTop="2sp"
|
android:paddingTop="3sp"
|
||||||
android:paddingBottom="2sp"
|
android:paddingBottom="3sp"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_marginLeft="8sp"
|
||||||
android:textSize="13sp" />
|
android:textSize="13sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@ -44,7 +43,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_marginLeft="8sp"
|
||||||
android:textSize="13sp" />
|
android:textSize="13sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -27,11 +27,11 @@
|
|||||||
<TextView android:id="@+id/status"
|
<TextView android:id="@+id/status"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:paddingTop="2sp"
|
android:paddingTop="3sp"
|
||||||
android:paddingBottom="2sp"
|
android:paddingBottom="3sp"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_marginLeft="10sp"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_alignParentRight="true" />
|
android:layout_alignParentRight="true" />
|
||||||
|
|
||||||
@ -41,7 +41,7 @@
|
|||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_marginLeft="10sp"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_alignParentRight="true" />
|
android:layout_alignParentRight="true" />
|
||||||
|
|
||||||
|
@ -194,5 +194,6 @@
|
|||||||
<string name="repo_disabled_notification">Disabled "%1$s".\n\nYou will
|
<string name="repo_disabled_notification">Disabled "%1$s".\n\nYou will
|
||||||
need to re-enable this repository to install apps from it.
|
need to re-enable this repository to install apps from it.
|
||||||
</string>
|
</string>
|
||||||
|
<string name="minsdk_or_later">Android %s or later</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -76,6 +76,9 @@ import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
|
|||||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
|
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
|
||||||
|
import com.nostra13.universalimageloader.utils.StorageUtils;
|
||||||
|
|
||||||
|
import android.os.Environment;
|
||||||
|
|
||||||
public class AppDetails extends ListActivity {
|
public class AppDetails extends ListActivity {
|
||||||
|
|
||||||
@ -140,10 +143,11 @@ public class AppDetails extends ListActivity {
|
|||||||
|
|
||||||
tv = (TextView) v.findViewById(R.id.status);
|
tv = (TextView) v.findViewById(R.id.status);
|
||||||
if (apk.vercode == app.installedVerCode
|
if (apk.vercode == app.installedVerCode
|
||||||
&& apk.sig.equals(mInstalledSigID))
|
&& apk.sig.equals(mInstalledSigID)) {
|
||||||
tv.setText(getString(R.string.inst));
|
tv.setText(getString(R.string.inst));
|
||||||
else
|
} else {
|
||||||
tv.setText(getString(R.string.not_inst));
|
tv.setText(getString(R.string.not_inst));
|
||||||
|
}
|
||||||
tv.setEnabled(apk.compatible);
|
tv.setEnabled(apk.compatible);
|
||||||
|
|
||||||
tv = (TextView) v.findViewById(R.id.size);
|
tv = (TextView) v.findViewById(R.id.size);
|
||||||
@ -153,6 +157,16 @@ public class AppDetails extends ListActivity {
|
|||||||
tv.setText(Utils.getFriendlySize(apk.detail_size));
|
tv.setText(Utils.getFriendlySize(apk.detail_size));
|
||||||
tv.setEnabled(apk.compatible);
|
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);
|
tv = (TextView) v.findViewById(R.id.buildtype);
|
||||||
if (apk.srcname != null) {
|
if (apk.srcname != null) {
|
||||||
tv.setText("source");
|
tv.setText("source");
|
||||||
@ -160,6 +174,7 @@ public class AppDetails extends ListActivity {
|
|||||||
tv.setText("bin");
|
tv.setText("bin");
|
||||||
}
|
}
|
||||||
tv.setEnabled(apk.compatible);
|
tv.setEnabled(apk.compatible);
|
||||||
|
|
||||||
tv = (TextView) v.findViewById(R.id.added);
|
tv = (TextView) v.findViewById(R.id.added);
|
||||||
if (apk.added != null) {
|
if (apk.added != null) {
|
||||||
tv.setVisibility(View.VISIBLE);
|
tv.setVisibility(View.VISIBLE);
|
||||||
@ -168,6 +183,7 @@ public class AppDetails extends ListActivity {
|
|||||||
} else {
|
} else {
|
||||||
tv.setVisibility(View.GONE);
|
tv.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
tv = (TextView) v.findViewById(R.id.nativecode);
|
tv = (TextView) v.findViewById(R.id.nativecode);
|
||||||
if (pref_expert && apk.nativecode != null) {
|
if (pref_expert && apk.nativecode != null) {
|
||||||
tv.setVisibility(View.VISIBLE);
|
tv.setVisibility(View.VISIBLE);
|
||||||
@ -457,26 +473,6 @@ public class AppDetails extends ListActivity {
|
|||||||
|
|
||||||
tv = (TextView) infoView.findViewById(R.id.description);
|
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());
|
tv.setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
|
|
||||||
// Need this to add the unimplemented support for ordered and unordered
|
// 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,
|
public void onClick(DialogInterface dialog,
|
||||||
int whichButton) {
|
int whichButton) {
|
||||||
downloadHandler = new DownloadHandler(app.curApk,
|
downloadHandler = new DownloadHandler(app.curApk,
|
||||||
repoaddress, DB
|
repoaddress, Utils
|
||||||
.getDataPath(getBaseContext()));
|
.getApkCacheDir(getBaseContext()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ask_alrt.setNegativeButton(getString(R.string.no),
|
ask_alrt.setNegativeButton(getString(R.string.no),
|
||||||
@ -879,7 +875,7 @@ public class AppDetails extends ListActivity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
downloadHandler = new DownloadHandler(app.curApk, repoaddress,
|
downloadHandler = new DownloadHandler(app.curApk, repoaddress,
|
||||||
DB.getDataPath(this));
|
Utils.getApkCacheDir(getBaseContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeApk(String id) {
|
private void removeApk(String id) {
|
||||||
|
@ -108,7 +108,7 @@ public class DB {
|
|||||||
+ "lastUpdated string," + "compatible int not null,"
|
+ "lastUpdated string," + "compatible int not null,"
|
||||||
+ "ignoreAllUpdates int not null,"
|
+ "ignoreAllUpdates int not null,"
|
||||||
+ "ignoreThisUpdate int not null,"
|
+ "ignoreThisUpdate int not null,"
|
||||||
+ "provides string," + "primary key(id));";
|
+ "primary key(id));";
|
||||||
|
|
||||||
public static class App implements Comparable<App> {
|
public static class App implements Comparable<App> {
|
||||||
|
|
||||||
@ -126,7 +126,6 @@ public class DB {
|
|||||||
detail_dogecoinAddr = null;
|
detail_dogecoinAddr = null;
|
||||||
detail_webURL = null;
|
detail_webURL = null;
|
||||||
categories = null;
|
categories = null;
|
||||||
provides = null;
|
|
||||||
antiFeatures = null;
|
antiFeatures = null;
|
||||||
requirements = null;
|
requirements = null;
|
||||||
hasUpdates = false;
|
hasUpdates = false;
|
||||||
@ -201,9 +200,6 @@ public class DB {
|
|||||||
public int installedVerCode;
|
public int installedVerCode;
|
||||||
public boolean userInstalled;
|
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
|
// List of categories (as defined in the metadata
|
||||||
// documentation) or null if there aren't any.
|
// documentation) or null if there aren't any.
|
||||||
public CommaSeparatedList categories;
|
public CommaSeparatedList categories;
|
||||||
@ -377,10 +373,11 @@ public class DB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cpuAbis = new ArrayList<String>();
|
cpuAbis = new ArrayList<String>(2);
|
||||||
if (hasApi(8))
|
|
||||||
cpuAbis.add(android.os.Build.CPU_ABI2);
|
|
||||||
cpuAbis.add(android.os.Build.CPU_ABI);
|
cpuAbis.add(android.os.Build.CPU_ABI);
|
||||||
|
if (hasApi(8)) {
|
||||||
|
cpuAbis.add(android.os.Build.CPU_ABI2);
|
||||||
|
}
|
||||||
|
|
||||||
Log.d("FDroid", logMsg.toString());
|
Log.d("FDroid", logMsg.toString());
|
||||||
}
|
}
|
||||||
@ -413,8 +410,7 @@ public class DB {
|
|||||||
}
|
}
|
||||||
if (!compatibleApi(apk.nativecode)) {
|
if (!compatibleApi(apk.nativecode)) {
|
||||||
Log.d("FDroid", apk.id + " vercode " + apk.vercode
|
Log.d("FDroid", apk.id + " vercode " + apk.vercode
|
||||||
+ " makes use of incompatible native code: "
|
+ " only supports " + CommaSeparatedList.str(apk.nativecode)
|
||||||
+ CommaSeparatedList.str(apk.nativecode)
|
|
||||||
+ " while your architecture is " + cpuAbis.get(0));
|
+ " while your architecture is " + cpuAbis.get(0));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -437,6 +433,7 @@ public class DB {
|
|||||||
public String address;
|
public String address;
|
||||||
public String name;
|
public String name;
|
||||||
public String description;
|
public String description;
|
||||||
|
public int version; // index version, i.e. what fdroidserver built it - 0 if not specified
|
||||||
public boolean inuse;
|
public boolean inuse;
|
||||||
public int priority;
|
public int priority;
|
||||||
public String pubkey; // null for an unsigned repo
|
public String pubkey; // null for an unsigned repo
|
||||||
@ -530,7 +527,7 @@ public class DB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final int DBVersion = 33;
|
private final int DBVersion = 35;
|
||||||
|
|
||||||
private int countAppsForRepo(int id) {
|
private int countAppsForRepo(int id) {
|
||||||
String[] selection = { "COUNT(distinct id)" };
|
String[] selection = { "COUNT(distinct id)" };
|
||||||
@ -609,6 +606,7 @@ public class DB {
|
|||||||
mContext.getString(R.string.default_repo_name));
|
mContext.getString(R.string.default_repo_name));
|
||||||
values.put("description",
|
values.put("description",
|
||||||
mContext.getString(R.string.default_repo_description));
|
mContext.getString(R.string.default_repo_description));
|
||||||
|
values.put("version", 0);
|
||||||
String pubkey = mContext.getString(R.string.default_repo_pubkey);
|
String pubkey = mContext.getString(R.string.default_repo_pubkey);
|
||||||
String fingerprint = DB.calcFingerprint(pubkey);
|
String fingerprint = DB.calcFingerprint(pubkey);
|
||||||
values.put("pubkey", pubkey);
|
values.put("pubkey", pubkey);
|
||||||
@ -626,9 +624,11 @@ public class DB {
|
|||||||
mContext.getString(R.string.default_repo_name2));
|
mContext.getString(R.string.default_repo_name2));
|
||||||
values.put("description",
|
values.put("description",
|
||||||
mContext.getString(R.string.default_repo_description2));
|
mContext.getString(R.string.default_repo_description2));
|
||||||
|
values.put("version", 0);
|
||||||
// default #2 is /archive which has the same key as /repo
|
// default #2 is /archive which has the same key as /repo
|
||||||
values.put("pubkey", pubkey);
|
values.put("pubkey", pubkey);
|
||||||
values.put("fingerprint", fingerprint);
|
values.put("fingerprint", fingerprint);
|
||||||
|
values.put("maxage", 0);
|
||||||
values.put("inuse", 0);
|
values.put("inuse", 0);
|
||||||
values.put("priority", 20);
|
values.put("priority", 20);
|
||||||
values.put("lastetag", (String) null);
|
values.put("lastetag", (String) null);
|
||||||
@ -720,23 +720,14 @@ public class DB {
|
|||||||
db.execSQL("alter table " + TABLE_REPO + " add column maxage integer not null default 0");
|
db.execSQL("alter table " + TABLE_REPO + " add column maxage integer not null default 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldVersion < 33) {
|
if (oldVersion < 35) {
|
||||||
if (!columnExists(db, TABLE_REPO, "lastUpdated"))
|
if (!columnExists(db, TABLE_REPO, "lastUpdated"))
|
||||||
db.execSQL("Alter table " + TABLE_REPO + " add column lastUpdated string");
|
db.execSQL("Alter table " + TABLE_REPO + " add column lastUpdated string");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 Context mContext;
|
||||||
private Apk.CompatibilityChecker compatChecker = null;
|
private Apk.CompatibilityChecker compatChecker = null;
|
||||||
|
|
||||||
@ -924,16 +915,23 @@ public class DB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, App> apps = new HashMap<String, App>();
|
// Start the map at the actual number of apps we will have
|
||||||
Cursor c = null;
|
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();
|
long startTime = System.currentTimeMillis();
|
||||||
try {
|
try {
|
||||||
|
|
||||||
String cols[] = new String[] { "antiFeatures", "requirements",
|
String cols[] = new String[] { "antiFeatures", "requirements",
|
||||||
"categories", "id", "name", "summary", "icon", "license",
|
"categories", "id", "name", "summary", "icon", "license",
|
||||||
"curVersion", "curVercode", "added", "lastUpdated",
|
"curVersion", "curVercode", "added", "lastUpdated",
|
||||||
"compatible", "ignoreAllUpdates", "ignoreThisUpdate",
|
"compatible", "ignoreAllUpdates", "ignoreThisUpdate" };
|
||||||
"provides" };
|
|
||||||
c = db.query(TABLE_APP, cols, null, null, null, null, null);
|
c = db.query(TABLE_APP, cols, null, null, null, null, null);
|
||||||
c.moveToFirst();
|
c.moveToFirst();
|
||||||
while (!c.isAfterLast()) {
|
while (!c.isAfterLast()) {
|
||||||
@ -959,7 +957,6 @@ public class DB {
|
|||||||
app.compatible = c.getInt(12) == 1;
|
app.compatible = c.getInt(12) == 1;
|
||||||
app.ignoreAllUpdates = c.getInt(13) == 1;
|
app.ignoreAllUpdates = c.getInt(13) == 1;
|
||||||
app.ignoreThisUpdate = c.getInt(14);
|
app.ignoreThisUpdate = c.getInt(14);
|
||||||
app.provides = DB.CommaSeparatedList.make(c.getString(15));
|
|
||||||
app.hasUpdates = false;
|
app.hasUpdates = false;
|
||||||
|
|
||||||
if (getinstalledinfo && systemApks.containsKey(app.id)) {
|
if (getinstalledinfo && systemApks.containsKey(app.id)) {
|
||||||
@ -979,18 +976,13 @@ public class DB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apps.put(app.id, app);
|
apps.put(app.id, app);
|
||||||
if (app.provides != null) {
|
|
||||||
for (String id : app.provides) {
|
|
||||||
apps.put(id, app);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.moveToNext();
|
c.moveToNext();
|
||||||
}
|
}
|
||||||
c.close();
|
c.close();
|
||||||
c = null;
|
c = null;
|
||||||
|
|
||||||
Log.d("FDroid", "Read app data from database " + " (took "
|
Log.d("FDroid", "Read app data from database (took "
|
||||||
+ (System.currentTimeMillis() - startTime) + " ms)");
|
+ (System.currentTimeMillis() - startTime) + " ms)");
|
||||||
|
|
||||||
List<Repo> repos = getRepos();
|
List<Repo> repos = getRepos();
|
||||||
@ -1049,7 +1041,7 @@ public class DB {
|
|||||||
c.close();
|
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)");
|
+ (System.currentTimeMillis() - startTime) + " ms)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1141,7 +1133,7 @@ public class DB {
|
|||||||
try {
|
try {
|
||||||
String filter = "%" + query + "%";
|
String filter = "%" + query + "%";
|
||||||
c = db.query(TABLE_APP, new String[] { "id" },
|
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);
|
new String[] { filter, filter, filter, filter }, null, null, null);
|
||||||
c.moveToFirst();
|
c.moveToFirst();
|
||||||
while (!c.isAfterLast()) {
|
while (!c.isAfterLast()) {
|
||||||
@ -1412,8 +1404,8 @@ public class DB {
|
|||||||
Cursor c = null;
|
Cursor c = null;
|
||||||
try {
|
try {
|
||||||
c = db.query(TABLE_REPO, new String[] { "address", "name",
|
c = db.query(TABLE_REPO, new String[] { "address", "name",
|
||||||
"description", "inuse", "priority", "pubkey", "fingerprint",
|
"description", "version", "inuse", "priority", "pubkey",
|
||||||
"maxage", "lastetag", "lastUpdated" },
|
"fingerprint", "maxage", "lastetag", "lastUpdated" },
|
||||||
"id = ?", new String[] { Integer.toString(id) }, null, null, null);
|
"id = ?", new String[] { Integer.toString(id) }, null, null, null);
|
||||||
if (!c.moveToFirst())
|
if (!c.moveToFirst())
|
||||||
return null;
|
return null;
|
||||||
@ -1422,19 +1414,19 @@ public class DB {
|
|||||||
repo.address = c.getString(0);
|
repo.address = c.getString(0);
|
||||||
repo.name = c.getString(1);
|
repo.name = c.getString(1);
|
||||||
repo.description = c.getString(2);
|
repo.description = c.getString(2);
|
||||||
repo.inuse = (c.getInt(3) == 1);
|
repo.version = c.getInt(3);
|
||||||
repo.priority = c.getInt(4);
|
repo.inuse = (c.getInt(4) == 1);
|
||||||
repo.pubkey = c.getString(5);
|
repo.priority = c.getInt(5);
|
||||||
repo.fingerprint = c.getString(6);
|
repo.pubkey = c.getString(6);
|
||||||
repo.maxage = c.getInt(7);
|
repo.fingerprint = c.getString(7);
|
||||||
repo.lastetag = c.getString(8);
|
repo.maxage = c.getInt(8);
|
||||||
|
repo.lastetag = c.getString(9);
|
||||||
try {
|
try {
|
||||||
repo.lastUpdated = c.getString(9) != null ?
|
repo.lastUpdated = c.getString(10) != null ?
|
||||||
mDateFormat.parse( c.getString(9)) :
|
mDateFormat.parse( c.getString(10)) :
|
||||||
null;
|
null;
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
Log.e("FDroid", "Error parsing date " + c.getString(9));
|
Log.e("FDroid", "Error parsing date " + c.getString(10));
|
||||||
}
|
}
|
||||||
return repo;
|
return repo;
|
||||||
} finally {
|
} finally {
|
||||||
@ -1449,8 +1441,8 @@ public class DB {
|
|||||||
Cursor c = null;
|
Cursor c = null;
|
||||||
try {
|
try {
|
||||||
c = db.query(TABLE_REPO, new String[] { "id", "address", "name",
|
c = db.query(TABLE_REPO, new String[] { "id", "address", "name",
|
||||||
"description", "inuse", "priority", "pubkey", "fingerprint",
|
"description", "version", "inuse", "priority", "pubkey",
|
||||||
"maxage", "lastetag" },
|
"fingerprint", "maxage", "lastetag" },
|
||||||
null, null, null, null, "priority");
|
null, null, null, null, "priority");
|
||||||
c.moveToFirst();
|
c.moveToFirst();
|
||||||
while (!c.isAfterLast()) {
|
while (!c.isAfterLast()) {
|
||||||
@ -1459,12 +1451,13 @@ public class DB {
|
|||||||
repo.address = c.getString(1);
|
repo.address = c.getString(1);
|
||||||
repo.name = c.getString(2);
|
repo.name = c.getString(2);
|
||||||
repo.description = c.getString(3);
|
repo.description = c.getString(3);
|
||||||
repo.inuse = (c.getInt(4) == 1);
|
repo.version = c.getInt(4);
|
||||||
repo.priority = c.getInt(5);
|
repo.inuse = (c.getInt(5) == 1);
|
||||||
repo.pubkey = c.getString(6);
|
repo.priority = c.getInt(6);
|
||||||
repo.fingerprint = c.getString(7);
|
repo.pubkey = c.getString(7);
|
||||||
repo.maxage = c.getInt(8);
|
repo.fingerprint = c.getString(8);
|
||||||
repo.lastetag = c.getString(9);
|
repo.maxage = c.getInt(9);
|
||||||
|
repo.lastetag = c.getString(10);
|
||||||
repos.add(repo);
|
repos.add(repo);
|
||||||
c.moveToNext();
|
c.moveToNext();
|
||||||
}
|
}
|
||||||
@ -1524,6 +1517,7 @@ public class DB {
|
|||||||
values.put("name", repo.name);
|
values.put("name", repo.name);
|
||||||
values.put("address", repo.address);
|
values.put("address", repo.address);
|
||||||
values.put("description", repo.description);
|
values.put("description", repo.description);
|
||||||
|
values.put("version", repo.version);
|
||||||
values.put("inuse", repo.inuse);
|
values.put("inuse", repo.inuse);
|
||||||
values.put("priority", repo.priority);
|
values.put("priority", repo.priority);
|
||||||
values.put("pubkey", repo.pubkey);
|
values.put("pubkey", repo.pubkey);
|
||||||
@ -1558,12 +1552,14 @@ public class DB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addRepo(String address, String name, String description,
|
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 {
|
throws SecurityException {
|
||||||
ContentValues values = new ContentValues();
|
ContentValues values = new ContentValues();
|
||||||
values.put("address", address);
|
values.put("address", address);
|
||||||
values.put("name", name);
|
values.put("name", name);
|
||||||
values.put("description", description);
|
values.put("description", description);
|
||||||
|
values.put("version", version);
|
||||||
values.put("inuse", inuse ? 1 : 0);
|
values.put("inuse", inuse ? 1 : 0);
|
||||||
values.put("priority", priority);
|
values.put("priority", priority);
|
||||||
values.put("pubkey", pubkey);
|
values.put("pubkey", pubkey);
|
||||||
|
@ -127,8 +127,11 @@ public class FDroid extends FragmentActivity {
|
|||||||
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(
|
MenuItem update = 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);
|
||||||
|
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(
|
menu.add(Menu.NONE, MANAGE_REPO, 2, R.string.menu_manage).setIcon(
|
||||||
android.R.drawable.ic_menu_agenda);
|
android.R.drawable.ic_menu_agenda);
|
||||||
MenuItem search = menu.add(Menu.NONE, SEARCH, 3, R.string.menu_search).setIcon(
|
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.Context;
|
||||||
import android.content.SharedPreferences;
|
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.impl.LimitedAgeDiscCache;
|
||||||
import com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator;
|
import com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||||
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
|
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
|
||||||
|
import com.nostra13.universalimageloader.utils.StorageUtils;
|
||||||
|
|
||||||
public class FDroidApp extends Application {
|
public class FDroidApp extends Application {
|
||||||
|
|
||||||
@ -78,14 +80,14 @@ public class FDroidApp extends Application {
|
|||||||
curTheme = Theme.valueOf(prefs.getString("theme", "dark"));
|
curTheme = Theme.valueOf(prefs.getString("theme", "dark"));
|
||||||
if (!prefs.getBoolean("cacheDownloaded", false)) {
|
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
|
// Things can be null if the SD card is not ready - we'll just
|
||||||
// ignore that and do it next time.
|
// ignore that and do it next time.
|
||||||
if(local_path != null) {
|
if (local_path != null) {
|
||||||
File[] files = local_path.listFiles();
|
File[] files = local_path.listFiles();
|
||||||
if(files != null) {
|
if (files != null) {
|
||||||
for(File f : files) {
|
for (File f : files) {
|
||||||
if(f.getName().endsWith(".apk")) {
|
if (f.getName().endsWith(".apk")) {
|
||||||
f.delete();
|
f.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,7 +103,8 @@ public class FDroidApp extends Application {
|
|||||||
|
|
||||||
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(ctx)
|
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(ctx)
|
||||||
.discCache(new LimitedAgeDiscCache(
|
.discCache(new LimitedAgeDiscCache(
|
||||||
new File(StorageUtils.getCacheDirectory(ctx), "icons"),
|
new File(StorageUtils.getCacheDirectory(ctx, true),
|
||||||
|
"icons"),
|
||||||
new FileNameGenerator() {
|
new FileNameGenerator() {
|
||||||
@Override
|
@Override
|
||||||
public String generate(String imageUri) {
|
public String generate(String imageUri) {
|
||||||
|
@ -64,8 +64,9 @@ public class RepoXMLHandler extends DefaultHandler {
|
|||||||
private DB.Apk curapk = null;
|
private DB.Apk curapk = null;
|
||||||
private StringBuilder curchars = new StringBuilder();
|
private StringBuilder curchars = new StringBuilder();
|
||||||
|
|
||||||
// After processing the XML, this will be -1 if the index didn't specify
|
// After processing the XML, these will be -1 if the index didn't specify
|
||||||
// a maximum age - otherwise it will be the value specified.
|
// them - otherwise it will be the value specified.
|
||||||
|
private int version = -1;
|
||||||
private int maxage = -1;
|
private int maxage = -1;
|
||||||
|
|
||||||
// After processing the XML, this will be null if the index specified a
|
// After processing the XML, this will be null if the index specified a
|
||||||
@ -242,8 +243,6 @@ public class RepoXMLHandler extends DefaultHandler {
|
|||||||
} catch (NumberFormatException ex) {
|
} catch (NumberFormatException ex) {
|
||||||
curapp.curVercode = -1;
|
curapp.curVercode = -1;
|
||||||
}
|
}
|
||||||
} else if (curel.equals("provides")) {
|
|
||||||
curapp.provides = DB.CommaSeparatedList.make(str);
|
|
||||||
} else if (curel.equals("categories")) {
|
} else if (curel.equals("categories")) {
|
||||||
curapp.categories = DB.CommaSeparatedList.make(str);
|
curapp.categories = DB.CommaSeparatedList.make(str);
|
||||||
} else if (curel.equals("antifeatures")) {
|
} else if (curel.equals("antifeatures")) {
|
||||||
@ -266,10 +265,12 @@ public class RepoXMLHandler extends DefaultHandler {
|
|||||||
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.equals("repo")) {
|
if (localName.equals("repo")) {
|
||||||
String pk = attributes.getValue("", "pubkey");
|
String pk = attributes.getValue("", "pubkey");
|
||||||
if (pk != null)
|
if (pk != null)
|
||||||
pubkey = pk;
|
pubkey = pk;
|
||||||
|
|
||||||
String maxAgeAttr = attributes.getValue("", "maxage");
|
String maxAgeAttr = attributes.getValue("", "maxage");
|
||||||
if (maxAgeAttr != null) {
|
if (maxAgeAttr != null) {
|
||||||
try {
|
try {
|
||||||
@ -277,12 +278,20 @@ public class RepoXMLHandler extends DefaultHandler {
|
|||||||
} catch (NumberFormatException nfe) {}
|
} catch (NumberFormatException nfe) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String versionAttr = attributes.getValue("", "version");
|
||||||
|
if (versionAttr != null) {
|
||||||
|
try {
|
||||||
|
version = Integer.parseInt(versionAttr);
|
||||||
|
} catch (NumberFormatException nfe) {}
|
||||||
|
}
|
||||||
|
|
||||||
String nm = attributes.getValue("", "name");
|
String nm = attributes.getValue("", "name");
|
||||||
if (nm != null)
|
if (nm != null)
|
||||||
name = nm;
|
name = nm;
|
||||||
String dc = attributes.getValue("", "description");
|
String dc = attributes.getValue("", "description");
|
||||||
if (dc != null)
|
if (dc != null)
|
||||||
description = dc;
|
description = dc;
|
||||||
|
|
||||||
} else if (localName.equals("application") && curapp == null) {
|
} else if (localName.equals("application") && curapp == null) {
|
||||||
curapp = new DB.App();
|
curapp = new DB.App();
|
||||||
curapp.detail_Populated = true;
|
curapp.detail_Populated = true;
|
||||||
@ -293,11 +302,13 @@ public class RepoXMLHandler extends DefaultHandler {
|
|||||||
new ProgressListener.Event(
|
new ProgressListener.Event(
|
||||||
RepoXMLHandler.PROGRESS_TYPE_PROCESS_XML, progressCounter,
|
RepoXMLHandler.PROGRESS_TYPE_PROCESS_XML, progressCounter,
|
||||||
totalAppCount, progressData));
|
totalAppCount, progressData));
|
||||||
|
|
||||||
} else if (localName.equals("package") && curapp != null && curapk == null) {
|
} else if (localName.equals("package") && curapp != null && curapk == null) {
|
||||||
curapk = new DB.Apk();
|
curapk = new DB.Apk();
|
||||||
curapk.id = curapp.id;
|
curapk.id = curapp.id;
|
||||||
curapk.repo = repo.id;
|
curapk.repo = repo.id;
|
||||||
hashType = null;
|
hashType = null;
|
||||||
|
|
||||||
} else if (localName.equals("hash") && curapk != null) {
|
} else if (localName.equals("hash") && curapk != null) {
|
||||||
hashType = attributes.getValue("", "type");
|
hashType = attributes.getValue("", "type");
|
||||||
}
|
}
|
||||||
@ -511,6 +522,13 @@ public class RepoXMLHandler extends DefaultHandler {
|
|||||||
repoChanged = true;
|
repoChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (version != -1 && version != repo.version) {
|
||||||
|
Log.d("FDroid", "Repo specified a new version: from "
|
||||||
|
+ repo.version + " to " + version);
|
||||||
|
repo.version = version;
|
||||||
|
repoChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (maxage != -1 && maxage != repo.maxage) {
|
if (maxage != -1 && maxage != repo.maxage) {
|
||||||
Log.d("FDroid",
|
Log.d("FDroid",
|
||||||
"Repo specified a new maximum age - updated");
|
"Repo specified a new maximum age - updated");
|
||||||
|
@ -31,6 +31,10 @@ import java.io.OutputStream;
|
|||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.Formatter;
|
import java.util.Formatter;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.nostra13.universalimageloader.utils.StorageUtils;
|
||||||
|
|
||||||
public final class Utils {
|
public final class Utils {
|
||||||
|
|
||||||
public static final int BUFFER_SIZE = 4096;
|
public static final int BUFFER_SIZE = 4096;
|
||||||
@ -86,6 +90,30 @@ public final class Utils {
|
|||||||
return String.format(FRIENDLY_SIZE_FORMAT[i], s);
|
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 {
|
public static int countSubstringOccurrence(File file, String substring) throws IOException {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
BufferedReader reader = null;
|
BufferedReader reader = null;
|
||||||
@ -152,4 +180,14 @@ public final class Utils {
|
|||||||
}
|
}
|
||||||
return fingerprintString;
|
return fingerprintString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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() {
|
public File getExternalCacheDir() {
|
||||||
File file = new File(Environment.getExternalStorageDirectory(),
|
File file = new File(Environment.getExternalStorageDirectory(),
|
||||||
"Android/data/org.fdroid.fdroid/cache");
|
"Android/data/org.fdroid.fdroid/cache");
|
||||||
if(!file.exists())
|
if (!file.exists())
|
||||||
file.mkdirs();
|
file.mkdirs();
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
@ -27,10 +27,13 @@ abstract public class AppListAdapter extends BaseAdapter {
|
|||||||
|
|
||||||
private List<DB.App> items = new ArrayList<DB.App>();
|
private List<DB.App> items = new ArrayList<DB.App>();
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
|
private LayoutInflater mInflater;
|
||||||
private DisplayImageOptions displayImageOptions;
|
private DisplayImageOptions displayImageOptions;
|
||||||
|
|
||||||
public AppListAdapter(Context context) {
|
public AppListAdapter(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
mInflater = (LayoutInflater) mContext.getSystemService(
|
||||||
|
Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
|
||||||
displayImageOptions = new DisplayImageOptions.Builder()
|
displayImageOptions = new DisplayImageOptions.Builder()
|
||||||
.cacheInMemory(true)
|
.cacheInMemory(true)
|
||||||
@ -76,38 +79,55 @@ abstract public class AppListAdapter extends BaseAdapter {
|
|||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class ViewHolder {
|
||||||
|
TextView name;
|
||||||
|
TextView summary;
|
||||||
|
TextView status;
|
||||||
|
TextView license;
|
||||||
|
ImageView icon;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
|
||||||
boolean compact = Preferences.get().hasCompactLayout();
|
boolean compact = Preferences.get().hasCompactLayout();
|
||||||
DB.App app = items.get(position);
|
DB.App app = items.get(position);
|
||||||
|
ViewHolder holder;
|
||||||
|
|
||||||
if (convertView == null) {
|
if (convertView == null) {
|
||||||
convertView = ((LayoutInflater) mContext.getSystemService(
|
convertView = mInflater.inflate(R.layout.applistitem, null);
|
||||||
Context.LAYOUT_INFLATER_SERVICE)).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);
|
holder.name.setText(app.name);
|
||||||
TextView summary = (TextView) convertView.findViewById(R.id.summary);
|
holder.summary.setText(app.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);
|
|
||||||
|
|
||||||
name.setText(app.name);
|
layoutIcon(holder.icon, compact);
|
||||||
summary.setText(app.summary);
|
ImageLoader.getInstance().displayImage(app.iconUrl, holder.icon,
|
||||||
|
|
||||||
int visibleOnCompact = compact ? View.VISIBLE : View.GONE;
|
|
||||||
int notVisibleOnCompact = compact ? View.GONE : View.VISIBLE;
|
|
||||||
|
|
||||||
layoutIcon(icon, compact);
|
|
||||||
ImageLoader.getInstance().displayImage(app.iconUrl, icon,
|
|
||||||
displayImageOptions);
|
displayImageOptions);
|
||||||
|
|
||||||
status.setText(getVersionInfo(app));
|
holder.status.setText(getVersionInfo(app));
|
||||||
license.setText(app.license);
|
holder.license.setText(app.license);
|
||||||
|
|
||||||
// Disable it all if it isn't compatible...
|
// 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) {
|
for (View view : views) {
|
||||||
view.setEnabled(app.compatible && !app.filtered);
|
view.setEnabled(app.compatible && !app.filtered);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user