Merge branch 'remove-old-ui-dead-code' into 'master'
Remove old ui dead code See merge request !456
@ -126,16 +126,6 @@
|
||||
android:resource="@xml/install_history_file_provider" />
|
||||
</provider>
|
||||
|
||||
<meta-data
|
||||
android:name="android.app.default_searchable"
|
||||
android:value=".FDroid" />
|
||||
|
||||
<activity
|
||||
android:name=".FDroid"
|
||||
android:launchMode="singleTop"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:configChanges="layoutDirection|locale|keyboardHidden|orientation|screenSize" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".privileged.views.InstallConfirmActivity"
|
||||
android:label="@string/menu_install"
|
||||
@ -183,17 +173,6 @@
|
||||
android:value=".views.ManageReposActivity" />
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".AppDetails"
|
||||
android:label="@string/app_details"
|
||||
android:exported="true"
|
||||
android:parentActivityName=".FDroid"
|
||||
android:configChanges="layoutDirection|locale" >
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".FDroid" />
|
||||
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".AppDetails2"
|
||||
android:label="@string/app_details"
|
||||
@ -204,14 +183,6 @@
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".views.main.MainActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:label="@string/menu_settings"
|
||||
android:name=".PreferencesActivity"
|
||||
android:parentActivityName=".FDroid" >
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".FDroid" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".acra.CrashReportActivity"
|
||||
android:theme="@style/AppThemeDark"
|
||||
|
@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2010-12 Ciaran Gultnieks, ciaran@ciarang.com
|
||||
* Copyright (C) 2013-15 Daniel Martí <mvdan@mvdan.cc>
|
||||
* Copyright (C) 2013 Stefan Völkel, bd@bc-bd.org
|
||||
* Copyright (C) 2015 Nico Alt, nicoalt@posteo.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package org.fdroid.fdroid;
|
||||
|
||||
import android.app.Activity;
|
||||
|
@ -1,456 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-12 Ciaran Gultnieks, ciaran@ciarang.com
|
||||
* Copyright (C) 2009 Roberto Jacinto, roberto.jacinto@caixamagica.pt
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package org.fdroid.fdroid;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.app.SearchManager;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.database.ContentObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.view.MenuItemCompat;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.SearchView;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.fdroid.fdroid.compat.TabManager;
|
||||
import org.fdroid.fdroid.compat.UriCompat;
|
||||
import org.fdroid.fdroid.data.AppProvider;
|
||||
import org.fdroid.fdroid.data.NewRepoConfig;
|
||||
import org.fdroid.fdroid.views.AppListFragmentPagerAdapter;
|
||||
import org.fdroid.fdroid.views.ManageReposActivity;
|
||||
import org.fdroid.fdroid.views.swap.SwapWorkflowActivity;
|
||||
|
||||
public class FDroid extends AppCompatActivity implements SearchView.OnQueryTextListener {
|
||||
|
||||
private static final String TAG = "FDroid";
|
||||
|
||||
private static final int REQUEST_PREFS = 1;
|
||||
private static final int REQUEST_ENABLE_BLUETOOTH = 2;
|
||||
private static final int REQUEST_SWAP = 3;
|
||||
|
||||
public static final String EXTRA_TAB_UPDATE = "extraTab";
|
||||
|
||||
private static final String ACTION_ADD_REPO = "org.fdroid.fdroid.FDroid.ACTION_ADD_REPO";
|
||||
|
||||
private static final String ADD_REPO_INTENT_HANDLED = "addRepoIntentHandled";
|
||||
|
||||
private FDroidApp fdroidApp;
|
||||
|
||||
private SearchView searchView;
|
||||
|
||||
private ViewPager viewPager;
|
||||
|
||||
@Nullable
|
||||
private TabManager tabManager;
|
||||
|
||||
private AppListFragmentPagerAdapter adapter;
|
||||
|
||||
@Nullable
|
||||
private MenuItem searchMenuItem;
|
||||
|
||||
@Nullable
|
||||
private String pendingSearchQuery;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
fdroidApp = (FDroidApp) getApplication();
|
||||
fdroidApp.applyTheme(this);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.fdroid);
|
||||
createViews();
|
||||
|
||||
getTabManager().createTabs();
|
||||
|
||||
// Start a search by just typing
|
||||
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
|
||||
|
||||
Intent intent = getIntent();
|
||||
handleSearchOrAppViewIntent(intent);
|
||||
|
||||
if (intent.hasExtra(EXTRA_TAB_UPDATE)) {
|
||||
boolean showUpdateTab = intent.getBooleanExtra(EXTRA_TAB_UPDATE, false);
|
||||
if (showUpdateTab) {
|
||||
getTabManager().selectTab(2);
|
||||
}
|
||||
}
|
||||
|
||||
Uri uri = AppProvider.getContentUri();
|
||||
getContentResolver().registerContentObserver(uri, true, new AppObserver());
|
||||
|
||||
// Re-enable once it can be disabled via a setting
|
||||
// See https://gitlab.com/fdroid/fdroidclient/issues/435
|
||||
//
|
||||
// if (UpdateService.isNetworkAvailableForUpdate(this)) {
|
||||
// UpdateService.updateNow(this);
|
||||
// }
|
||||
}
|
||||
|
||||
private void performSearch(String query) {
|
||||
if (searchMenuItem == null) {
|
||||
// Store this for later when we do actually have a search menu ready to use.
|
||||
pendingSearchQuery = query;
|
||||
return;
|
||||
}
|
||||
|
||||
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
|
||||
MenuItemCompat.expandActionView(searchMenuItem);
|
||||
searchView.setQuery(query, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
FDroidApp.checkStartTor(this);
|
||||
// AppDetails and RepoDetailsActivity set different NFC actions, so reset here
|
||||
NfcHelper.setAndroidBeam(this, getApplication().getPackageName());
|
||||
checkForAddRepoIntent(getIntent());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
handleSearchOrAppViewIntent(intent);
|
||||
|
||||
// This is called here as well as onResume(), because onNewIntent() is not called the first
|
||||
// time the activity is created. An alternative option to make sure that the add repo intent
|
||||
// is always handled is to call setIntent(intent) here. However, after this good read:
|
||||
// http://stackoverflow.com/a/7749347 it seems that adding a repo is not really more
|
||||
// important than the original intent which caused the activity to start (even though it
|
||||
// could technically have been an add repo intent itself).
|
||||
// The end result is that this method will be called twice for one add repo intent. Once
|
||||
// here and once in onResume(). However, the method deals with this by ensuring it only
|
||||
// handles the same intent once.
|
||||
checkForAddRepoIntent(intent);
|
||||
}
|
||||
|
||||
private void handleSearchOrAppViewIntent(Intent intent) {
|
||||
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
|
||||
String query = intent.getStringExtra(SearchManager.QUERY);
|
||||
performSearch(query);
|
||||
return;
|
||||
}
|
||||
|
||||
final Uri data = intent.getData();
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String scheme = data.getScheme();
|
||||
final String path = data.getPath();
|
||||
String packageName = null;
|
||||
String query = null;
|
||||
if (data.isHierarchical()) {
|
||||
final String host = data.getHost();
|
||||
if (host == null) {
|
||||
return;
|
||||
}
|
||||
switch (host) {
|
||||
case "f-droid.org":
|
||||
if (path.startsWith("/repository/browse")) {
|
||||
// http://f-droid.org/repository/browse?fdfilter=search+query
|
||||
query = UriCompat.getQueryParameter(data, "fdfilter");
|
||||
|
||||
// http://f-droid.org/repository/browse?fdid=packageName
|
||||
packageName = UriCompat.getQueryParameter(data, "fdid");
|
||||
} else if (path.startsWith("/app")) {
|
||||
// http://f-droid.org/app/packageName
|
||||
packageName = data.getLastPathSegment();
|
||||
if ("app".equals(packageName)) {
|
||||
packageName = null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "details":
|
||||
// market://details?id=app.id
|
||||
packageName = UriCompat.getQueryParameter(data, "id");
|
||||
break;
|
||||
case "search":
|
||||
// market://search?q=query
|
||||
query = UriCompat.getQueryParameter(data, "q");
|
||||
break;
|
||||
case "play.google.com":
|
||||
if (path.startsWith("/store/apps/details")) {
|
||||
// http://play.google.com/store/apps/details?id=app.id
|
||||
packageName = UriCompat.getQueryParameter(data, "id");
|
||||
} else if (path.startsWith("/store/search")) {
|
||||
// http://play.google.com/store/search?q=foo
|
||||
query = UriCompat.getQueryParameter(data, "q");
|
||||
}
|
||||
break;
|
||||
case "apps":
|
||||
case "amazon.com":
|
||||
case "www.amazon.com":
|
||||
// amzn://apps/android?p=app.id
|
||||
// http://amazon.com/gp/mas/dl/android?s=app.id
|
||||
packageName = UriCompat.getQueryParameter(data, "p");
|
||||
query = UriCompat.getQueryParameter(data, "s");
|
||||
break;
|
||||
}
|
||||
} else if ("fdroid.app".equals(scheme)) {
|
||||
// fdroid.app:app.id
|
||||
packageName = data.getSchemeSpecificPart();
|
||||
} else if ("fdroid.search".equals(scheme)) {
|
||||
// fdroid.search:query
|
||||
query = data.getSchemeSpecificPart();
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(query)) {
|
||||
// an old format for querying via packageName
|
||||
if (query.startsWith("pname:")) {
|
||||
packageName = query.split(":")[1];
|
||||
}
|
||||
|
||||
// sometimes, search URLs include pub: or other things before the query string
|
||||
if (query.contains(":")) {
|
||||
query = query.split(":")[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(packageName)) {
|
||||
Utils.debugLog(TAG, "FDroid launched via app link for '" + packageName + "'");
|
||||
Intent intentToInvoke = new Intent(this, AppDetails2.class);
|
||||
intentToInvoke.putExtra(AppDetails2.EXTRA_APPID, packageName);
|
||||
startActivity(intentToInvoke);
|
||||
finish();
|
||||
} else if (!TextUtils.isEmpty(query)) {
|
||||
Utils.debugLog(TAG, "FDroid launched via search link for '" + query + "'");
|
||||
performSearch(query);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkForAddRepoIntent(Intent intent) {
|
||||
// Don't handle the intent after coming back to this view (e.g. after hitting the back button)
|
||||
// http://stackoverflow.com/a/14820849
|
||||
if (!intent.hasExtra(ADD_REPO_INTENT_HANDLED)) {
|
||||
intent.putExtra(ADD_REPO_INTENT_HANDLED, true);
|
||||
NewRepoConfig parser = new NewRepoConfig(this, intent);
|
||||
if (parser.isValidRepo()) {
|
||||
if (parser.isFromSwap()) {
|
||||
Intent confirmIntent = new Intent(this, SwapWorkflowActivity.class);
|
||||
confirmIntent.putExtra(SwapWorkflowActivity.EXTRA_CONFIRM, true);
|
||||
confirmIntent.setData(intent.getData());
|
||||
startActivityForResult(confirmIntent, REQUEST_SWAP);
|
||||
} else {
|
||||
startActivity(new Intent(ACTION_ADD_REPO, intent.getData(), this, ManageReposActivity.class));
|
||||
}
|
||||
} else if (parser.getErrorMessage() != null) {
|
||||
Toast.makeText(this, parser.getErrorMessage(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
getTabManager().onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.main, menu);
|
||||
if (fdroidApp.bluetoothAdapter == null) {
|
||||
// ignore on devices without Bluetooth
|
||||
MenuItem btItem = menu.findItem(R.id.action_bluetooth_apk);
|
||||
btItem.setVisible(false);
|
||||
}
|
||||
|
||||
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
|
||||
searchMenuItem = menu.findItem(R.id.action_search);
|
||||
searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
|
||||
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
|
||||
// LayoutParams.MATCH_PARENT does not work, use a big value instead
|
||||
searchView.setMaxWidth(1000000);
|
||||
searchView.setOnQueryTextListener(this);
|
||||
|
||||
// If we were asked to execute a search before getting around to building the options
|
||||
// menu, then we should deal with that now that the options menu is all sorted out.
|
||||
if (pendingSearchQuery != null) {
|
||||
performSearch(pendingSearchQuery);
|
||||
pendingSearchQuery = null;
|
||||
}
|
||||
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
|
||||
case R.id.action_update_repo:
|
||||
UpdateService.updateNow(this);
|
||||
return true;
|
||||
|
||||
case R.id.action_manage_repos:
|
||||
startActivity(new Intent(this, ManageReposActivity.class));
|
||||
return true;
|
||||
|
||||
case R.id.action_settings:
|
||||
Intent prefs = new Intent(getBaseContext(), PreferencesActivity.class);
|
||||
startActivityForResult(prefs, REQUEST_PREFS);
|
||||
return true;
|
||||
|
||||
case R.id.action_swap:
|
||||
startActivity(new Intent(this, SwapWorkflowActivity.class));
|
||||
return true;
|
||||
|
||||
case R.id.action_bluetooth_apk:
|
||||
/*
|
||||
* If Bluetooth has not been enabled/turned on, then enabling
|
||||
* device discoverability will automatically enable Bluetooth
|
||||
*/
|
||||
Intent discoverBt = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
|
||||
discoverBt.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 121);
|
||||
startActivityForResult(discoverBt, REQUEST_ENABLE_BLUETOOTH);
|
||||
// if this is successful, the Bluetooth transfer is started
|
||||
return true;
|
||||
|
||||
case R.id.action_about:
|
||||
View view = LayoutInflater.from(this).inflate(R.layout.about, null);
|
||||
|
||||
String versionName = Utils.getVersionName(this);
|
||||
if (versionName != null) {
|
||||
((TextView) view.findViewById(R.id.version)).setText(versionName);
|
||||
}
|
||||
|
||||
AlertDialog alrt = new AlertDialog.Builder(this).setView(view).create();
|
||||
alrt.setTitle(R.string.about_title);
|
||||
alrt.setButton(AlertDialog.BUTTON_NEGATIVE, getString(R.string.ok),
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
}
|
||||
});
|
||||
alrt.show();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
|
||||
switch (requestCode) {
|
||||
case REQUEST_PREFS:
|
||||
// The automatic update settings may have changed, so reschedule (or
|
||||
// unschedule) the service accordingly. It's cheap, so no need to
|
||||
// check if the particular setting has actually been changed.
|
||||
UpdateService.schedule(getBaseContext());
|
||||
|
||||
if ((resultCode & PreferencesActivity.RESULT_RESTART) != 0) {
|
||||
((FDroidApp) getApplication()).reloadTheme();
|
||||
final Intent intent = getIntent();
|
||||
overridePendingTransition(0, 0);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||
finish();
|
||||
overridePendingTransition(0, 0);
|
||||
startActivity(intent);
|
||||
}
|
||||
break;
|
||||
case REQUEST_ENABLE_BLUETOOTH:
|
||||
fdroidApp.sendViaBluetooth(this, resultCode, "org.fdroid.fdroid");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void createViews() {
|
||||
viewPager = (ViewPager) findViewById(R.id.main_pager);
|
||||
adapter = new AppListFragmentPagerAdapter(this);
|
||||
viewPager.setAdapter(adapter);
|
||||
viewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
getTabManager().selectTab(position);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private TabManager getTabManager() {
|
||||
if (tabManager == null) {
|
||||
tabManager = new TabManager(this, viewPager);
|
||||
}
|
||||
return tabManager;
|
||||
}
|
||||
|
||||
private void refreshUpdateTabLabel() {
|
||||
getTabManager().refreshTabLabel(TabManager.INDEX_CAN_UPDATE);
|
||||
getTabManager().refreshTabLabel(TabManager.INDEX_INSTALLED);
|
||||
}
|
||||
|
||||
public void removeNotification(int id) {
|
||||
NotificationManager nMgr = (NotificationManager) getBaseContext()
|
||||
.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
nMgr.cancel(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
searchView.clearFocus();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String newText) {
|
||||
adapter.updateSearchQuery(newText);
|
||||
return true;
|
||||
}
|
||||
|
||||
private class AppObserver extends ContentObserver {
|
||||
|
||||
AppObserver() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange, Uri uri) {
|
||||
FDroid.this.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
refreshUpdateTabLabel();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
onChange(selfChange, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -312,7 +312,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
|
||||
}
|
||||
|
||||
/**
|
||||
* This is cached as it is called several times inside the AppListAdapter.
|
||||
* This is cached as it is called several times inside app list adapters.
|
||||
* Providing it here means the shared preferences file only needs to be
|
||||
* read once, and we will keep our copy up to date by listening to changes
|
||||
* in PREF_ROOTED.
|
||||
@ -326,7 +326,7 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
|
||||
}
|
||||
|
||||
/**
|
||||
* This is cached as it is called several times inside the AppListAdapter.
|
||||
* This is cached as it is called several times inside app list adapters.
|
||||
* Providing it here means the shared preferences file only needs to be
|
||||
* read once, and we will keep our copy up to date by listening to changes
|
||||
* in PREF_HIDE_ANTI_FEATURE_APPS.
|
||||
|
@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-12 Ciaran Gultnieks, ciaran@ciarang.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package org.fdroid.fdroid;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import org.fdroid.fdroid.views.fragments.PreferencesFragment;
|
||||
|
||||
public class PreferencesActivity extends AppCompatActivity {
|
||||
|
||||
public static final int RESULT_RESTART = 4;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
((FDroidApp) getApplication()).applyTheme(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
FragmentManager fm = getSupportFragmentManager();
|
||||
if (fm.findFragmentById(android.R.id.content) == null) {
|
||||
// Need to set a dummy view (which will get overridden by the fragment manager
|
||||
// below) so that we can call setContentView(). This is a work around for
|
||||
// a (bug?) thing in 3.0, 3.1 which requires setContentView to be invoked before
|
||||
// the actionbar is played with:
|
||||
// http://blog.perpetumdesign.com/2011/08/strange-case-of-dr-action-and-mr-bar.html
|
||||
if (Build.VERSION.SDK_INT >= 11 && Build.VERSION.SDK_INT <= 13) {
|
||||
setContentView(new LinearLayout(this));
|
||||
}
|
||||
|
||||
PreferencesFragment preferencesFragment = new PreferencesFragment();
|
||||
fm.beginTransaction()
|
||||
.add(android.R.id.content, preferencesFragment)
|
||||
.commit();
|
||||
}
|
||||
|
||||
// Actionbar cannot be accessed until after setContentView (on 3.0 and 3.1 devices)
|
||||
// see: http://blog.perpetumdesign.com/2011/08/strange-case-of-dr-action-and-mr-bar.html
|
||||
// for reason why.
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
NavUtils.navigateUpFromSameTask(this);
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package org.fdroid.fdroid.compat;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.os.Build;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ArrayAdapterCompat {
|
||||
|
||||
@TargetApi(11)
|
||||
public static <T> void addAll(ArrayAdapter<T> adapter, List<T> list) {
|
||||
if (Build.VERSION.SDK_INT >= 11) {
|
||||
adapter.addAll(list);
|
||||
} else {
|
||||
for (T category : list) {
|
||||
adapter.add(category);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,154 +0,0 @@
|
||||
package org.fdroid.fdroid.compat;
|
||||
|
||||
import android.content.res.Configuration;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import org.fdroid.fdroid.FDroid;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TabManager {
|
||||
|
||||
public static final int INDEX_AVAILABLE = 0;
|
||||
public static final int INDEX_INSTALLED = 1;
|
||||
public static final int INDEX_CAN_UPDATE = 2;
|
||||
public static final int INDEX_COUNT = 3;
|
||||
|
||||
private final ViewPager pager;
|
||||
private final FDroid parent;
|
||||
private final ActionBar actionBar;
|
||||
private Spinner actionBarSpinner;
|
||||
|
||||
// Used to make sure we only search for the action bar spinner once
|
||||
// in each orientation.
|
||||
private boolean dirtyConfig = true;
|
||||
|
||||
public TabManager(FDroid parent, ViewPager pager) {
|
||||
actionBar = parent.getSupportActionBar();
|
||||
this.parent = parent;
|
||||
this.pager = pager;
|
||||
}
|
||||
|
||||
private CharSequence getLabel(int index) {
|
||||
return pager.getAdapter().getPageTitle(index);
|
||||
}
|
||||
|
||||
private void removeNotification(int id) {
|
||||
parent.removeNotification(id);
|
||||
}
|
||||
|
||||
public void createTabs() {
|
||||
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
|
||||
for (int i = 0; i < pager.getAdapter().getCount(); i++) {
|
||||
CharSequence label = pager.getAdapter().getPageTitle(i);
|
||||
actionBar.addTab(
|
||||
actionBar.newTab()
|
||||
.setText(label)
|
||||
.setTabListener(new ActionBar.TabListener() {
|
||||
@Override
|
||||
public void onTabSelected(ActionBar.Tab tab,
|
||||
FragmentTransaction ft) {
|
||||
int pos = tab.getPosition();
|
||||
pager.setCurrentItem(pos);
|
||||
if (pos == INDEX_CAN_UPDATE) {
|
||||
removeNotification(1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void selectTab(int index) {
|
||||
actionBar.setSelectedNavigationItem(index);
|
||||
Spinner actionBarSpinner = getActionBarSpinner();
|
||||
if (actionBarSpinner != null) {
|
||||
actionBarSpinner.setSelection(index);
|
||||
}
|
||||
if (index == INDEX_CAN_UPDATE) {
|
||||
removeNotification(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshTabLabel(int index) {
|
||||
CharSequence text = getLabel(index);
|
||||
actionBar.getTabAt(index).setText(text);
|
||||
}
|
||||
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
dirtyConfig = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traversing the view hierarchy is a non-trivial task, and takes between 0 and 3
|
||||
* milliseconds on my SGS i9000 (Android 4.2).
|
||||
* As such, we lazily try to identify the spinner, and only search once per
|
||||
* orientation change. Once we've found it, we stop looking.
|
||||
*/
|
||||
private Spinner getActionBarSpinner() {
|
||||
if (actionBarSpinner == null && dirtyConfig) {
|
||||
dirtyConfig = false;
|
||||
actionBarSpinner = findActionBarSpinner();
|
||||
}
|
||||
return actionBarSpinner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dodgey hack to fix issue 231, based on the solution at
|
||||
* http://stackoverflow.com/a/13353493
|
||||
* Turns out that there is a bug in Android where the Spinner in the action
|
||||
* bar (which represents the tabs if there is not enough space) is not
|
||||
* updated when we call setSelectedNavigationItem(), and they don't expose
|
||||
* the spinner via the API. So we go on a merry hunt for all spinners in
|
||||
* our view, and find the first one with an id of -1.
|
||||
*
|
||||
* This is because the view hierarchy dictates that the action bar comes
|
||||
* before everything below it when traversing children, and also our spinner
|
||||
* on the first view (for the app categories) has an id, whereas the
|
||||
* actionbar one doesn't. If that changes in future releases of android,
|
||||
* then we will need to update the findListNavigationSpinner() method.
|
||||
*/
|
||||
private Spinner findActionBarSpinner() {
|
||||
View rootView = parent.findViewById(android.R.id.content).getRootView();
|
||||
List<Spinner> spinners = traverseViewChildren((ViewGroup) rootView);
|
||||
return findListNavigationSpinner(spinners);
|
||||
}
|
||||
|
||||
private Spinner findListNavigationSpinner(List<Spinner> spinners) {
|
||||
Spinner spinner = null;
|
||||
if (spinners.size() > 0) {
|
||||
Spinner first = spinners.get(0);
|
||||
if (first.getId() == -1) {
|
||||
spinner = first;
|
||||
}
|
||||
}
|
||||
return spinner;
|
||||
}
|
||||
|
||||
private List<Spinner> traverseViewChildren(ViewGroup parent) {
|
||||
List<Spinner> spinners = new ArrayList<>();
|
||||
for (int i = 0; i < parent.getChildCount(); i++) {
|
||||
View child = parent.getChildAt(i);
|
||||
if (child instanceof Spinner) {
|
||||
spinners.add((Spinner) child);
|
||||
} else if (child instanceof ViewGroup) {
|
||||
spinners.addAll(traverseViewChildren((ViewGroup) child));
|
||||
}
|
||||
}
|
||||
return spinners;
|
||||
}
|
||||
}
|
@ -53,20 +53,6 @@ public class AppProvider extends FDroidProvider {
|
||||
|
||||
private Helper() { }
|
||||
|
||||
public static int count(Context context, Uri uri) {
|
||||
final String[] projection = {Cols._COUNT};
|
||||
Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
|
||||
int count = 0;
|
||||
if (cursor != null) {
|
||||
if (cursor.getCount() == 1) {
|
||||
cursor.moveToFirst();
|
||||
count = cursor.getInt(0);
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static List<App> all(ContentResolver resolver) {
|
||||
return all(resolver, Cols.ALL);
|
||||
}
|
||||
@ -367,8 +353,6 @@ public class AppProvider extends FDroidProvider {
|
||||
private static final String PATH_INSTALLED = "installed";
|
||||
private static final String PATH_CAN_UPDATE = "canUpdate";
|
||||
private static final String PATH_SEARCH = "search";
|
||||
private static final String PATH_SEARCH_INSTALLED = "searchInstalled";
|
||||
private static final String PATH_SEARCH_CAN_UPDATE = "searchCanUpdate";
|
||||
private static final String PATH_SEARCH_REPO = "searchRepo";
|
||||
protected static final String PATH_APPS = "apps";
|
||||
protected static final String PATH_SPECIFIC_APP = "app";
|
||||
@ -389,9 +373,7 @@ public class AppProvider extends FDroidProvider {
|
||||
private static final int CALC_SUGGESTED_APKS = CATEGORY + 1;
|
||||
private static final int REPO = CALC_SUGGESTED_APKS + 1;
|
||||
private static final int SEARCH_REPO = REPO + 1;
|
||||
private static final int SEARCH_INSTALLED = SEARCH_REPO + 1;
|
||||
private static final int SEARCH_CAN_UPDATE = SEARCH_INSTALLED + 1;
|
||||
private static final int HIGHEST_PRIORITY = SEARCH_CAN_UPDATE + 1;
|
||||
private static final int HIGHEST_PRIORITY = SEARCH_REPO + 1;
|
||||
private static final int CALC_PREFERRED_METADATA = HIGHEST_PRIORITY + 1;
|
||||
private static final int TOP_FROM_CATEGORY = CALC_PREFERRED_METADATA + 1;
|
||||
|
||||
@ -402,8 +384,6 @@ public class AppProvider extends FDroidProvider {
|
||||
MATCHER.addURI(getAuthority(), PATH_CATEGORY + "/*", CATEGORY);
|
||||
MATCHER.addURI(getAuthority(), PATH_SEARCH + "/*/*", SEARCH_TEXT_AND_CATEGORIES);
|
||||
MATCHER.addURI(getAuthority(), PATH_SEARCH + "/*", SEARCH_TEXT);
|
||||
MATCHER.addURI(getAuthority(), PATH_SEARCH_INSTALLED + "/*", SEARCH_INSTALLED);
|
||||
MATCHER.addURI(getAuthority(), PATH_SEARCH_CAN_UPDATE + "/*", SEARCH_CAN_UPDATE);
|
||||
MATCHER.addURI(getAuthority(), PATH_SEARCH_REPO + "/*/*", SEARCH_REPO);
|
||||
MATCHER.addURI(getAuthority(), PATH_REPO + "/#", REPO);
|
||||
MATCHER.addURI(getAuthority(), PATH_CAN_UPDATE, CAN_UPDATE);
|
||||
@ -456,10 +436,6 @@ public class AppProvider extends FDroidProvider {
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Uri getContentUri(App app) {
|
||||
return getContentUri(app.packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AppProvider.Helper#findSpecificApp(ContentResolver, String, long, String[]) for details
|
||||
* of why you should usually prefer {@link AppProvider#getHighestPriorityMetadataUri(String)} to
|
||||
@ -481,10 +457,6 @@ public class AppProvider extends FDroidProvider {
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Uri getContentUri(String packageName) {
|
||||
return Uri.withAppendedPath(getContentUri(), packageName);
|
||||
}
|
||||
|
||||
public static Uri getSearchUri(String query, @Nullable String category) {
|
||||
if (TextUtils.isEmpty(query) && TextUtils.isEmpty(category)) {
|
||||
// Return all the things for an empty search.
|
||||
@ -504,22 +476,6 @@ public class AppProvider extends FDroidProvider {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public static Uri getSearchInstalledUri(String query) {
|
||||
return getContentUri()
|
||||
.buildUpon()
|
||||
.appendPath(PATH_SEARCH_INSTALLED)
|
||||
.appendPath(query)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Uri getSearchCanUpdateUri(String query) {
|
||||
return getContentUri()
|
||||
.buildUpon()
|
||||
.appendPath(PATH_SEARCH_CAN_UPDATE)
|
||||
.appendPath(query)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Uri getSearchUri(Repo repo, String query) {
|
||||
return getContentUri().buildUpon()
|
||||
.appendPath(PATH_SEARCH_REPO)
|
||||
@ -761,16 +717,6 @@ public class AppProvider extends FDroidProvider {
|
||||
includeSwap = false;
|
||||
break;
|
||||
|
||||
case SEARCH_INSTALLED:
|
||||
selection = querySearch(uri.getLastPathSegment()).add(queryInstalled());
|
||||
includeSwap = false;
|
||||
break;
|
||||
|
||||
case SEARCH_CAN_UPDATE:
|
||||
selection = querySearch(uri.getLastPathSegment()).add(queryCanUpdate());
|
||||
includeSwap = false;
|
||||
break;
|
||||
|
||||
case SEARCH_REPO:
|
||||
selection = selection
|
||||
.add(querySearch(pathSegments.get(2)))
|
||||
|
@ -1,6 +1,5 @@
|
||||
package org.fdroid.fdroid.data;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.UriMatcher;
|
||||
@ -8,17 +7,12 @@ import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.data.Schema.CatJoinTable;
|
||||
import org.fdroid.fdroid.data.Schema.CategoryTable;
|
||||
import org.fdroid.fdroid.data.Schema.AppMetadataTable;
|
||||
import org.fdroid.fdroid.data.Schema.PackageTable;
|
||||
import org.fdroid.fdroid.data.Schema.CategoryTable.Cols;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class CategoryProvider extends FDroidProvider {
|
||||
|
||||
public static final class Helper {
|
||||
@ -53,47 +47,6 @@ public class CategoryProvider extends FDroidProvider {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static String getCategoryAll(Context context) {
|
||||
return context.getString(R.string.category_All);
|
||||
}
|
||||
|
||||
public static String getCategoryWhatsNew(Context context) {
|
||||
return context.getString(R.string.category_Whats_New);
|
||||
}
|
||||
|
||||
public static String getCategoryRecentlyUpdated(Context context) {
|
||||
return context.getString(R.string.category_Recently_Updated);
|
||||
}
|
||||
|
||||
public static List<String> categories(Context context) {
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final Uri uri = CategoryProvider.getAllCategories();
|
||||
final String[] projection = {Cols.NAME};
|
||||
final Cursor cursor = resolver.query(uri, projection, null, null, null);
|
||||
List<String> categories = new ArrayList<>(30);
|
||||
if (cursor != null) {
|
||||
if (cursor.getCount() > 0) {
|
||||
cursor.moveToFirst();
|
||||
while (!cursor.isAfterLast()) {
|
||||
final String name = cursor.getString(0);
|
||||
categories.add(name);
|
||||
cursor.moveToNext();
|
||||
}
|
||||
}
|
||||
cursor.close();
|
||||
}
|
||||
Collections.sort(categories);
|
||||
|
||||
// Populate the category list with the real categories, and the
|
||||
// locally generated meta-categories for "What's New", "Recently
|
||||
// Updated" and "All"...
|
||||
categories.add(0, getCategoryAll(context));
|
||||
categories.add(0, getCategoryRecentlyUpdated(context));
|
||||
categories.add(0, getCategoryWhatsNew(context));
|
||||
|
||||
return categories;
|
||||
}
|
||||
}
|
||||
|
||||
private class Query extends QueryBuilder {
|
||||
|
@ -415,7 +415,7 @@ public class AppSecurityPermissions {
|
||||
|| ((pInfo.protectionLevel & PermissionInfo.PROTECTION_FLAG_PRE23) != 0);
|
||||
|
||||
// Dangerous and normal permissions are always shown to the user
|
||||
// this is matches the permission list in AppDetails
|
||||
// this is matches the permission list in AppDetails2
|
||||
if (isNormal || isDangerous) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1,137 +0,0 @@
|
||||
package org.fdroid.fdroid.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.support.v4.widget.CursorAdapter;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.ImageLoader;
|
||||
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.Utils;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
|
||||
public abstract class AppListAdapter extends CursorAdapter {
|
||||
|
||||
private LayoutInflater inflater;
|
||||
private DisplayImageOptions displayImageOptions;
|
||||
private String upgradeFromTo;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public AppListAdapter(Context context, Cursor c) {
|
||||
super(context, c);
|
||||
init(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return mDataValid && super.isEmpty();
|
||||
}
|
||||
|
||||
public AppListAdapter(Context context, Cursor c, boolean autoRequery) {
|
||||
super(context, c, autoRequery);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public AppListAdapter(Context context, Cursor c, int flags) {
|
||||
super(context, c, flags);
|
||||
init(context);
|
||||
}
|
||||
|
||||
private void init(Context context) {
|
||||
inflater = (LayoutInflater) context.getSystemService(
|
||||
Context.LAYOUT_INFLATER_SERVICE);
|
||||
displayImageOptions = Utils.getImageLoadingOptions().build();
|
||||
upgradeFromTo = context.getResources().getString(R.string.upgrade_from_to);
|
||||
}
|
||||
|
||||
protected abstract boolean showStatusUpdate();
|
||||
|
||||
protected abstract boolean showStatusInstalled();
|
||||
|
||||
private static class ViewHolder {
|
||||
TextView name;
|
||||
TextView summary;
|
||||
TextView status;
|
||||
TextView license;
|
||||
ImageView icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View newView(Context context, Cursor cursor, ViewGroup parent) {
|
||||
View view = inflater.inflate(R.layout.applistitem, parent, false);
|
||||
|
||||
ViewHolder holder = new ViewHolder();
|
||||
holder.name = (TextView) view.findViewById(R.id.name);
|
||||
holder.summary = (TextView) view.findViewById(R.id.summary);
|
||||
holder.status = (TextView) view.findViewById(R.id.status);
|
||||
holder.license = (TextView) view.findViewById(R.id.license);
|
||||
holder.icon = (ImageView) view.findViewById(R.id.icon);
|
||||
view.setTag(holder);
|
||||
|
||||
setupView(view, cursor, holder);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor) {
|
||||
ViewHolder holder = (ViewHolder) view.getTag();
|
||||
setupView(view, cursor, holder);
|
||||
}
|
||||
|
||||
private void setupView(View view, Cursor cursor, ViewHolder holder) {
|
||||
final App app = new App(cursor);
|
||||
|
||||
holder.name.setText(app.name);
|
||||
holder.summary.setText(app.summary);
|
||||
|
||||
ImageLoader.getInstance().displayImage(app.iconUrl, holder.icon,
|
||||
displayImageOptions);
|
||||
|
||||
holder.status.setText(getVersionInfo(app));
|
||||
holder.license.setText(app.license);
|
||||
|
||||
// Disable it all if it isn't compatible...
|
||||
final View[] views = {
|
||||
view,
|
||||
holder.status,
|
||||
holder.summary,
|
||||
holder.license,
|
||||
holder.name,
|
||||
};
|
||||
|
||||
for (View v : views) {
|
||||
v.setEnabled(app.compatible && !app.isFiltered());
|
||||
}
|
||||
}
|
||||
|
||||
private String getVersionInfo(App app) {
|
||||
|
||||
if (app.suggestedVersionCode <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!app.isInstalled()) {
|
||||
return app.getSuggestedVersionName();
|
||||
}
|
||||
|
||||
final String installedVersionString = app.installedVersionName;
|
||||
|
||||
if (app.canAndWantToUpdate(mContext) && showStatusUpdate()) {
|
||||
return String.format(upgradeFromTo,
|
||||
installedVersionString, app.getSuggestedVersionName());
|
||||
}
|
||||
|
||||
if (app.installedVersionCode > 0 && showStatusInstalled()) {
|
||||
return installedVersionString + " ✔";
|
||||
}
|
||||
|
||||
return installedVersionString;
|
||||
}
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
package org.fdroid.fdroid.views;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentPagerAdapter;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.fdroid.fdroid.FDroid;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.compat.TabManager;
|
||||
import org.fdroid.fdroid.data.AppProvider;
|
||||
import org.fdroid.fdroid.views.fragments.AppListFragment;
|
||||
import org.fdroid.fdroid.views.fragments.AvailableAppsFragment;
|
||||
import org.fdroid.fdroid.views.fragments.CanUpdateAppsFragment;
|
||||
import org.fdroid.fdroid.views.fragments.InstalledAppsFragment;
|
||||
|
||||
/**
|
||||
* Used by the FDroid activity in conjunction with its ViewPager to support
|
||||
* swiping of tabs for both old devices (< 3.0) and new devices.
|
||||
*
|
||||
* See http://stackoverflow.com/a/15261142 for how to obtain references
|
||||
* to fragments in order to update them in response to search queries.
|
||||
*/
|
||||
public class AppListFragmentPagerAdapter extends FragmentPagerAdapter {
|
||||
|
||||
@NonNull private final FDroid parent;
|
||||
@Nullable private String searchQuery;
|
||||
|
||||
private final AppListFragment[] registeredFragments = new AppListFragment[TabManager.INDEX_COUNT];
|
||||
|
||||
public AppListFragmentPagerAdapter(@NonNull FDroid parent) {
|
||||
super(parent.getSupportFragmentManager());
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object instantiateItem(ViewGroup container, int position) {
|
||||
AppListFragment fragment = (AppListFragment) super.instantiateItem(container, position);
|
||||
fragment.updateSearchQuery(searchQuery);
|
||||
registeredFragments[position] = fragment;
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem(ViewGroup container, int position, Object object) {
|
||||
registeredFragments[position] = null;
|
||||
super.destroyItem(container, position, object);
|
||||
}
|
||||
|
||||
private String getInstalledTabTitle() {
|
||||
int installedCount = AppProvider.Helper.count(parent, AppProvider.getInstalledUri());
|
||||
return parent.getString(R.string.tab_installed_apps_count, installedCount);
|
||||
}
|
||||
|
||||
private String getUpdateTabTitle() {
|
||||
int updateCount = AppProvider.Helper.count(parent, AppProvider.getCanUpdateUri());
|
||||
return parent.getString(R.string.tab_updates_count, updateCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changing the search query is quite an expensive operation, so this does some rudimentary
|
||||
* checking to see if the two queries are meaningfully different. At present, it trims the
|
||||
* strings and does a case insensitive comparison.
|
||||
*/
|
||||
private boolean isSearchQuerySame(String newQuery) {
|
||||
String oldValueTrimmed = searchQuery == null ? "" : searchQuery.trim();
|
||||
String newValueTrimmed = newQuery == null ? "" : newQuery.trim();
|
||||
return oldValueTrimmed.equalsIgnoreCase(newValueTrimmed);
|
||||
}
|
||||
|
||||
public void updateSearchQuery(@Nullable String query) {
|
||||
if (isSearchQuerySame(query)) {
|
||||
return;
|
||||
}
|
||||
|
||||
searchQuery = query;
|
||||
for (AppListFragment fragment : registeredFragments) {
|
||||
if (fragment != null) {
|
||||
fragment.updateSearchQuery(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Fragment getItem(int i) {
|
||||
switch (i) {
|
||||
case TabManager.INDEX_AVAILABLE:
|
||||
return new AvailableAppsFragment();
|
||||
case TabManager.INDEX_INSTALLED:
|
||||
return new InstalledAppsFragment();
|
||||
default:
|
||||
return new CanUpdateAppsFragment();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return TabManager.INDEX_COUNT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPageTitle(int i) {
|
||||
switch (i) {
|
||||
case TabManager.INDEX_AVAILABLE:
|
||||
return parent.getString(R.string.tab_available_apps);
|
||||
case TabManager.INDEX_INSTALLED:
|
||||
return getInstalledTabTitle();
|
||||
case TabManager.INDEX_CAN_UPDATE:
|
||||
return getUpdateTabTitle();
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package org.fdroid.fdroid.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.os.Build;
|
||||
|
||||
public class AvailableAppListAdapter extends AppListAdapter {
|
||||
|
||||
public static AvailableAppListAdapter create(Context context, Cursor cursor, int flags) {
|
||||
if (Build.VERSION.SDK_INT >= 11) {
|
||||
return new AvailableAppListAdapter(context, cursor, flags);
|
||||
}
|
||||
return new AvailableAppListAdapter(context, cursor);
|
||||
}
|
||||
|
||||
private AvailableAppListAdapter(Context context, Cursor c) {
|
||||
super(context, c);
|
||||
}
|
||||
|
||||
public AvailableAppListAdapter(Context context, Cursor c, boolean autoRequery) {
|
||||
super(context, c, autoRequery);
|
||||
}
|
||||
|
||||
private AvailableAppListAdapter(Context context, Cursor c, int flags) {
|
||||
super(context, c, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean showStatusUpdate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean showStatusInstalled() {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package org.fdroid.fdroid.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.os.Build;
|
||||
|
||||
public class CanUpdateAppListAdapter extends AppListAdapter {
|
||||
|
||||
public static CanUpdateAppListAdapter create(Context context, Cursor cursor, int flags) {
|
||||
if (Build.VERSION.SDK_INT >= 11) {
|
||||
return new CanUpdateAppListAdapter(context, cursor, flags);
|
||||
}
|
||||
return new CanUpdateAppListAdapter(context, cursor);
|
||||
}
|
||||
|
||||
private CanUpdateAppListAdapter(Context context, Cursor c) {
|
||||
super(context, c);
|
||||
}
|
||||
|
||||
public CanUpdateAppListAdapter(Context context, Cursor c, boolean autoRequery) {
|
||||
super(context, c, autoRequery);
|
||||
}
|
||||
|
||||
private CanUpdateAppListAdapter(Context context, Cursor c, int flags) {
|
||||
super(context, c, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean showStatusUpdate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean showStatusInstalled() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package org.fdroid.fdroid.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.os.Build;
|
||||
|
||||
public class InstalledAppListAdapter extends AppListAdapter {
|
||||
|
||||
public static InstalledAppListAdapter create(Context context, Cursor cursor, int flags) {
|
||||
if (Build.VERSION.SDK_INT >= 11) {
|
||||
return new InstalledAppListAdapter(context, cursor, flags);
|
||||
}
|
||||
return new InstalledAppListAdapter(context, cursor);
|
||||
}
|
||||
|
||||
private InstalledAppListAdapter(Context context, Cursor c) {
|
||||
super(context, c);
|
||||
}
|
||||
|
||||
public InstalledAppListAdapter(Context context, Cursor c, boolean autoRequery) {
|
||||
super(context, c, autoRequery);
|
||||
}
|
||||
|
||||
private InstalledAppListAdapter(Context context, Cursor c, int flags) {
|
||||
super(context, c, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean showStatusUpdate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean showStatusInstalled() {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -147,7 +147,7 @@ public class RepoDetailsActivity extends ActionBarActivity {
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver,
|
||||
new IntentFilter(UpdateService.LOCAL_ACTION_STATUS));
|
||||
|
||||
// FDroid.java and AppDetails set different NFC actions, so reset here
|
||||
// FDroid.java and AppDetails2 set different NFC actions, so reset here
|
||||
setNfc();
|
||||
processIntent(getIntent());
|
||||
}
|
||||
|
@ -1,240 +0,0 @@
|
||||
package org.fdroid.fdroid.views.fragments;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.ActivityOptionsCompat;
|
||||
import android.support.v4.app.ListFragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.util.Pair;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.fdroid.fdroid.AppDetails;
|
||||
import org.fdroid.fdroid.AppDetails2;
|
||||
import org.fdroid.fdroid.Preferences;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.UpdateService;
|
||||
import org.fdroid.fdroid.Utils;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
import org.fdroid.fdroid.data.Schema.AppMetadataTable;
|
||||
import org.fdroid.fdroid.views.AppListAdapter;
|
||||
|
||||
public abstract class AppListFragment extends ListFragment implements
|
||||
AdapterView.OnItemClickListener,
|
||||
AdapterView.OnItemLongClickListener,
|
||||
Preferences.ChangeListener,
|
||||
LoaderManager.LoaderCallbacks<Cursor> {
|
||||
|
||||
private static final String TAG = "AppListFragment";
|
||||
|
||||
private static final int REQUEST_APPDETAILS = 0;
|
||||
|
||||
private static final String[] APP_PROJECTION = {
|
||||
AppMetadataTable.Cols._ID, // Required for cursor loader to work.
|
||||
AppMetadataTable.Cols.Package.PACKAGE_NAME,
|
||||
AppMetadataTable.Cols.NAME,
|
||||
AppMetadataTable.Cols.SUMMARY,
|
||||
AppMetadataTable.Cols.IS_COMPATIBLE,
|
||||
AppMetadataTable.Cols.LICENSE,
|
||||
AppMetadataTable.Cols.ICON,
|
||||
AppMetadataTable.Cols.ICON_URL,
|
||||
AppMetadataTable.Cols.InstalledApp.VERSION_CODE,
|
||||
AppMetadataTable.Cols.InstalledApp.VERSION_NAME,
|
||||
AppMetadataTable.Cols.SuggestedApk.VERSION_NAME,
|
||||
AppMetadataTable.Cols.SUGGESTED_VERSION_CODE,
|
||||
AppMetadataTable.Cols.REQUIREMENTS, // Needed for filtering apps that require root.
|
||||
AppMetadataTable.Cols.ANTI_FEATURES, // Needed for filtering apps that require anti-features.
|
||||
};
|
||||
|
||||
private static final String APP_SORT = AppMetadataTable.Cols.NAME;
|
||||
|
||||
private AppListAdapter appAdapter;
|
||||
|
||||
@Nullable private String searchQuery;
|
||||
|
||||
protected abstract AppListAdapter getAppListAdapter();
|
||||
|
||||
protected abstract String getFromTitle();
|
||||
|
||||
protected abstract Uri getDataUri();
|
||||
|
||||
protected abstract Uri getDataUri(String query);
|
||||
|
||||
protected abstract int getEmptyMessage();
|
||||
|
||||
protected abstract int getNoSearchResultsMessage();
|
||||
|
||||
/**
|
||||
* Subclasses can choose to do different things based on when a user begins searching.
|
||||
* For example, the "Available" tab chooses to hide its category spinner to make it clear
|
||||
* that it is searching all apps, not the current category.
|
||||
* NOTE: This will get called <em>multiple</em> times, every time the user changes the
|
||||
* search query.
|
||||
*/
|
||||
void onSearch() {
|
||||
// Do nothing by default.
|
||||
}
|
||||
|
||||
/**
|
||||
* Alerts the child class that the user is no longer performing a search.
|
||||
* This is triggered every time the search query is blank.
|
||||
*
|
||||
* @see AppListFragment#onSearch()
|
||||
*/
|
||||
protected void onSearchStopped() {
|
||||
// Do nothing by default.
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function to set empty view text which should be different
|
||||
* depending on whether search is active or not.
|
||||
*/
|
||||
private void setEmptyText(int resId) {
|
||||
((TextView) getListView().getEmptyView()).setText(resId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
// Can't do this in the onCreate view, because "onCreateView" which
|
||||
// returns the list view is "called between onCreate and
|
||||
// onActivityCreated" according to the docs.
|
||||
getListView().setOnItemClickListener(this);
|
||||
getListView().setOnItemLongClickListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
//Starts a new or restarts an existing Loader in this manager
|
||||
getLoaderManager().initLoader(0, null, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
appAdapter = getAppListAdapter();
|
||||
|
||||
if (appAdapter.getCount() == 0) {
|
||||
updateEmptyRepos();
|
||||
}
|
||||
|
||||
setListAdapter(appAdapter);
|
||||
}
|
||||
|
||||
/**
|
||||
* The first time the app is run, we will have an empty app list.
|
||||
* If this is the case, we will attempt to update with the default repo.
|
||||
* However, if we have tried this at least once, then don't try to do
|
||||
* it automatically again, because the repos or internet connection may
|
||||
* be bad.
|
||||
*/
|
||||
private boolean updateEmptyRepos() {
|
||||
Preferences prefs = Preferences.get();
|
||||
if (!prefs.hasTriedEmptyUpdate()) {
|
||||
Utils.debugLog(TAG, "Empty app list, and we haven't done an update yet. Forcing repo update.");
|
||||
prefs.setTriedEmptyUpdate(true);
|
||||
UpdateService.updateNow(getActivity());
|
||||
return true;
|
||||
}
|
||||
Utils.debugLog(TAG, "Empty app list, but it looks like we've had an update previously. Will not force repo update.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
showItemDetails(view, position, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
showItemDetails(view, position, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void showItemDetails(View view, int position, boolean useNewDetailsActivity) {
|
||||
// Cursor is null in the swap list when touching the first item.
|
||||
Cursor cursor = (Cursor) getListView().getItemAtPosition(position);
|
||||
if (cursor != null) {
|
||||
final App app = new App(cursor);
|
||||
Intent intent = getAppDetailsIntent(useNewDetailsActivity);
|
||||
intent.putExtra(AppDetails2.EXTRA_APPID, app.packageName);
|
||||
intent.putExtra(AppDetails.EXTRA_FROM, getFromTitle());
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
Pair<View, String> iconTransitionPair = Pair.create(view.findViewById(R.id.icon),
|
||||
getString(R.string.transition_app_item_icon));
|
||||
Bundle bundle = ActivityOptionsCompat
|
||||
.makeSceneTransitionAnimation(getActivity(),
|
||||
iconTransitionPair)
|
||||
.toBundle();
|
||||
startActivityForResult(intent, REQUEST_APPDETAILS, bundle);
|
||||
} else {
|
||||
startActivityForResult(intent, REQUEST_APPDETAILS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Intent getAppDetailsIntent(boolean useNewDetailsActivity) {
|
||||
return new Intent(getActivity(), useNewDetailsActivity ? AppDetails2.class : AppDetails.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreferenceChange() {
|
||||
getAppListAdapter().notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
|
||||
appAdapter.swapCursor(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Cursor> loader) {
|
||||
appAdapter.swapCursor(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
Uri uri = updateSearchStatus() ? getDataUri(searchQuery) : getDataUri();
|
||||
return new CursorLoader(
|
||||
getActivity(), uri, APP_PROJECTION, null, null, APP_SORT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the subclass via {@link AppListFragment#onSearch()} and {@link AppListFragment#onSearchStopped()}
|
||||
* about whether or not a search is taking place and changes empty message
|
||||
* appropriately.
|
||||
*
|
||||
* @return True if a user is searching.
|
||||
*/
|
||||
private boolean updateSearchStatus() {
|
||||
if (TextUtils.isEmpty(searchQuery)) {
|
||||
onSearchStopped();
|
||||
setEmptyText(getEmptyMessage());
|
||||
return false;
|
||||
}
|
||||
onSearch();
|
||||
setEmptyText(getNoSearchResultsMessage());
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updateSearchQuery(@Nullable String query) {
|
||||
if (!TextUtils.equals(query, searchQuery)) {
|
||||
searchQuery = query;
|
||||
if (isAdded()) {
|
||||
getLoaderManager().restartLoader(0, null, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,253 +0,0 @@
|
||||
package org.fdroid.fdroid.views.fragments;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.database.ContentObserver;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import org.fdroid.fdroid.Preferences;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.Utils;
|
||||
import org.fdroid.fdroid.compat.ArrayAdapterCompat;
|
||||
import org.fdroid.fdroid.compat.CursorAdapterCompat;
|
||||
import org.fdroid.fdroid.data.AppProvider;
|
||||
import org.fdroid.fdroid.data.CategoryProvider;
|
||||
import org.fdroid.fdroid.views.AppListAdapter;
|
||||
import org.fdroid.fdroid.views.AvailableAppListAdapter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AvailableAppsFragment extends AppListFragment implements
|
||||
LoaderManager.LoaderCallbacks<Cursor> {
|
||||
|
||||
private static final String TAG = "AvailableAppsFragment";
|
||||
|
||||
private static final String PREFERENCES_FILE = "CategorySpinnerPosition";
|
||||
private static final String CATEGORY_KEY = "Selection";
|
||||
private static String defaultCategory;
|
||||
|
||||
private List<String> categories;
|
||||
|
||||
@Nullable
|
||||
private View categoryWrapper;
|
||||
|
||||
@Nullable
|
||||
private Spinner categorySpinner;
|
||||
private String currentCategory;
|
||||
private AppListAdapter adapter;
|
||||
|
||||
@Override
|
||||
protected String getFromTitle() {
|
||||
return getString(R.string.tab_available_apps);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AppListAdapter getAppListAdapter() {
|
||||
if (adapter == null) {
|
||||
final AppListAdapter a = AvailableAppListAdapter.create(getActivity(), null, CursorAdapterCompat.FLAG_AUTO_REQUERY);
|
||||
Preferences.get().registerUpdateHistoryListener(new Preferences.ChangeListener() {
|
||||
@Override
|
||||
public void onPreferenceChange() {
|
||||
a.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
adapter = a;
|
||||
}
|
||||
return adapter;
|
||||
}
|
||||
|
||||
private class CategoryObserver extends ContentObserver {
|
||||
|
||||
private final ArrayAdapter<String> adapter;
|
||||
|
||||
CategoryObserver(ArrayAdapter<String> adapter) {
|
||||
// Using Looper.getMainLooper() ensures that the onChange method is run on the main thread.
|
||||
super(new Handler(Looper.getMainLooper()));
|
||||
this.adapter = adapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
final Activity activity = getActivity();
|
||||
if (!isAdded() || adapter == null || activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Because onChange is always invoked on the main thread (see constructor), we want to
|
||||
// run the database query on a background thread. Afterwards, the UI is updated
|
||||
// on a foreground thread.
|
||||
new AsyncTask<Void, Void, List<String>>() {
|
||||
@Override
|
||||
protected List<String> doInBackground(Void... params) {
|
||||
return CategoryProvider.Helper.categories(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<String> loadedCategories) {
|
||||
adapter.clear();
|
||||
categories = loadedCategories;
|
||||
ArrayAdapterCompat.addAll(adapter, translateCategories(activity, loadedCategories));
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange, Uri uri) {
|
||||
onChange(selfChange);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to translate category names with fallback to default name if no translation available
|
||||
*/
|
||||
private static List<String> translateCategories(Context context, List<String> categories) {
|
||||
List<String> translatedCategories = new ArrayList<>(categories.size());
|
||||
Resources res = context.getResources();
|
||||
String pkgName = context.getPackageName();
|
||||
for (String category : categories) {
|
||||
String resId = category.replace(" & ", "_").replace(" ", "_").replace("'", "");
|
||||
int id = res.getIdentifier("category_" + resId, "string", pkgName);
|
||||
translatedCategories.add(id == 0 ? category : context.getString(id));
|
||||
}
|
||||
return translatedCategories;
|
||||
}
|
||||
|
||||
private Spinner setupCategorySpinner(Spinner spinner) {
|
||||
|
||||
categorySpinner = spinner;
|
||||
categorySpinner.setId(R.id.category_spinner);
|
||||
|
||||
categories = CategoryProvider.Helper.categories(getActivity());
|
||||
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<>(
|
||||
getActivity(), android.R.layout.simple_spinner_item, translateCategories(getActivity(), categories));
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
categorySpinner.setAdapter(adapter);
|
||||
|
||||
getActivity().getContentResolver().registerContentObserver(
|
||||
AppProvider.getContentUri(), false, new CategoryObserver(adapter));
|
||||
|
||||
categorySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
|
||||
getListView().setSelection(0);
|
||||
setCurrentCategory(categories.get(pos));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
setCurrentCategory(null);
|
||||
}
|
||||
});
|
||||
return categorySpinner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.available_app_list, container, false);
|
||||
|
||||
categoryWrapper = view.findViewById(R.id.category_wrapper);
|
||||
setupCategorySpinner((Spinner) view.findViewById(R.id.category_spinner));
|
||||
defaultCategory = CategoryProvider.Helper.getCategoryWhatsNew(getActivity());
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Uri getDataUri() {
|
||||
if (currentCategory == null || currentCategory.equals(CategoryProvider.Helper.getCategoryAll(getActivity()))) {
|
||||
return AppProvider.getContentUri();
|
||||
}
|
||||
if (currentCategory.equals(CategoryProvider.Helper.getCategoryRecentlyUpdated(getActivity()))) {
|
||||
return AppProvider.getRecentlyUpdatedUri();
|
||||
}
|
||||
if (currentCategory.equals(CategoryProvider.Helper.getCategoryWhatsNew(getActivity()))) {
|
||||
// Removed this feature in the new UI. this fragment will be gone soon so not implementing it again.
|
||||
// return AppProvider.getNewlyAddedUri();
|
||||
return AppProvider.getRecentlyUpdatedUri();
|
||||
}
|
||||
return AppProvider.getCategoryUri(currentCategory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Uri getDataUri(String query) {
|
||||
return AppProvider.getSearchUri(query, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.empty_available_app_list;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNoSearchResultsMessage() {
|
||||
return R.string.empty_search_available_app_list;
|
||||
}
|
||||
|
||||
private void setCurrentCategory(String category) {
|
||||
currentCategory = category;
|
||||
Utils.debugLog(TAG, "Category '" + currentCategory + "' selected.");
|
||||
getLoaderManager().restartLoader(0, null, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
/* restore the saved Category Spinner position */
|
||||
Activity activity = getActivity();
|
||||
SharedPreferences p = activity.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE);
|
||||
currentCategory = p.getString(CATEGORY_KEY, defaultCategory);
|
||||
|
||||
if (categorySpinner != null) {
|
||||
for (int i = 0; i < categorySpinner.getCount(); i++) {
|
||||
if (currentCategory.equals(categorySpinner.getItemAtPosition(i).toString())) {
|
||||
categorySpinner.setSelection(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setCurrentCategory(currentCategory);
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
/* store the Category Spinner position for when we come back */
|
||||
SharedPreferences p = getActivity().getSharedPreferences(PREFERENCES_FILE,
|
||||
Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor e = p.edit();
|
||||
e.putString(CATEGORY_KEY, currentCategory);
|
||||
e.apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSearch() {
|
||||
if (categoryWrapper != null) {
|
||||
categoryWrapper.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSearchStopped() {
|
||||
if (categoryWrapper != null) {
|
||||
categoryWrapper.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package org.fdroid.fdroid.views.fragments;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.compat.CursorAdapterCompat;
|
||||
import org.fdroid.fdroid.data.AppProvider;
|
||||
import org.fdroid.fdroid.views.AppListAdapter;
|
||||
import org.fdroid.fdroid.views.CanUpdateAppListAdapter;
|
||||
|
||||
public class CanUpdateAppsFragment extends AppListFragment {
|
||||
|
||||
@Override
|
||||
protected AppListAdapter getAppListAdapter() {
|
||||
return CanUpdateAppListAdapter.create(getActivity(), null, CursorAdapterCompat.FLAG_AUTO_REQUERY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getFromTitle() {
|
||||
return getString(R.string.tab_updates);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Uri getDataUri() {
|
||||
return AppProvider.getCanUpdateUri();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Uri getDataUri(String query) {
|
||||
return AppProvider.getSearchCanUpdateUri(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.empty_can_update_app_list;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNoSearchResultsMessage() {
|
||||
return R.string.empty_search_can_update_app_list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.can_update_app_list, container, false);
|
||||
}
|
||||
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
package org.fdroid.fdroid.views.fragments;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.compat.CursorAdapterCompat;
|
||||
import org.fdroid.fdroid.data.AppProvider;
|
||||
import org.fdroid.fdroid.views.AppListAdapter;
|
||||
import org.fdroid.fdroid.views.InstalledAppListAdapter;
|
||||
|
||||
public class InstalledAppsFragment extends AppListFragment {
|
||||
|
||||
@Override
|
||||
protected AppListAdapter getAppListAdapter() {
|
||||
return InstalledAppListAdapter.create(getActivity(), null, CursorAdapterCompat.FLAG_AUTO_REQUERY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getFromTitle() {
|
||||
return getString(R.string.tab_installed_apps);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Uri getDataUri() {
|
||||
return AppProvider.getInstalledUri();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Uri getDataUri(String query) {
|
||||
return AppProvider.getSearchInstalledUri(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getEmptyMessage() {
|
||||
return R.string.empty_installed_app_list;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNoSearchResultsMessage() {
|
||||
return R.string.empty_search_installed_app_list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.installed_app_list, container, false);
|
||||
}
|
||||
|
||||
}
|
@ -17,7 +17,6 @@ import org.fdroid.fdroid.AppDetails2;
|
||||
import org.fdroid.fdroid.CleanCacheService;
|
||||
import org.fdroid.fdroid.FDroidApp;
|
||||
import org.fdroid.fdroid.Preferences;
|
||||
import org.fdroid.fdroid.PreferencesActivity;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.UpdateService;
|
||||
import org.fdroid.fdroid.installer.InstallHistoryService;
|
||||
@ -83,8 +82,6 @@ public class PreferencesFragment extends PreferenceFragment
|
||||
|
||||
private void updateSummary(String key, boolean changing) {
|
||||
|
||||
int result = 0;
|
||||
|
||||
switch (key) {
|
||||
case Preferences.PREF_UPD_INTERVAL:
|
||||
ListPreference listPref = (ListPreference) findPreference(
|
||||
@ -114,10 +111,7 @@ public class PreferencesFragment extends PreferenceFragment
|
||||
|
||||
case Preferences.PREF_THEME:
|
||||
entrySummary(key);
|
||||
if (changing) {
|
||||
result |= PreferencesActivity.RESULT_RESTART;
|
||||
getActivity().setResult(result);
|
||||
}
|
||||
// TODO: Ask MainActivity to restart itself.
|
||||
break;
|
||||
|
||||
case Preferences.PREF_INCOMP_VER:
|
||||
@ -147,10 +141,8 @@ public class PreferencesFragment extends PreferenceFragment
|
||||
case Preferences.PREF_LANGUAGE:
|
||||
entrySummary(key);
|
||||
if (changing) {
|
||||
result |= PreferencesActivity.RESULT_RESTART;
|
||||
Activity activity = getActivity();
|
||||
activity.setResult(result);
|
||||
((FDroidApp) activity.getApplication()).updateLanguage();
|
||||
// TODO: Ask MainActivity to restart itself.
|
||||
((FDroidApp) getActivity().getApplication()).updateLanguage();
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -147,7 +147,7 @@ public class MainActivity extends AppCompatActivity implements BottomNavigationB
|
||||
setSelectedMenuInNav();
|
||||
}
|
||||
|
||||
// AppDetails 2 and RepoDetailsActivity set different NFC actions, so reset here
|
||||
// AppDetails2 and RepoDetailsActivity set different NFC actions, so reset here
|
||||
NfcHelper.setAndroidBeam(this, getApplication().getPackageName());
|
||||
checkForAddRepoIntent(getIntent());
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 207 B |
Before Width: | Height: | Size: 919 B |
Before Width: | Height: | Size: 476 B |
Before Width: | Height: | Size: 958 B |
Before Width: | Height: | Size: 195 B |
Before Width: | Height: | Size: 460 B |
Before Width: | Height: | Size: 1003 B |
Before Width: | Height: | Size: 113 B |
Before Width: | Height: | Size: 602 B |
Before Width: | Height: | Size: 346 KiB |
Before Width: | Height: | Size: 825 B |
Before Width: | Height: | Size: 164 B |
Before Width: | Height: | Size: 760 B |
Before Width: | Height: | Size: 304 B |
Before Width: | Height: | Size: 727 B |
Before Width: | Height: | Size: 157 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 712 B |
Before Width: | Height: | Size: 85 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 235 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 585 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 220 B |
Before Width: | Height: | Size: 562 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 95 B |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 309 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 842 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 283 B |
Before Width: | Height: | Size: 843 B |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 94 B |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 377 B |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 343 B |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 100 B |
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:radius="@dimen/badge_size" />
|
||||
<solid android:color="#ffdd0000" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
A category chip displays an icon on the left and the category label on the right. It follows the
|
||||
material design specification at https://material.google.com/components/chips.html#chips-contact-chips.
|
||||
Most of the actual drawing is done in the Java code rather than here.
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<corners android:radius="16dp" />
|
||||
<solid android:color="#FFCCCCCC" />
|
||||
</shape>
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Shown in the app list item as a shortcut for the user to be able to download/install an app.
|
||||
-->
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/ic_download_button" />
|
||||
</selector>
|
@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM17,15.59L15.59,17 12,13.41 8.41,17 7,15.59 10.59,12 7,8.41 8.41,7 12,10.59 15.59,7 17,8.41 13.41,12 17,15.59z"/>
|
||||
</vector>
|
@ -1,13 +0,0 @@
|
||||
<vector android:height="32dp" android:viewportHeight="74.53289"
|
||||
android:viewportWidth="74.53289" android:width="32dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillAlpha="1" android:fillColor="#0066cc"
|
||||
android:pathData="m37.27,0c-20.57,0 -37.27,16.7 -37.27,37.27 0,20.57 16.7,37.27 37.27,37.27 20.57,0 37.27,-16.7 37.27,-37.27 0,-20.57 -16.7,-37.27 -37.27,-37.27zM37.27,2c19.49,0 35.27,15.78 35.27,35.27 0,19.49 -15.78,35.27 -35.27,35.27 -19.49,0 -35.27,-15.78 -35.27,-35.27 0,-19.49 15.78,-35.27 35.27,-35.27z"
|
||||
android:strokeAlpha="1" android:strokeColor="#00000000"
|
||||
android:strokeLineCap="butt" android:strokeLineJoin="miter" android:strokeWidth="2"/>
|
||||
<path android:fillAlpha="1" android:fillColor="#0066cc"
|
||||
android:pathData="M23.05,49.12h27.97v4.04h-27.97z"
|
||||
android:strokeAlpha="1" android:strokeColor="#00000000" android:strokeWidth="2"/>
|
||||
<path android:fillAlpha="1" android:fillColor="#0066cc"
|
||||
android:pathData="m31.07,19.19 l0,12.18 -7.71,0 13.86,13.57 13.86,-13.57 -7.83,0 0,-12.18z"
|
||||
android:strokeAlpha="1" android:strokeColor="#00000000" android:strokeWidth="2"/>
|
||||
</vector>
|
@ -1,47 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/app_summary_container"
|
||||
android:layout_width="0px"
|
||||
android:layout_weight="0.5"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="5dp">
|
||||
|
||||
<fragment
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/header"
|
||||
android:name="org.fdroid.fdroid.AppDetails$AppDetailsHeaderFragment"
|
||||
tools:layout="@layout/app_details_header"/>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/fragment_app_summary"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:name="org.fdroid.fdroid.AppDetails$AppDetailsSummaryFragment"
|
||||
tools:layout="@layout/app_details_summary"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/fragment_app_list"
|
||||
android:layout_width="0px"
|
||||
android:layout_weight="0.5"
|
||||
android:layout_height="wrap_content"
|
||||
android:name="org.fdroid.fdroid.AppDetails$AppDetailsListFragment"/>
|
||||
|
||||
</LinearLayout>
|
@ -1,179 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (C) 2015 Nico Alt, nicoalt@posteo.org
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 3
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/icon_and_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal"
|
||||
android:padding="2dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/app_icon"
|
||||
android:scaleType="fitCenter"
|
||||
tools:src="@drawable/ic_launcher"
|
||||
android:transitionName="@string/transition_app_item_icon" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="vertical"
|
||||
android:layout_toRightOf="@id/icon"
|
||||
android:layout_toEndOf="@id/icon"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="viewStart"
|
||||
android:textSize="17sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="F-Droid" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginBottom="3dp"
|
||||
android:layout_weight="1"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/author"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="viewStart"
|
||||
android:textSize="13sp"
|
||||
android:visibility="gone"
|
||||
tools:text="F-Droid Authors" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/current_version"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="viewStart"
|
||||
android:textSize="13sp"
|
||||
tools:text="1.24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="viewStart"
|
||||
android:textSize="13sp"
|
||||
tools:text="Version 1.23 installed" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_main"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:layout_weight="0"
|
||||
android:baselineAligned="false"
|
||||
tools:text="Open" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/icon"
|
||||
android:gravity="center">
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal" />
|
||||
<TextView
|
||||
android:id="@+id/progress_size"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@id/progress_bar"
|
||||
android:visibility="gone"
|
||||
android:textSize="12sp"/>
|
||||
<TextView
|
||||
android:id="@+id/progress_percentage"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_below="@id/progress_bar"
|
||||
android:visibility="gone"
|
||||
android:textSize="12sp"/>
|
||||
</RelativeLayout>
|
||||
<ImageButton
|
||||
android:id="@+id/cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="5dp"
|
||||
android:layout_weight="0"
|
||||
android:visibility="gone"
|
||||
android:src="@drawable/ic_clear"
|
||||
android:background="@null"/>
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
|
@ -1,104 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/listPreferredItemHeight"
|
||||
android:paddingLeft="?attr/listPreferredItemPaddingLeft"
|
||||
android:paddingStart="?attr/listPreferredItemPaddingLeft"
|
||||
android:paddingRight="?attr/listPreferredItemPaddingRight"
|
||||
android:paddingEnd="?attr/listPreferredItemPaddingRight"
|
||||
android:baselineAligned="false"
|
||||
>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:contentDescription="@string/app_icon"
|
||||
android:layout_width="48dip"
|
||||
android:layout_height="48dip"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:scaleType="fitCenter"
|
||||
tools:src="@drawable/ic_launcher"
|
||||
android:transitionName="@string/transition_app_item_icon" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<TextView android:id="@+id/name"
|
||||
android:textSize="16sp"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="?attr/listPreferredItemPaddingLeft"
|
||||
android:paddingEnd="?attr/listPreferredItemPaddingRight"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="start"
|
||||
android:textAlignment="viewStart"
|
||||
tools:text="F-Droid" />
|
||||
|
||||
<TextView android:id="@+id/status"
|
||||
android:textSize="14sp"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="end"
|
||||
android:textAlignment="viewEnd"
|
||||
tools:text="Installed" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<TextView android:id="@+id/summary"
|
||||
android:textSize="14sp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="?attr/listPreferredItemPaddingLeft"
|
||||
android:paddingStart="?attr/listPreferredItemPaddingLeft"
|
||||
android:paddingRight="?attr/listPreferredItemPaddingRight"
|
||||
android:paddingEnd="?attr/listPreferredItemPaddingRight"
|
||||
android:gravity="start"
|
||||
android:textAlignment="viewStart"
|
||||
tools:text="Application manager" />
|
||||
|
||||
<TextView android:id="@+id/license"
|
||||
android:textSize="14sp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:layout_weight="0"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="end"
|
||||
android:textAlignment="viewEnd"
|
||||
tools:text="GPLv3+" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingLeft="6dp"
|
||||
android:paddingRight="6dp">
|
||||
|
||||
<fragment
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/header"
|
||||
android:name="org.fdroid.fdroid.AppDetails$AppDetailsHeaderFragment"
|
||||
tools:layout="@layout/app_details_header" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/fragment_app_list"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:name="org.fdroid.fdroid.AppDetails$AppDetailsListFragment" />
|
||||
|
||||
</LinearLayout>
|
@ -31,7 +31,6 @@
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="centerCrop"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:src="@drawable/feature_placeholder"
|
||||
app:layout_collapseMode="parallax" />
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
|
@ -1,178 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (C) 2015 Nico Alt, nicoalt@posteo.org
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 3
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/icon_and_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal"
|
||||
android:padding="2dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/app_icon"
|
||||
android:scaleType="fitCenter"
|
||||
tools:src="@drawable/ic_launcher" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="vertical"
|
||||
android:layout_toRightOf="@id/icon"
|
||||
android:layout_toEndOf="@id/icon"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="viewStart"
|
||||
android:textSize="17sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="F-Droid" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginBottom="3dp"
|
||||
android:layout_weight="1"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/author"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="viewStart"
|
||||
android:textSize="13sp"
|
||||
android:visibility="gone"
|
||||
tools:text="F-Droid Authors" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/current_version"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="viewStart"
|
||||
android:textSize="13sp"
|
||||
tools:text="1.24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:ellipsize="end"
|
||||
android:gravity="start"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="viewStart"
|
||||
android:textSize="13sp"
|
||||
tools:text="Version 1.23 installed" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_main"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:layout_weight="0"
|
||||
android:baselineAligned="false"
|
||||
tools:text="Open" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:id="@+id/holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/icon"
|
||||
android:gravity="center">
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal" />
|
||||
<TextView
|
||||
android:id="@+id/progress_size"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@id/progress_bar"
|
||||
android:visibility="gone"
|
||||
android:textSize="12sp"/>
|
||||
<TextView
|
||||
android:id="@+id/progress_percentage"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_below="@id/progress_bar"
|
||||
android:visibility="gone"
|
||||
android:textSize="12sp"/>
|
||||
</RelativeLayout>
|
||||
<ImageButton
|
||||
android:id="@+id/cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="5dp"
|
||||
android:layout_weight="0"
|
||||
android:visibility="gone"
|
||||
android:src="@drawable/ic_clear"
|
||||
android:background="@null"/>
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
|
@ -1,233 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2015 Nico Alt, nicoalt@posteo.org
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 3
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingLeft="@dimen/layout_horizontal_margin"
|
||||
android:paddingStart="@dimen/layout_horizontal_margin"
|
||||
android:paddingRight="@dimen/layout_horizontal_margin"
|
||||
android:paddingEnd="@dimen/layout_horizontal_margin"
|
||||
android:paddingTop="4dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/summary"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
tools:text="Application manager" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/package_name"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="12sp"
|
||||
tools:text="org.fdroid.fdroid" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/signature"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/antifeatures"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6sp"
|
||||
android:textColor="#ff0000"
|
||||
android:textStyle="bold"
|
||||
tools:text="Feeds you too much chocolate" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_description"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8sp"
|
||||
android:singleLine="false"
|
||||
android:textSize="13sp"
|
||||
tools:text="Connects to F-Droid compatible repositories. The default repo is hosted at f-droid.org, which contains only bona fide FOSS.
|
||||
|
||||
Android is open in the sense that you are free to install apks from anywhere you wish, but there are many good reasons for using a client/repository setup:
|
||||
|
||||
* Be notified when updates are available
|
||||
* Keep track of older and beta versions
|
||||
* Filter apps that aren't compatible with the device
|
||||
* Find apps via categories and searchable descriptions
|
||||
* Access associated urls for donations, source code etc.
|
||||
* Stay safe by checking repo index signatures and apk hashes
|
||||
|
||||
Changelog" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/view_more_description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|center_horizontal"
|
||||
android:text="@string/more"
|
||||
android:textAllCaps="true"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
tools:ignore="UnusedAttribute" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2px"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="?android:attr/listDivider"
|
||||
tools:ignore="PxUsage" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_information"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/information"
|
||||
style="@style/AppDetailsSubheaderText"
|
||||
android:text="@string/links"
|
||||
android:drawableRight="@drawable/ic_expand_more_grey600"
|
||||
android:drawableEnd="@drawable/ic_expand_more_grey600"
|
||||
android:drawableLeft="@drawable/ic_website"
|
||||
android:drawableStart="@drawable/ic_website" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_information_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginLeft="@dimen/layout_horizontal_margin"
|
||||
android:layout_marginStart="@dimen/layout_horizontal_margin"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/source"
|
||||
style="@style/AppDetailsLink"
|
||||
android:drawableLeft="@drawable/ic_source_code"
|
||||
android:drawableStart="@drawable/ic_source_code"
|
||||
android:text="@string/menu_source" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/issues"
|
||||
style="@style/AppDetailsLink"
|
||||
android:drawableLeft="@drawable/ic_issues"
|
||||
android:drawableStart="@drawable/ic_issues"
|
||||
android:text="@string/menu_issues" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/changelog"
|
||||
style="@style/AppDetailsLink"
|
||||
android:drawableLeft="@drawable/ic_changelog"
|
||||
android:drawableStart="@drawable/ic_changelog"
|
||||
android:text="@string/menu_changelog" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/website"
|
||||
style="@style/AppDetailsLink"
|
||||
android:drawableLeft="@drawable/ic_website"
|
||||
android:drawableStart="@drawable/ic_website"
|
||||
android:text="@string/menu_website" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/email"
|
||||
style="@style/AppDetailsLink"
|
||||
android:drawableLeft="@drawable/ic_email"
|
||||
android:drawableStart="@drawable/ic_email"
|
||||
android:text="@string/menu_email" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/donate"
|
||||
style="@style/AppDetailsLink"
|
||||
android:drawableLeft="@drawable/ic_donate"
|
||||
android:drawableStart="@drawable/ic_donate"
|
||||
android:text="@string/menu_donate" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bitcoin"
|
||||
style="@style/AppDetailsLink"
|
||||
android:drawableLeft="@drawable/ic_bitcoin"
|
||||
android:drawableStart="@drawable/ic_bitcoin"
|
||||
android:text="@string/menu_bitcoin" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/litecoin"
|
||||
style="@style/AppDetailsLink"
|
||||
android:drawableLeft="@drawable/donation_option_litecoin"
|
||||
android:drawableStart="@drawable/donation_option_litecoin"
|
||||
android:text="@string/menu_litecoin" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/flattr"
|
||||
style="@style/AppDetailsLink"
|
||||
android:drawableLeft="@drawable/donation_option_flattr"
|
||||
android:drawableStart="@drawable/donation_option_flattr"
|
||||
android:text="@string/menu_flattr" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_permissions"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginBottom="8dp"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/permissions"
|
||||
style="@style/AppDetailsSubheaderText"
|
||||
android:text="@string/permissions"
|
||||
android:drawableLeft="@drawable/ic_lock_24dp_grey600"
|
||||
android:drawableStart="@drawable/ic_lock_24dp_grey600"
|
||||
android:drawableRight="@drawable/ic_expand_more_grey600"
|
||||
android:drawableEnd="@drawable/ic_expand_more_grey600" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/permission_list"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
android:paddingEnd="4dp"
|
||||
android:paddingRight="4dp"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -1,104 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/listPreferredItemHeight"
|
||||
android:paddingLeft="?attr/listPreferredItemPaddingLeft"
|
||||
android:paddingStart="?attr/listPreferredItemPaddingLeft"
|
||||
android:paddingRight="?attr/listPreferredItemPaddingRight"
|
||||
android:paddingEnd="?attr/listPreferredItemPaddingRight"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:contentDescription="@string/app_icon"
|
||||
android:layout_width="48dip"
|
||||
android:layout_height="48dip"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:scaleType="fitCenter"
|
||||
tools:src="@drawable/ic_launcher" />
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<TextView android:id="@+id/name"
|
||||
android:textSize="16sp"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="?attr/listPreferredItemPaddingLeft"
|
||||
android:paddingStart="?attr/listPreferredItemPaddingLeft"
|
||||
android:paddingRight="?attr/listPreferredItemPaddingRight"
|
||||
android:paddingEnd="?attr/listPreferredItemPaddingRight"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="start"
|
||||
android:textAlignment="viewStart"
|
||||
tools:text="F-Droid" />
|
||||
|
||||
<TextView android:id="@+id/status"
|
||||
android:textSize="14sp"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="end"
|
||||
android:textAlignment="viewEnd"
|
||||
tools:text="Installed" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<TextView android:id="@+id/summary"
|
||||
android:textSize="14sp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="?attr/listPreferredItemPaddingLeft"
|
||||
android:paddingStart="?attr/listPreferredItemPaddingLeft"
|
||||
android:paddingRight="?attr/listPreferredItemPaddingRight"
|
||||
android:paddingEnd="?attr/listPreferredItemPaddingRight"
|
||||
android:gravity="start"
|
||||
android:textAlignment="viewStart"
|
||||
tools:text="Application manager" />
|
||||
|
||||
<TextView android:id="@+id/license"
|
||||
android:textSize="14sp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
android:layout_weight="0"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="end"
|
||||
android:textAlignment="viewEnd"
|
||||
tools:text="GPLv3+" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -1,38 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/category_wrapper"
|
||||
android:layout_alignParentTop="true">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/category_spinner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:paddingBottom="1dp" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="2dp"
|
||||
android:layout_alignBottom="@id/category_spinner"
|
||||
android:background="@color/fdroid_green" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<ListView
|
||||
style="@style/AppList"
|
||||
android:layout_below="@id/category_wrapper" />
|
||||
|
||||
<TextView
|
||||
style="@style/AppListEmptyText"
|
||||
android:layout_below="@id/category_wrapper"
|
||||
android:text="@string/empty_available_app_list" />
|
||||
|
||||
</RelativeLayout>
|
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ListView
|
||||
style="@style/AppList" />
|
||||
|
||||
<TextView
|
||||
style="@style/AppListEmptyText"
|
||||
android:text="@string/empty_can_update_app_list" />
|
||||
|
||||
</RelativeLayout>
|
@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/fdroid_layout"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v4.view.ViewPager
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/main_pager"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
|
||||
</android.support.v4.view.ViewPager>
|
||||
|
||||
</LinearLayout>
|
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ListView
|
||||
style="@style/AppList" />
|
||||
|
||||
<TextView
|
||||
style="@style/AppListEmptyText"
|
||||
android:text="@string/empty_installed_app_list" />
|
||||
|
||||
</RelativeLayout>
|
@ -1,41 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto" >
|
||||
|
||||
<item
|
||||
android:id="@+id/action_search"
|
||||
android:icon="@drawable/ic_search_white"
|
||||
android:title="@string/menu_search"
|
||||
app:actionViewClass="android.support.v7.widget.SearchView"
|
||||
app:showAsAction="collapseActionView|ifRoom"/>
|
||||
<item
|
||||
android:id="@+id/action_update_repo"
|
||||
android:icon="@drawable/ic_refresh_white"
|
||||
android:title="@string/menu_update_repo"
|
||||
app:showAsAction="ifRoom"/>
|
||||
<item
|
||||
android:id="@+id/action_swap"
|
||||
android:title="@string/swap"
|
||||
app:showAsAction="ifRoom"/>
|
||||
<item
|
||||
android:id="@+id/action_manage_repos"
|
||||
android:icon="@drawable/ic_toc_white"
|
||||
android:title="@string/menu_manage"
|
||||
app:showAsAction="ifRoom"/>
|
||||
<item
|
||||
android:id="@+id/action_bluetooth_apk"
|
||||
android:icon="@drawable/ic_bluetooth_white"
|
||||
android:title="@string/menu_send_apk_bt"
|
||||
app:showAsAction="ifRoom"/>
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:icon="@drawable/ic_settings_white"
|
||||
android:title="@string/menu_settings"
|
||||
app:showAsAction="ifRoom"/>
|
||||
<item
|
||||
android:id="@+id/action_about"
|
||||
android:icon="@drawable/ic_help_white"
|
||||
android:title="@string/menu_about"
|
||||
app:showAsAction="ifRoom"/>
|
||||
|
||||
</menu>
|
@ -75,11 +75,6 @@
|
||||
<string name="cancel">Kanselleer</string>
|
||||
<string name="overwrite">Oorskryf</string>
|
||||
|
||||
<string name="tab_available_apps">Beskikbaar</string>
|
||||
<string name="tab_installed_apps">Geinstalleer</string>
|
||||
<string name="tab_updates">Opdaterings</string>
|
||||
<string name="tab_installed_apps_count">Geinstalleer (%d)</string>
|
||||
<string name="tab_updates_count">Opdaterings (%d)</string>
|
||||
<string name="fdroid_updates_available">F-Droid opdaterings beskikbaar</string>
|
||||
<string name="bluetooth_activity_not_found">Geen Bluetooth stuur metode gevind, kies een!</string>
|
||||
<string name="choose_bt_send">Kies Bluetooth stuur metode</string>
|
||||
@ -226,13 +221,9 @@ Jy moet
|
||||
<string name="pref_language">Taal</string>
|
||||
<string name="pref_language_default">Stelsel nalaat waarde</string>
|
||||
|
||||
<string name="app_icon">Program simbooltjie</string>
|
||||
<string name="wifi">Wi-Fi</string>
|
||||
<string name="wifi_ap">Hotspot</string>
|
||||
|
||||
<string name="category_All">Alle</string>
|
||||
<string name="category_Whats_New">Wat\'s nuut</string>
|
||||
<string name="category_Recently_Updated">Onlangs opgedateer</string>
|
||||
<string name="category_Connectivity">Konnektiwiteit</string>
|
||||
<string name="category_Development">Ontwikkeling</string>
|
||||
<string name="category_Games">Speletjies</string>
|
||||
|
@ -20,8 +20,6 @@
|
||||
<string name="cancel">إلغاء</string>
|
||||
<string name="enable">تمكين</string>
|
||||
<string name="add_key">إضافة مفتاح</string>
|
||||
<string name="tab_available_apps">متواجد</string>
|
||||
<string name="tab_updates">التحديثات</string>
|
||||
<string name="choose_bt_send">اختيار البلوتوث كطريقة إرسال</string>
|
||||
<string name="send_via_bluetooth">إرسال بواسطة البلوتوث</string>
|
||||
<string name="repo_add_url">عنوان المستودع</string>
|
||||
@ -38,8 +36,6 @@
|
||||
<string name="menu_ignore_this">تجاهل هذا التحديث</string>
|
||||
<string name="menu_source">الشفرة المصدرية</string>
|
||||
<string name="menu_donate">التبرع</string>
|
||||
<string name="category_All">الكل</string>
|
||||
<string name="category_Whats_New">ما الجديد</string>
|
||||
<string name="local_repo">مستودع محلي</string>
|
||||
<string name="deleting_repo">يتم حذف المستودع الحالي…</string>
|
||||
<string name="next">التالي</string>
|
||||
@ -53,7 +49,6 @@
|
||||
<string name="repo_name">الإسم</string>
|
||||
<string name="unknown">غير معروف</string>
|
||||
<string name="repo_confirm_delete_title">حذف المستودع؟</string>
|
||||
<string name="app_icon">أيقونة التطبيق</string>
|
||||
<string name="category_Development">التطوير</string>
|
||||
<string name="category_Games">الألعاب</string>
|
||||
<string name="category_Internet">الإنترنت</string>
|
||||
@ -116,9 +111,6 @@
|
||||
<string name="back">إلى الخلف</string>
|
||||
<string name="overwrite">استبدال</string>
|
||||
|
||||
<string name="tab_installed_apps">تم التثبيت</string>
|
||||
<string name="tab_installed_apps_count">تم التثبيت (%d)</string>
|
||||
<string name="tab_updates_count">تحديثات (%d)</string>
|
||||
<string name="fdroid_updates_available">تحديثات اف-درويد متوفرة</string>
|
||||
<string name="notification_summary_more">+%1$d المزيد…</string>
|
||||
<string name="bluetooth_activity_not_found">لا توجد طريقة إرسال بلوتوث، فضلاً إختر واحدة !</string>
|
||||
@ -230,7 +222,6 @@
|
||||
<string name="wifi">شبكة لاسلكية (واي-فاي)</string>
|
||||
<string name="wifi_ap">نقاط الإنترنت</string>
|
||||
|
||||
<string name="category_Recently_Updated">تم تحديثه مؤخرا</string>
|
||||
<string name="category_Connectivity">الاتصال</string>
|
||||
<string name="category_Graphics">الرسومات</string>
|
||||
<string name="category_Money">نقود</string>
|
||||
|
@ -43,8 +43,6 @@
|
||||
<string name="enable">Habilitar</string>
|
||||
<string name="add_key">Amestar clave</string>
|
||||
<string name="overwrite">Sobrescribir</string>
|
||||
<string name="tab_available_apps">Disponible</string>
|
||||
<string name="tab_updates">Anovamientos</string>
|
||||
<string name="fdroid_updates_available">Anovamientos de F-Droid disponibles</string>
|
||||
<string name="bluetooth_activity_not_found">Nun s\'alcontró dal métodu d\'unviu pente Bluetooth, ¡escueyi ún!</string>
|
||||
<string name="choose_bt_send">Escueyi\'l métodu d\'unvu pente Bluetooth</string>
|
||||
@ -92,9 +90,6 @@
|
||||
<string name="rooted_on">Nun escurez les aplicaciones que rican privilexos root</string>
|
||||
<string name="ignoreTouch">Inorar pantalla táutil</string>
|
||||
<string name="ignoreTouch_on">Inclúi siempres aplicaciones que rican pantalla táutil</string>
|
||||
<string name="category_All">Too</string>
|
||||
<string name="category_Whats_New">Qué hai nuevo</string>
|
||||
<string name="category_Recently_Updated">Anovao apocayá</string>
|
||||
<string name="local_repo">Repositoriu llocal</string>
|
||||
<string name="local_repo_running">F-Doid ta tresnáu pa intercambiar</string>
|
||||
<string name="touch_to_configure_local_repo">Toca pa ver los detalles y permitir a otros intercambiar les tos aplicaciones.</string>
|
||||
@ -148,7 +143,6 @@ rehabilitar esti repositoriu pa instalar aplicaciones dende elli.</string>
|
||||
<string name="minsdk_up_to_maxsdk">De %1$s fasta %2$s</string>
|
||||
<string name="not_on_same_wifi">¡El to preséu nun ta na mesma rede Wi-Fi que\'l repositoriu llocal que tas acabante d\'amestar! Tenta de xunite a esta rede: %s</string>
|
||||
<string name="requires_features">Rique: %1$s</string>
|
||||
<string name="app_icon">Iconu d\'aplicación</string>
|
||||
<string name="category_Development">Desendolcu</string>
|
||||
<string name="category_Games">Xuegos</string>
|
||||
<string name="category_Internet">Internet</string>
|
||||
@ -211,7 +205,6 @@ rehabilitar esti repositoriu pa instalar aplicaciones dende elli.</string>
|
||||
<string name="links">Enllaces</string>
|
||||
|
||||
<string name="back">Atrás</string>
|
||||
<string name="tab_installed_apps">Instaláu</string>
|
||||
<string name="notification_summary_more">+%1$d más…</string>
|
||||
<string name="bad_fingerprint">Buelga incorreuta</string>
|
||||
<string name="invalid_url">Esto nun ye una URL válida.</string>
|
||||
@ -317,8 +310,6 @@ L\'aplicación nun rique accesu especial dalu.</string>
|
||||
<string name="repo_edit_credentials">Camudar contraseña</string>
|
||||
<string name="repo_error_empty_username">Nome d\'usuariu baleru, nun se camudaron les credenciales</string>
|
||||
|
||||
<string name="tab_installed_apps_count">Instalaes (%d)</string>
|
||||
<string name="tab_updates_count">Anovamientos (%d)</string>
|
||||
<string name="about_license">Llicencia</string>
|
||||
|
||||
<string name="status_inserting_apps">Guardando detalles d\'aplicaciones</string>
|
||||
|
@ -81,11 +81,6 @@
|
||||
<string name="add_key">Дадаць ключ</string>
|
||||
<string name="overwrite">Перазапісаць</string>
|
||||
|
||||
<string name="tab_available_apps">Даступна</string>
|
||||
<string name="tab_installed_apps">Усталяваныя</string>
|
||||
<string name="tab_updates">Абнаўленні</string>
|
||||
<string name="tab_installed_apps_count">Усталявана (%d)</string>
|
||||
<string name="tab_updates_count">Абнаўленні (%d)</string>
|
||||
<string name="fdroid_updates_available">Даступны абнаўленні F-Droid</string>
|
||||
<string name="bluetooth_activity_not_found">Не знойдзена метада адпраўкі праз Bluetooth, абярыце адзін!</string>
|
||||
<string name="choose_bt_send">Абраць метад адпраўкі праз Bluetooth</string>
|
||||
@ -235,13 +230,9 @@
|
||||
<string name="pref_language">Мова</string>
|
||||
<string name="pref_language_default">Агаданая сістэмная</string>
|
||||
|
||||
<string name="app_icon">Значка праграмы</string>
|
||||
<string name="wifi">Wi-Fi</string>
|
||||
<string name="wifi_ap">Кропка доступу</string>
|
||||
|
||||
<string name="category_All">Усе</string>
|
||||
<string name="category_Whats_New">Што новага</string>
|
||||
<string name="category_Recently_Updated">Нядаўна абноўленыя</string>
|
||||
<string name="category_Connectivity">Сувязь</string>
|
||||
<string name="category_Development">Распрацоўка</string>
|
||||
<string name="category_Games">Гульні</string>
|
||||
|
@ -40,8 +40,6 @@
|
||||
<string name="repo_add_add">Добавяне</string>
|
||||
<string name="cancel">Отказ</string>
|
||||
<string name="add_key">Добавете ключ</string>
|
||||
<string name="tab_available_apps">Налични</string>
|
||||
<string name="tab_updates">Обновявания</string>
|
||||
<string name="fdroid_updates_available">Налични актуализации от F-Droid</string>
|
||||
<string name="bluetooth_activity_not_found">Не е намерен Bluetooth метод за изпращане, изберете един!</string>
|
||||
<string name="choose_bt_send">Изберете Bluetooth метод за изпращане</string>
|
||||
@ -84,9 +82,6 @@
|
||||
<string name="rooted_on">Приложенията изискващи Root няма да бъдат изобразявани в сиво</string>
|
||||
<string name="ignoreTouch">Игнорирай сензорния екран</string>
|
||||
<string name="ignoreTouch_on">Приложенията изискващи сензорен екран ще бъдат показвани винаги</string>
|
||||
<string name="category_All">Всички</string>
|
||||
<string name="category_Whats_New">Какво ново</string>
|
||||
<string name="category_Recently_Updated">Обновени наскоро</string>
|
||||
<string name="local_repo">Локално хранилище</string>
|
||||
<string name="deleting_repo">Изтриване на хранилището…</string>
|
||||
<string name="adding_apks_format">Добавяне на %s към хранилището…</string>
|
||||
@ -122,7 +117,6 @@
|
||||
<string name="minsdk_up_to_maxsdk">%1$s до %2$s</string>
|
||||
<string name="not_on_same_wifi">Вашето устройство не е в една и съща Wi-Fi мрежа с локалното хранилище, което добавихте! Опитайте да се свържете към тази мрежа: %s</string>
|
||||
<string name="requires_features">Изисква: %1$s</string>
|
||||
<string name="app_icon">Икона на приложението</string>
|
||||
<string name="category_Development">Разработване</string>
|
||||
<string name="category_Games">Игри</string>
|
||||
<string name="category_Internet">Интернет</string>
|
||||
@ -178,7 +172,6 @@
|
||||
<string name="downloading">Сваляне…</string>
|
||||
|
||||
<string name="about_source">Изходен код</string>
|
||||
<string name="tab_installed_apps">Инсталирани</string>
|
||||
<string name="notification_summary_more">+ още %1$d…</string>
|
||||
<string name="update_notification_title">Актуализиране на хранилищата</string>
|
||||
<string name="install_error_unknown">Инсталирането се провали поради неизвестна грешка</string>
|
||||
@ -291,8 +284,6 @@
|
||||
<string name="enable">Включване</string>
|
||||
<string name="overwrite">Презаписване</string>
|
||||
|
||||
<string name="tab_installed_apps_count">Инсталирани (%d)</string>
|
||||
<string name="tab_updates_count">Актуализации (%d)</string>
|
||||
<string name="repo_provider">Хранилище: %s</string>
|
||||
|
||||
<string name="menu_email">Изпращане на имейл на създателя</string>
|
||||
|
@ -42,8 +42,6 @@
|
||||
<string name="enable">Permès</string>
|
||||
<string name="add_key">Afegeix clau</string>
|
||||
<string name="overwrite">Sobreescriu</string>
|
||||
<string name="tab_available_apps">Disponible</string>
|
||||
<string name="tab_updates">Actualitzacions</string>
|
||||
<string name="fdroid_updates_available">Hi ha actualitzacions disponibles de l\'F-Droid</string>
|
||||
<string name="bluetooth_activity_not_found">Trieu un mètode d\'enviament per Bluetooth!</string>
|
||||
<string name="send_via_bluetooth">Envia per Bluetooth</string>
|
||||
@ -90,9 +88,6 @@
|
||||
<string name="rooted_on">No marquis en gris aplicacions que requereixen privilegis d\'administrador</string>
|
||||
<string name="ignoreTouch">Ignora la pantalla tàctil</string>
|
||||
<string name="ignoreTouch_on">Inclou sempre aplicacions que requereixin pantalla tàctil</string>
|
||||
<string name="category_All">Tot</string>
|
||||
<string name="category_Whats_New">Novetats</string>
|
||||
<string name="category_Recently_Updated">S\'ha actualitzat fa poc</string>
|
||||
<string name="local_repo">Dipòsit local</string>
|
||||
<string name="local_repo_running">F-Droid està a punt per a l\'intercanvi</string>
|
||||
<string name="touch_to_configure_local_repo">Toqueu per veure més detalls i permetre l\'intercanvi d\'aplicacions.</string>
|
||||
@ -150,7 +145,6 @@ tornar a habilitar el dipòsit per instal·lar aplicacions d\'aquest.</string>
|
||||
<string name="minsdk_up_to_maxsdk">%1$s fins a %2$s</string>
|
||||
<string name="not_on_same_wifi">El dipòsit local que acabeu d\'afegir i el vostre dispositiu no són a la mateixa Wi-Fi. Proveu amb aquesta xarxa: %s</string>
|
||||
<string name="requires_features">Requereix: %1$s</string>
|
||||
<string name="app_icon">Icona de l\'aplicació</string>
|
||||
<string name="category_Development">Desenvolupament</string>
|
||||
<string name="category_Games">Jocs</string>
|
||||
<string name="category_Internet">Internet</string>
|
||||
@ -195,7 +189,6 @@ tornar a habilitar el dipòsit per instal·lar aplicacions d\'aquest.</string>
|
||||
<string name="system_uninstall_button">Desinstal·la</string>
|
||||
|
||||
<string name="unstable_updates">Actualitzacions inestables</string>
|
||||
<string name="tab_installed_apps">Instal·lades</string>
|
||||
<string name="menu_bitcoin">Bitcoin</string>
|
||||
<string name="menu_litecoin">Litecoin</string>
|
||||
<string name="menu_flattr">Flattr</string>
|
||||
@ -322,8 +315,6 @@ es perdran. L\'aplicació no requereix cap accés especial.</string>
|
||||
|
||||
<string name="about_license">Llicència</string>
|
||||
|
||||
<string name="tab_installed_apps_count">(%d) instal·lat</string>
|
||||
<string name="tab_updates_count">Actualitzacions (%d)</string>
|
||||
<string name="status_inserting_apps">Desant els detalls de l\'aplicació</string>
|
||||
<string name="empty_search_installed_app_list">Cap coincidència amb les aplicacions instal·lades.</string>
|
||||
<string name="empty_search_available_app_list">Cap coincidència amb les aplicacions disponibles.</string>
|
||||
|
@ -39,8 +39,6 @@
|
||||
<string name="enable">Povolit</string>
|
||||
<string name="add_key">Přidat klíč</string>
|
||||
<string name="overwrite">Přepsat</string>
|
||||
<string name="tab_available_apps">Dostupné</string>
|
||||
<string name="tab_updates">Aktualizace</string>
|
||||
<string name="fdroid_updates_available">Dostupné aktualizace F-Droid</string>
|
||||
<string name="send_via_bluetooth">Poslat přes bluetooth</string>
|
||||
<string name="repo_add_url">Adresa repositáře</string>
|
||||
@ -74,9 +72,6 @@
|
||||
<string name="rooted_on">Nezašedávat aplikace vyžadující root oprávnění</string>
|
||||
<string name="ignoreTouch">Ignorovat dotykovou obrazovku</string>
|
||||
<string name="ignoreTouch_on">Vždy zahrnovat aplikace vyžadující dotykovou obrazovku</string>
|
||||
<string name="category_All">Vše</string>
|
||||
<string name="category_Whats_New">Novinky</string>
|
||||
<string name="category_Recently_Updated">Nedávno aktualizované</string>
|
||||
<string name="local_repo">Místní repozitář</string>
|
||||
<string name="local_repo_running">F-Droid je připraven k výměně</string>
|
||||
<string name="touch_to_configure_local_repo">Dotykem zobraz detaily a umožni ostatním si přetáhnout tvé aplikace.</string>
|
||||
@ -118,7 +113,6 @@ Pro zobrazení nabízených aplikací je nutné ho nejprve aktualizovat.</string
|
||||
Pro instalaci aplikací z tohoto repozitáře ho bude nejprve třeba znovu povolit.</string>
|
||||
<string name="minsdk_or_later">%s nebo novější</string>
|
||||
<string name="requires_features">Vyžaduje: %1$s</string>
|
||||
<string name="app_icon">Ikona aplikace</string>
|
||||
<string name="category_Development">Vývoj</string>
|
||||
<string name="category_Games">Hry</string>
|
||||
<string name="category_Internet">Internet</string>
|
||||
@ -180,7 +174,6 @@ Pro instalaci aplikací z tohoto repozitáře ho bude nejprve třeba znovu povol
|
||||
<string name="more">Více</string>
|
||||
<string name="less">Méně</string>
|
||||
|
||||
<string name="tab_installed_apps">Nainstalováno</string>
|
||||
<string name="bad_fingerprint">Špatný fingerprint</string>
|
||||
<string name="menu_settings">Nastavení</string>
|
||||
<string name="menu_bitcoin">Bitcoin</string>
|
||||
@ -209,8 +202,6 @@ Pro instalaci aplikací z tohoto repozitáře ho bude nejprve třeba znovu povol
|
||||
|
||||
<string name="about_license">Licence</string>
|
||||
|
||||
<string name="tab_installed_apps_count">Nainstalováno (%d)</string>
|
||||
<string name="tab_updates_count">Aktualizace (%d)</string>
|
||||
<string name="not_on_same_wifi">Tento přístroj není na stejné wifi síti jako právě přidaný místní repozitář! Zkuste se připojit k této síti: %s</string>
|
||||
<string name="pref_language">Jazyk</string>
|
||||
<string name="pref_language_default">Systémové výchozí</string>
|
||||
|
@ -70,11 +70,6 @@
|
||||
<string name="add_key">Tilføj Nøgle</string>
|
||||
<string name="overwrite">Overskriv</string>
|
||||
|
||||
<string name="tab_available_apps">Tilgængelig</string>
|
||||
<string name="tab_installed_apps">Installeret</string>
|
||||
<string name="tab_updates">Opdateringer</string>
|
||||
<string name="tab_installed_apps_count">Installeret (%d)</string>
|
||||
<string name="tab_updates_count">Opdateringer (%d)</string>
|
||||
<string name="fdroid_updates_available">F-Droid Opdateringer Tilgængelige</string>
|
||||
<string name="notification_summary_more">+%1$d flere…</string>
|
||||
<string name="bluetooth_activity_not_found">Ingen Bluetooth afsendelsesmetode fundet, vælg en!</string>
|
||||
@ -201,13 +196,9 @@ Du skal aktivere det for at se de programmer det har.</string>
|
||||
<string name="pref_language">Sprog</string>
|
||||
<string name="pref_language_default">Systemstandard</string>
|
||||
|
||||
<string name="app_icon">Programikon</string>
|
||||
<string name="wifi">Wi-Fi</string>
|
||||
<string name="wifi_ap">Hotspot</string>
|
||||
|
||||
<string name="category_All">Alle</string>
|
||||
<string name="category_Whats_New">Hvad er Nyt</string>
|
||||
<string name="category_Recently_Updated">Nyligt Opdateret</string>
|
||||
<string name="category_Connectivity">Tilslutningsmuligheder</string>
|
||||
<string name="category_Development">Udvikling</string>
|
||||
<string name="category_Games">Spil</string>
|
||||
|
@ -43,8 +43,6 @@
|
||||
<string name="enable">Aktivieren</string>
|
||||
<string name="add_key">Schlüssel hinzufügen</string>
|
||||
<string name="overwrite">Überschreiben</string>
|
||||
<string name="tab_available_apps">Verfügbar</string>
|
||||
<string name="tab_updates">Aktualisierungen</string>
|
||||
<string name="fdroid_updates_available">F-Droid: Aktualisierungen verfügbar</string>
|
||||
<string name="bluetooth_activity_not_found">Keine Bluetooth-Sendemethode gefunden, bitte eine auswählen!</string>
|
||||
<string name="choose_bt_send">Bluetooth-Sendemethode auswählen</string>
|
||||
@ -92,9 +90,6 @@
|
||||
<string name="rooted_on">Apps nicht ausgrauen, wenn sie Root-Rechte verlangen</string>
|
||||
<string name="ignoreTouch">Touchscreen ignorieren</string>
|
||||
<string name="ignoreTouch_on">Apps anzeigen, die einen Touchscreen benötigen</string>
|
||||
<string name="category_All">Alle</string>
|
||||
<string name="category_Whats_New">Was gibt es Neues</string>
|
||||
<string name="category_Recently_Updated">Kürzlich aktualisiert</string>
|
||||
<string name="local_repo">Lokale Paketquelle</string>
|
||||
<string name="local_repo_running">F-Droid ist zum Tausch bereit</string>
|
||||
<string name="touch_to_configure_local_repo">Berühren, um die Details anzusehen und anderen einen App-Tausch mit Ihnen zu ermöglichen.</string>
|
||||
@ -128,8 +123,8 @@
|
||||
<string name="repo_description">Beschreibung</string>
|
||||
<string name="repo_last_update">Letzte Aktualisierung</string>
|
||||
<string name="repo_name">Name</string>
|
||||
<string name="unsigned_description">Die Liste der Anwendungen konnte nicht überprüft werden.
|
||||
Sie sollten bei Anwendungen vorsichtig sein,
|
||||
<string name="unsigned_description">Die Liste der Anwendungen konnte nicht überprüft werden.
|
||||
Sie sollten bei Anwendungen vorsichtig sein,
|
||||
wenn sie aus nicht signierten Quellen heruntergeladen wurden.</string>
|
||||
<string name="repo_not_yet_updated">Diese Paketquelle wurde noch nicht benutzt.
|
||||
Um darin bereitgestellte Anwendungen anzuzeigen, muss sie aktiviert werden.</string>
|
||||
@ -152,7 +147,6 @@ um Anwendungen daraus installieren zu können.</string>
|
||||
<string name="minsdk_up_to_maxsdk">%1$s bis zu %2$s</string>
|
||||
<string name="not_on_same_wifi">Dieses Gerät befindet sich nicht im selben WLAN, wie die eben hinzugefügte Paketquelle! Versuchen Sie sich mit dem folgenden Netzwerk zu verbinden: %s</string>
|
||||
<string name="requires_features">Erfordert: %1$s</string>
|
||||
<string name="app_icon">App-Symbol</string>
|
||||
<string name="category_Development">Entwicklung</string>
|
||||
<string name="category_Games">Spiele</string>
|
||||
<string name="category_Internet">Internet</string>
|
||||
@ -198,7 +192,6 @@ um Anwendungen daraus installieren zu können.</string>
|
||||
<string name="unstable_updates">Instabile Aktualisierungen</string>
|
||||
<string name="unstable_updates_summary">Aktualisierungen für instabile Version vorschlagen</string>
|
||||
|
||||
<string name="tab_installed_apps">Installiert</string>
|
||||
<string name="menu_changelog">Änderungen</string>
|
||||
<string name="category_Connectivity">Verbindung</string>
|
||||
<string name="category_Sports_Health">Sport & Gesundheit</string>
|
||||
@ -318,8 +311,6 @@ Bitte eine andere Kategorie wählen oder die Paketquellen aktualisieren.</string
|
||||
|
||||
<string name="about_license">Lizenz</string>
|
||||
|
||||
<string name="tab_installed_apps_count">Installiert (%d)</string>
|
||||
<string name="tab_updates_count">Aktualisierung (%d)</string>
|
||||
<string name="status_inserting_apps">Anwendungsdetails werden gespeichert</string>
|
||||
<string name="empty_search_can_update_app_list">Keine passenden Anwendungen zum Aktualisieren.</string>
|
||||
|
||||
|
@ -35,8 +35,6 @@
|
||||
<string name="enable">Ενεργοποίηση</string>
|
||||
<string name="add_key">Προσθήκη κλειδιού</string>
|
||||
<string name="overwrite">Αντικατάσταση</string>
|
||||
<string name="tab_available_apps">Διαθέσιμα</string>
|
||||
<string name="tab_updates">Ενημερώσεις</string>
|
||||
<string name="fdroid_updates_available">Υπάρχουν ενημερώσεις του F-Droid</string>
|
||||
<string name="bluetooth_activity_not_found">Καμία μέθοδος αποστολής με Bluetooth δεν βρέθηκε, επιλέξετε μία!</string>
|
||||
<string name="choose_bt_send">Επιλέξτε τη μέθοδο αποστολής με Bluetooth</string>
|
||||
@ -83,9 +81,6 @@
|
||||
<string name="rooted_on">Να μη γκριζάρονται εφαρμογές που απαιτούν δικαιώματα υπερχρήστη</string>
|
||||
<string name="ignoreTouch">Αγνόηση οθόνης αφής</string>
|
||||
<string name="ignoreTouch_on">Πάντα να περιλαμβάνονται εφαρμογές που απαιτούν οθόνη αφής</string>
|
||||
<string name="category_All">Όλα</string>
|
||||
<string name="category_Whats_New">Τι νέο υπάρχει</string>
|
||||
<string name="category_Recently_Updated">Πρόσφατα Ενημερωμένες</string>
|
||||
<string name="status_download">Λήψη
|
||||
%2$s / %3$s (%4$d%%) από
|
||||
%1$s</string>
|
||||
@ -139,7 +134,6 @@
|
||||
<string name="less">Λιγότερα</string>
|
||||
|
||||
<string name="back">Πίσω</string>
|
||||
<string name="tab_installed_apps">Εγκατεστημένο</string>
|
||||
<string name="notification_summary_more">+%1$d περισσότερα…</string>
|
||||
<string name="send_via_bluetooth">Αποστολή μέσω Bluetooth</string>
|
||||
|
||||
@ -192,7 +186,6 @@
|
||||
<string name="pref_language">Γλώσσα</string>
|
||||
<string name="pref_language_default">Προεπιλογή συστήματος</string>
|
||||
|
||||
<string name="app_icon">Εικονίδιο εφαρμογής</string>
|
||||
<string name="wifi">Wi-Fi</string>
|
||||
<string name="wifi_ap">Σημείο πρόσβασης</string>
|
||||
|
||||
@ -340,8 +333,6 @@
|
||||
<string name="repo_error_empty_username">Κενό όνομα χρήστη, τα διαπιστευτήρια δεν άλλαξαν</string>
|
||||
|
||||
<string name="versions">Εκδόσεις</string>
|
||||
<string name="tab_installed_apps_count">Εγκαταστημένο (%d)</string>
|
||||
<string name="tab_updates_count">Ενημερώσεις (%d)</string>
|
||||
<string name="repo_provider">Αποθετήριο: %s</string>
|
||||
|
||||
<string name="menu_email">Ηλ. ταχυδρομείο δημιουργού</string>
|
||||
|
@ -26,8 +26,6 @@
|
||||
<string name="repo_add_add">Aldoni</string>
|
||||
<string name="cancel">Nuligi</string>
|
||||
<string name="overwrite">Anstataŭigi</string>
|
||||
<string name="tab_available_apps">Disponeblaj</string>
|
||||
<string name="tab_updates">Ĝisdatigeblaj</string>
|
||||
<string name="fdroid_updates_available">F-Droidaj ĝisdatigoj disponeblaj</string>
|
||||
<string name="send_via_bluetooth">Sendi per Bludento</string>
|
||||
<string name="repo_add_url">Deponeja adreso</string>
|
||||
@ -66,9 +64,6 @@
|
||||
<string name="rooted_on">Ne grizigi aplikaĵojn, kiuj postulas ĉefuzantajn privilegiojn</string>
|
||||
<string name="ignoreTouch">Ignori tuŝekranon</string>
|
||||
<string name="ignoreTouch_on">Ĉiam inkluzivi aplikaĵojn, kiuj postulas tuŝekranon</string>
|
||||
<string name="category_All">Ĉiuj</string>
|
||||
<string name="category_Whats_New">Novaj</string>
|
||||
<string name="category_Recently_Updated">Ĵus ĝisdatigitaj</string>
|
||||
<string name="local_repo">Loka deponejo</string>
|
||||
<string name="deleting_repo">Forigado de la deponejo…</string>
|
||||
<string name="adding_apks_format">Aldonado de %s al la deponejo…</string>
|
||||
@ -91,7 +86,6 @@
|
||||
<string name="up_to_maxsdk">Ĝis %s</string>
|
||||
<string name="minsdk_up_to_maxsdk">De %1$s ĝis %2$s</string>
|
||||
<string name="requires_features">Postulas: %1$s</string>
|
||||
<string name="app_icon">Aplikaĵ-emblemo</string>
|
||||
<string name="category_Development">Programado</string>
|
||||
<string name="category_Games">Ludoj</string>
|
||||
<string name="category_Internet">Interreto</string>
|
||||
@ -146,9 +140,6 @@
|
||||
<string name="back">Reen</string>
|
||||
<string name="enable">Aktivigi</string>
|
||||
<string name="add_key">Aldoni ŝlosilon</string>
|
||||
<string name="tab_installed_apps">Instalitaj</string>
|
||||
<string name="tab_installed_apps_count">Instalitaj (%d)</string>
|
||||
<string name="tab_updates_count">Ĝisdatigoj (%d)</string>
|
||||
<string name="notification_summary_more">ankoraŭ +%1$d…</string>
|
||||
<string name="bluetooth_activity_not_found">Neniu Bludenta metodo de sendo trovita, elektu iun!</string>
|
||||
<string name="choose_bt_send">Elektu Bludentan metodon de sendo</string>
|
||||
|
@ -43,8 +43,6 @@
|
||||
<string name="enable">Habilitar</string>
|
||||
<string name="add_key">Agregar clave</string>
|
||||
<string name="overwrite">Sobrescribir</string>
|
||||
<string name="tab_available_apps">Disponible</string>
|
||||
<string name="tab_updates">Actualizaciones</string>
|
||||
<string name="fdroid_updates_available">Actualizaciones de F-Droid disponibles</string>
|
||||
<string name="bluetooth_activity_not_found">No se encontró método de envío Bluetooth, ¡elige uno!</string>
|
||||
<string name="choose_bt_send">Elegir el método de envío Bluetooth</string>
|
||||
@ -92,9 +90,6 @@
|
||||
<string name="rooted_on">No marcar en gris las aplicaciones que requieren permisos de «root»</string>
|
||||
<string name="ignoreTouch">Ignorar pantalla táctil</string>
|
||||
<string name="ignoreTouch_on">Siempre incluir aplicaciones que requieran pantalla táctil</string>
|
||||
<string name="category_All">Todas</string>
|
||||
<string name="category_Whats_New">Novedades</string>
|
||||
<string name="category_Recently_Updated">Recientemente actualizados</string>
|
||||
<string name="local_repo">Repo local</string>
|
||||
<string name="local_repo_running">F-Droid está preparado para intercambiar</string>
|
||||
<string name="touch_to_configure_local_repo">Tocar para ver los detalles y permitir a otros intercambiar aplicaciones.</string>
|
||||
@ -149,7 +144,6 @@ Para ver las aplicaciones que ofrece tienes que activarlo.</string>
|
||||
<string name="minsdk_up_to_maxsdk">De %1$s a %2$s</string>
|
||||
<string name="not_on_same_wifi">¡Tu dispositivo no está en la misma Wi-Fi que el repo que acabas de añadir! Intenta unirte a esta red: %s</string>
|
||||
<string name="requires_features">Requiere: %1$s</string>
|
||||
<string name="app_icon">Icono de la aplicación</string>
|
||||
<string name="category_Development">Desarrollo</string>
|
||||
<string name="category_Games">Juegos</string>
|
||||
<string name="category_Internet">Internet</string>
|
||||
@ -282,7 +276,6 @@ No requiere ningún acceso especial.</string>
|
||||
<string name="theme_dark">Oscuro</string>
|
||||
<string name="unstable_updates">Actualizaciones inestables</string>
|
||||
<string name="unstable_updates_summary">Sugerir actualizaciones a versiones inestables</string>
|
||||
<string name="tab_installed_apps">Instalado</string>
|
||||
<string name="system_install_post_fail_message">La instalación de la extensión de F-Droid con permisos de sistema ha fallado. El método de instalación no está soportado por todas las versiones de Android, así que, por favor, consulta el sistema de gestión de incidencias de F-Droid para más información.</string>
|
||||
<string name="install_confirm_update_system">¿Quieres instalar una actualización
|
||||
de esta aplicación fija? Los datos no se perderán.
|
||||
@ -319,8 +312,6 @@ No requiere ningún acceso especial.</string>
|
||||
<string name="repo_edit_credentials">Cambiar contraseña</string>
|
||||
<string name="repo_error_empty_username">Nombre de usuario vacío, las credenciales no se han cambiado</string>
|
||||
|
||||
<string name="tab_installed_apps_count">Instalado (%d)</string>
|
||||
<string name="tab_updates_count">Actualizaciones (%d)</string>
|
||||
<string name="about_license">Licencia</string>
|
||||
|
||||
<string name="status_inserting_apps">Guardando los detalles de la aplicación</string>
|
||||
|