Merge pull request

This commit is contained in:
David Development 2015-07-18 11:37:01 +02:00
commit 0df4cceb92
56 changed files with 257 additions and 997 deletions

3
.gitmodules vendored
View file

@ -7,9 +7,6 @@
[submodule "ShowcaseView"]
path = ShowcaseView
url = https://github.com/amlcurran/ShowcaseView.git
[submodule "android-HoloCircularProgressBar"]
path = android-HoloCircularProgressBar
url = https://github.com/passsy/android-HoloCircularProgressBar.git
[submodule "custom-tabs-client"]
path = custom-tabs-client
url = https://github.com/GoogleChrome/custom-tabs-client

View file

@ -38,37 +38,29 @@ android {
}
}
configurations.all {
resolutionStrategy {
force 'com.android.support:support-v4:22.2.0'
force 'com.android.support:appcompat-v7:22.2.0'
}
}
dependencies {
// core android studio module
//compile project(':core')
// You must install or update the Google Repository through the SDK manager to use this dependency.
// The Google Repository (separate from the corresponding library) can be found in the Extras category.
// compile 'com.google.android.gms:play-services:4.2.42'
compile files('src/main/libs/gson-2.2.4.jar')
compile files('src/main/libs/jsoup-1.7.2.jar')
compile project(':Changeloglib:ChangeLogLibrary')
compile project(':ownCloud-Account-Importer')
compile project(':ShowcaseView:library')
compile project(':android-HoloCircularProgressBar:library')
compile project(':customtabs')
compile 'com.android.support:support-v4:22.2.0'
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.android.support:design:22.2.0'
compile 'de.mrmaffen:holocircularprogressbar:1.0.1'
compile 'com.google.code.gson:gson:2.3.1'
compile 'com.jakewharton:butterknife:5.1.+'
compile 'com.squareup.picasso:picasso:2.3.1@jar'
compile 'com.sothree.slidinguppanel:library:+'
compile 'de.greenrobot:eventbus:2.2.1'
compile 'de.greenrobot:greendao:1.3.7@jar'
compile 'de.greenrobot:greendao-generator:1.3.1@jar'
compile 'org.freemarker:freemarker:2.3.18@jar'
compile 'org.apache.commons:commons-lang3:3.4'
testCompile 'org.robolectric:robolectric:3.0-rc3'

View file

@ -22,6 +22,7 @@
package de.luhmer.owncloudnewsreader.ListView;
import android.annotation.TargetApi;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
@ -551,6 +552,7 @@ public class SubscriptionExpandableListAdapter extends BaseExpandableListAdapter
}
@SuppressLint("NewApi") // wrongly reports setSelectionFromTop is only available in lollipop
public void notifyCountDataSetChanged(SparseArray<String> unreadCountFolders, SparseArray<String> unreadCountFeeds, SparseArray<String> urlsToFavIcons, SparseArray<String> starredCountFeeds) {
this.unreadCountFolders = unreadCountFolders;
this.unreadCountFeeds = unreadCountFeeds;
@ -585,4 +587,4 @@ public class SubscriptionExpandableListAdapter extends BaseExpandableListAdapter
if(eListTextClickHandler != null)
eListTextClickHandler.onTextClicked(idFeed, context, isFolder, optional_folder_id);
}
}
}

View file

@ -22,7 +22,8 @@
package de.luhmer.owncloudnewsreader;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.support.v7.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.SharedPreferences;
@ -35,6 +36,8 @@ import android.text.InputType;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
@ -46,14 +49,12 @@ import java.net.URL;
import butterknife.ButterKnife;
import butterknife.InjectView;
import butterknife.OnClick;
import de.luhmer.owncloud.accountimporter.ImportAccountsDialogFragment;
import de.luhmer.owncloud.accountimporter.helper.AccountImporter;
import de.luhmer.owncloud.accountimporter.helper.OwnCloudAccount;
import de.luhmer.owncloud.accountimporter.interfaces.IAccountImport;
import de.luhmer.owncloudnewsreader.authentication.AuthenticatorActivity;
import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm;
import de.luhmer.owncloudnewsreader.helper.FontHelper;
import de.luhmer.owncloudnewsreader.reader.owncloud.OwnCloudReaderMethods;
/**
@ -81,6 +82,7 @@ public class LoginDialogFragment extends DialogFragment implements IAccountImpor
private String mPassword;
private String mOc_root_path;
private boolean mCbDisableHostnameVerification;
private boolean showImportAccountButton;
// UI references.
@InjectView(R.id.username) EditText mUsernameView;
@ -122,6 +124,7 @@ public class LoginDialogFragment extends DialogFragment implements IAccountImpor
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
showImportAccountButton = AccountImporter.findAccounts(getActivity()).size() > 0;
//setRetainInstance(true);
@ -131,11 +134,14 @@ public class LoginDialogFragment extends DialogFragment implements IAccountImpor
View view = inflater.inflate(R.layout.dialog_signin, null);
ButterKnife.inject(this, view);
builder.setView(view).setTitle(getString(R.string.action_sign_in_short));
builder.setView(view);
builder.setTitle(getString(R.string.action_sign_in_short));
FontHelper fHelper = new FontHelper(getActivity());
fHelper.setFontForAllChildren(view, fHelper.getFont());
builder.setPositiveButton(getString(R.string.action_sign_in_short), null);
if(showImportAccountButton) {
builder.setNeutralButton(getString(R.string.import_account), null);
}
mImageViewShowPwd.setOnClickListener(ImgViewShowPasswordListener);
@ -161,22 +167,46 @@ public class LoginDialogFragment extends DialogFragment implements IAccountImpor
}
});
AlertDialog dialog = builder.create();
// Set dialog to resize when soft keyboard pops up
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
view.findViewById(R.id.btn_importAccount).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ImportAccountsDialogFragment.show(getActivity(), LoginDialogFragment.this);
}
});
if(AccountImporter.findAccounts(getActivity()).size() <= 0) {
view.findViewById(R.id.btn_importAccount).setVisibility(View.GONE);
}
return builder.create();
return dialog;
}
private View.OnClickListener ImgViewShowPasswordListener = new View.OnClickListener() {
@Override
public void onStart() {
super.onStart();
final AlertDialog dialog = (AlertDialog) getDialog();
// Override the onClickListeners, as the default implementation would dismiss the dialog
if (dialog != null) {
if (showImportAccountButton) {
Button neutralButton = dialog.getButton(DialogInterface.BUTTON_NEUTRAL);
neutralButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ImportAccountsDialogFragment.show(getActivity(), LoginDialogFragment.this);
}
});
}
Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
positiveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
attemptLogin();
}
});
}
}
@Override
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
if(mActivity instanceof AuthenticatorActivity)
mActivity.finish();
}
private View.OnClickListener ImgViewShowPasswordListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
mPasswordVisible = !mPasswordVisible;
@ -189,17 +219,6 @@ public class LoginDialogFragment extends DialogFragment implements IAccountImpor
}
};
@OnClick(R.id.btn_signin) void SignIn() {
attemptLogin();
}
@OnClick(R.id.btn_cancel) void Cancel() {
LoginDialogFragment.this.getDialog().cancel();
if(mActivity instanceof AuthenticatorActivity)
mActivity.finish();
}
private ProgressDialog BuildPendingDialogWhileLoggingIn()
{
ProgressDialog pDialog = new ProgressDialog(getActivity());

View file

@ -452,7 +452,7 @@ public class NewsDetailActivity extends PodcastFragmentActivity {
case R.id.action_tts:
TTSItem ttsItem = new TTSItem(rssItem.getId(), rssItem.getTitle(), rssItem.getTitle() + "\n\n " + Html.fromHtml(rssItem.getBody()).toString(), rssItem.getFeed().getFaviconUrl());
mPodcastPlaybackService.openTtsFeed(ttsItem);
openTTSItem(ttsItem);
break;
case R.id.action_ShareItem:

View file

@ -14,7 +14,6 @@ import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.util.TypedValue;
import android.view.SurfaceView;
@ -44,6 +43,7 @@ import de.luhmer.owncloudnewsreader.helper.ImageHandler;
import de.luhmer.owncloudnewsreader.helper.SizeAnimator;
import de.luhmer.owncloudnewsreader.interfaces.IPlayPausePodcastClicked;
import de.luhmer.owncloudnewsreader.model.PodcastItem;
import de.luhmer.owncloudnewsreader.model.TTSItem;
import de.luhmer.owncloudnewsreader.services.PodcastDownloadService;
import de.luhmer.owncloudnewsreader.services.PodcastPlaybackService;
import de.luhmer.owncloudnewsreader.view.PodcastSlidingUpPanelLayout;
@ -110,13 +110,6 @@ public class PodcastFragmentActivity extends AppCompatActivity implements IPlayP
@Override
protected void onStart() {
super.onStart();
// Bind to LocalService
Intent intent = new Intent(this, PodcastPlaybackService.class);
if(!isMyServiceRunning(PodcastPlaybackService.class)) {
startService(intent);
}
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
@ -551,6 +544,34 @@ public class PodcastFragmentActivity extends AppCompatActivity implements IPlayP
return px;
}
private void openPodcast(PodcastItem podcastItem) {
// Bind to LocalService
Intent intent = new Intent(this, PodcastPlaybackService.class);
if(!isMyServiceRunning(PodcastPlaybackService.class)) {
intent.putExtra(PodcastPlaybackService.PODCAST_ITEM, podcastItem);
startService(intent);
} else {
mPodcastPlaybackService.openFile(podcastItem);
loadPodcastFavIcon();
}
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
protected void openTTSItem(TTSItem ttsItem) {
// Bind to LocalService
Intent intent = new Intent(this, PodcastPlaybackService.class);
if(!isMyServiceRunning(PodcastPlaybackService.class)) {
intent.putExtra(PodcastPlaybackService.TTS_ITEM, ttsItem);
startService(intent);
} else {
mPodcastPlaybackService.openTtsFeed(ttsItem);
loadPodcastFavIcon();
}
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
public void openPodcast(final RssItem rssItem) {
final PodcastItem podcastItem = DatabaseConnectionOrm.ParsePodcastItemFromRssItem(this, rssItem);
@ -559,8 +580,7 @@ public class PodcastFragmentActivity extends AppCompatActivity implements IPlayP
if(file.exists()) {
podcastItem.link = file.getAbsolutePath();
mPodcastPlaybackService.openFile(podcastItem);
loadPodcastFavIcon();// Picasso.with(this).load(rssItem.getFeed().getFaviconUrl()).into(mPodcastFragment.imgFavIcon);
openPodcast(podcastItem);
} else if(!podcastItem.offlineCached) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this)
@ -581,9 +601,7 @@ public class PodcastFragmentActivity extends AppCompatActivity implements IPlayP
alertDialog.setPositiveButton("Stream", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
mPodcastPlaybackService.openFile(podcastItem);
//Picasso.with(PodcastFragmentActivity.this).load(rssItem.getFeed().getFaviconUrl()).into(mPodcastFragment.imgFavIcon);
loadPodcastFavIcon();
openPodcast(podcastItem);
}
});
}

View file

@ -59,6 +59,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Toast;
import java.io.File;
import java.text.DecimalFormat;
@ -655,29 +656,30 @@ public class SettingsActivity extends PreferenceActivity {
protected Boolean doInBackground(Void... params) {
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(_mActivity);
dbConn.resetDatabase();
boolean success = ImageHandler.clearCache(_mActivity);
new GetCacheSizeAsync().execute((Void)null);
return success;
return ImageHandler.clearCache(_mActivity);
}
@Override
protected void onPostExecute(Boolean result) {
pd.dismiss();
if(result)
LoginDialogFragment.ShowAlertDialog("Information" , "Cache is cleared!", _mActivity);
new GetCacheSizeAsync().execute((Void) null);
pd.dismiss();
String resultString;
if(result)
resultString = context.getString(R.string.cache_is_cleared);
else
LoginDialogFragment.ShowAlertDialog("Information", context.getString(R.string.login_dialog_text_something_went_wrong), _mActivity);
resultString = context.getString(R.string.login_dialog_text_something_went_wrong);
Toast.makeText(context, resultString, Toast.LENGTH_SHORT).show();
super.onPostExecute(result);
};
}
public static class GetCacheSizeAsync extends AsyncTask<Void, Void, Void> {
String mSize = "0MB";
String mCount = "0 Files";
int count = 0;
long size = 0;
DecimalFormat dcmFormat = new DecimalFormat("#.##");
private String mSize = "0MB";
private String mCount;
private int count = 0;
private long size = 0;
private DecimalFormat dcmFormat = new DecimalFormat("#.##");
@Override
protected Void doInBackground(Void... params) {
@ -685,11 +687,12 @@ public class SettingsActivity extends PreferenceActivity {
{
getFolderSize(new File(FileUtils.getPath(_mActivity)));
mSize = dcmFormat.format(size / 1024d / 1024d) + "MB";
mCount = String.valueOf(count) + " Files";
}
catch(Exception ex)
{
ex.printStackTrace();
} finally {
mCount = _mActivity.getResources().getQuantityString(R.plurals.number_of_files,count,count);
}
return null;
}

View file

@ -85,7 +85,7 @@ public class GetImageThreaded extends Thread
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(cont);
Feed feed = dbConn.getFeedById(ThreadId);
if(!cacheFile.isFile() || feed.getAvgColour() == null)
if(!cacheFile.isFile() || (feed != null && feed.getAvgColour() == null))
{
File dir = new File(rootPath);
dir.mkdirs();

View file

@ -429,7 +429,7 @@ public class DatabaseConnectionOrm {
String whereStatement = getAllItemsIdsForFolderSQL(ID_FOLDER, onlyUnread, sortDirection);
whereStatement = whereStatement.replace("SELECT " + RssItemDao.Properties.Id.columnName + " FROM " + RssItemDao.TABLENAME, "");
whereStatement += " LIMIT " + limit;
return daoSession.getRssItemDao().queryRaw(whereStatement, null);
return daoSession.getRssItemDao().queryRaw(whereStatement, (String)null);
}
public String getAllItemsIdsForFolderSQL(long ID_FOLDER, boolean onlyUnread, SORT_DIRECTION sortDirection) {

View file

@ -1,117 +0,0 @@
/**
* Android ownCloud News
*
* @author David Luhmer
* @copyright 2013 David Luhmer david-dev@live.de
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.luhmer.owncloudnewsreader.helper;
import android.annotation.TargetApi;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.http.AndroidHttpClient;
import android.os.AsyncTask;
import android.os.Build;
import android.util.Log;
import android.widget.ImageView;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import java.io.InputStream;
import java.lang.ref.WeakReference;
/**
* Created by David on 24.05.13.
*/
public class BitmapDownloaderTask extends AsyncTask<String, Void, Drawable> {
//private String url;
private final WeakReference<ImageView> imageViewReference;
public BitmapDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
@Override
// Actual download method, run in the task thread
protected Drawable doInBackground(String... params) {
// params comes from the execute() call: params[0] is the url.
//return downloadBitmap(params[0]);
return ImageHandler.LoadImageFromWebOperations(params[0]);
}
@Override
// Once the image is downloaded, associates it to the imageView
protected void onPostExecute(Drawable bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageDrawable(bitmap);
//imageView.setImageBitmap(bitmap);
}
}
}
@TargetApi(Build.VERSION_CODES.FROYO)
static Bitmap downloadBitmap(String url) {
final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
final HttpGet getRequest = new HttpGet(url);
try {
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.d("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url);
return null;
}
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
inputStream = entity.getContent();
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
} catch (Exception e) {
// Could provide a more explicit error message for IOException or IllegalStateException
getRequest.abort();
Log.d("ImageDownloader", "Error while retrieving bitmap from " + url);
} finally {
if (client != null) {
client.close();
}
}
return null;
}
}

View file

@ -1,9 +1,11 @@
package de.luhmer.owncloudnewsreader.model;
import java.io.Serializable;
/**
* Created by David on 10.01.2015.
*/
public class TTSItem {
public class TTSItem implements Serializable {
public TTSItem() {

View file

@ -25,25 +25,24 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.message.BasicNameValuePair;
import android.util.Base64;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map.Entry;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
@ -56,17 +55,17 @@ import de.luhmer.owncloudnewsreader.SettingsActivity;
import de.luhmer.owncloudnewsreader.reader.owncloud.API;
import de.luhmer.owncloudnewsreader.ssl.MemorizingTrustManager;
import de.luhmer.owncloudnewsreader.ssl.TLSSocketFactory;
import de.luhmer.owncloudnewsreader.util.Base64;
public class HttpJsonRequest {
//private static final String TAG = "HttpJsonRequest";
//@TargetApi(Build.VERSION_CODES.GINGERBREAD)
@SuppressLint("DefaultLocale")
public static InputStream PerformJsonRequest(String urlString, List<NameValuePair> nameValuePairs, final String username, final String password, Context context) throws AuthenticationException, Exception
public static InputStream PerformJsonRequest(String urlString, HashMap<String,String> nameValuePairs, final String username, final String password, Context context) throws Exception
{
if(nameValuePairs != null)
urlString += "&" + URLEncodedUtils.format(nameValuePairs, "utf-8");
if(nameValuePairs != null) {
urlString += getUrlEncodedString(nameValuePairs);
}
URL url = new URL(API.validateURL(urlString));
@ -114,15 +113,20 @@ public class HttpJsonRequest {
if(HttpResult == HttpURLConnection.HTTP_OK) {
return urlConnection.getInputStream();
} else {
if(urlConnection.getResponseMessage().equals("Unauthorized"))
throw new AuthenticationException(urlConnection.getResponseMessage());
else
throw new Exception(urlConnection.getResponseMessage());
throw new Exception(urlConnection.getResponseMessage());
}
}
private static String getUrlEncodedString(HashMap<String, String> nameValuePairs) throws UnsupportedEncodingException {
String urlString = "";
for(Entry<String,String> entry: nameValuePairs.entrySet()) {
urlString += String.format("&%s=%s", URLEncoder.encode(entry.getKey(), "UTF-8"), URLEncoder.encode(entry.getValue(), "UTF-8"));
}
return urlString;
}
private static HttpURLConnection getUrlConnection(URL url, Context context, String username, String password) throws IOException, KeyManagementException, NoSuchAlgorithmException {
private static HttpURLConnection getUrlConnection(URL url, Context context, String username, String password) throws IOException, KeyManagementException, NoSuchAlgorithmException {
URLConnection urlConnection = url.openConnection();
// If https is used, use MemorizingTrustManager for certificate verification
@ -177,13 +181,18 @@ public class HttpJsonRequest {
// (this still shows a certification dialog, which requires user interaction!)
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
if(sp.getBoolean(SettingsActivity.CB_DISABLE_HOSTNAME_VERIFICATION_STRING, false))
httpsURLConnection.setHostnameVerifier(new AllowAllHostnameVerifier());
httpsURLConnection.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
else
httpsURLConnection.setHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier());
}
if(username != null && password != null)
urlConnection.setRequestProperty("Authorization", "Basic " + Base64.encode((username + ":" + password).getBytes()));
urlConnection.setRequestProperty("Authorization", "Basic " + Base64.encodeToString((username + ":" + password).getBytes(),Base64.DEFAULT));
return (HttpURLConnection) urlConnection;
}
@ -221,11 +230,10 @@ public class HttpJsonRequest {
*/
public static int performCreateFeedRequest(String urlString, String username, String password, Context context, String feedUrl, long folderId) throws Exception {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("url", feedUrl));
nameValuePairs.add(new BasicNameValuePair("folderId", String.valueOf(folderId)));
if(nameValuePairs != null)
urlString += "&" + URLEncodedUtils.format(nameValuePairs, "utf-8");
HashMap<String,String> nameValuePairs = new HashMap<>();
nameValuePairs.put("url", feedUrl);
nameValuePairs.put("folderId", String.valueOf(folderId));
urlString += getUrlEncodedString(nameValuePairs);
URL url = new URL(API.validateURL(urlString));

View file

@ -58,7 +58,7 @@ public class AsyncTask_GetItems extends AsyncTask_Reader {
@Override
protected void onProgressUpdate(Void... values) {
Toast.makeText(context, "Fetched " + totalCount + " items so far..", Toast.LENGTH_SHORT).show();
Toast.makeText(context, context.getResources().getQuantityString(R.plurals.fetched_items_so_far,totalCount,totalCount), Toast.LENGTH_SHORT).show();
super.onProgressUpdate(values);
}

View file

@ -26,9 +26,6 @@ import android.content.Context;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -36,7 +33,6 @@ import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@ -56,19 +52,19 @@ public class OwnCloudReaderMethods {
public static int[] GetUpdatedItems(TAGS tag, Context cont, long lastSync, API api) throws Exception
{
List<NameValuePair> nVPairs = new ArrayList<NameValuePair>();
//nVPairs.add(new BasicNameValuePair("batchSize", maxSizePerSync));
HashMap<String,String> nVPairs = new HashMap<>();
//nVPairs.put("batchSize", maxSizePerSync));
if(tag.equals(TAGS.ALL_STARRED))
{
nVPairs.add(new BasicNameValuePair("type", "2"));
nVPairs.add(new BasicNameValuePair("id", "0"));
nVPairs.put("type", "2");
nVPairs.put("id", "0");
}
else if(tag.equals(TAGS.ALL))
{
nVPairs.add(new BasicNameValuePair("type", "3"));
nVPairs.add(new BasicNameValuePair("id", "0"));
nVPairs.put("type", "3");
nVPairs.put("id", "0");
}
nVPairs.add(new BasicNameValuePair("lastModified", String.valueOf(lastSync)));
nVPairs.put("lastModified", String.valueOf(lastSync));
InputStream is = HttpJsonRequest.PerformJsonRequest(api.getItemUpdatedUrl(), nVPairs, api.getUsername(), api.getPassword(), cont);
@ -89,23 +85,23 @@ public class OwnCloudReaderMethods {
//"type": 1, // the type of the query (Feed: 0, Folder: 1, Starred: 2, All: 3)
public static int GetItems(TAGS tag, Context cont, String offset, boolean getRead, String id, String type, API api) throws Exception
{
List<NameValuePair> nVPairs = new ArrayList<NameValuePair>();
nVPairs.add(new BasicNameValuePair("batchSize", maxSizePerSync));
HashMap<String,String> nVPairs = new HashMap<>();
nVPairs.put("batchSize", maxSizePerSync);
if(tag.equals(TAGS.ALL_STARRED))
{
nVPairs.add(new BasicNameValuePair("type", type));
nVPairs.add(new BasicNameValuePair("id", id));
nVPairs.put("type", type);
nVPairs.put("id", id);
}
else if(tag.equals(TAGS.ALL))
{
nVPairs.add(new BasicNameValuePair("type", type));
nVPairs.add(new BasicNameValuePair("id", id));
nVPairs.put("type", type);
nVPairs.put("id", id);
}
nVPairs.add(new BasicNameValuePair("offset", offset));
nVPairs.put("offset", offset);
if(getRead)
nVPairs.add(new BasicNameValuePair("getRead", "true"));
nVPairs.put("getRead", "true");
else
nVPairs.add(new BasicNameValuePair("getRead", "false"));
nVPairs.put("getRead", "false");
InputStream is = HttpJsonRequest.PerformJsonRequest(api.getItemUrl(), nVPairs, api.getUsername(), api.getPassword(), cont);
@ -370,7 +366,7 @@ public class OwnCloudReaderMethods {
if(jsonIds != null)
{
nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("itemIds", jsonIds));
nameValuePairs.put("itemIds", jsonIds));
}*/
if(tag.equals(TAGS.MARK_ITEM_AS_STARRED))
@ -458,9 +454,6 @@ public class OwnCloudReaderMethods {
} finally {
is.close();
}
}
catch(AuthenticationException ex) {
throw ex;
} catch(Exception ex) {//TODO GET HERE THE RIGHT EXCEPTION
String requestUrl = oc_root_path + OwnCloudConstants.ROOT_PATH_APIv1 + OwnCloudConstants.VERSION_PATH + OwnCloudConstants.JSON_FORMAT;
requestUrl = API.validateURL(requestUrl);

View file

@ -54,7 +54,8 @@ public class PodcastPlaybackService extends Service implements TextToSpeech.OnIn
}
public static final String PODCAST_ITEM = "PODCAST_ITEM";
public static final String TTS_ITEM = "TTS_ITEM";
private PodcastItem mCurrentlyPlayingPodcast;
private TTSItem mCurrentlyPlayingTTS;
@ -141,6 +142,13 @@ public class PodcastPlaybackService extends Service implements TextToSpeech.OnIn
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
if (intent.hasExtra(PODCAST_ITEM)) {
openFile((PodcastItem) intent.getSerializableExtra(PODCAST_ITEM));
} else if(intent.hasExtra(TTS_ITEM)) {
openTtsFeed((TTSItem) intent.getSerializableExtra(TTS_ITEM));
}
}
return Service.START_STICKY;
}

View file

@ -220,9 +220,9 @@ public class MemorizingTrustManager implements X509TrustManager {
}
try {
ks.load(null, null);
ks.load(new java.io.FileInputStream(keyStoreFile), "MTM".toCharArray());
} catch (java.io.FileNotFoundException e) {
Log.i(TAG, "getAppKeyStore(" + keyStoreFile + ") - file does not exist");
if(keyStoreFile.canRead()) {
ks.load(new java.io.FileInputStream(keyStoreFile), "MTM".toCharArray());
}
} catch (Exception e) {
Log.e(TAG, "getAppKeyStore(" + keyStoreFile + ")", e);
}

View file

@ -1,570 +0,0 @@
// Portions copyright 2002, Google, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package de.luhmer.owncloudnewsreader.util;
// This code was converted from code at http://iharder.sourceforge.net/base64/
// Lots of extraneous features were removed.
/* The original code said:
* <p>
* I am placing this code in the Public Domain. Do with it as you will.
* This software comes with no guarantees or warranties but with
* plenty of well-wishing instead!
* Please visit
* <a href="http://iharder.net/xmlizable">http://iharder.net/xmlizable</a>
* periodically to check for updates or to contribute improvements.
* </p>
*
* @author Robert Harder
* @author rharder@usa.net
* @version 1.3
*/
/**
* Base64 converter class. This code is not a complete MIME encoder;
* it simply converts binary data to base64 data and back.
*
* <p>Note {@link CharBase64} is a GWT-compatible implementation of this
* class.
*/
public class Base64 {
/** Specify encoding (value is {@code true}). */
public final static boolean ENCODE = true;
/** Specify decoding (value is {@code false}). */
public final static boolean DECODE = false;
/** The equals sign (=) as a byte. */
private final static byte EQUALS_SIGN = (byte) '=';
/** The new line character (\n) as a byte. */
private final static byte NEW_LINE = (byte) '\n';
/**
* The 64 valid Base64 values.
*/
private final static byte[] ALPHABET =
{(byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F',
(byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K',
(byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P',
(byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
(byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
(byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e',
(byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j',
(byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o',
(byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't',
(byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y',
(byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3',
(byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8',
(byte) '9', (byte) '+', (byte) '/'};
/**
* The 64 valid web safe Base64 values.
*/
private final static byte[] WEBSAFE_ALPHABET =
{(byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F',
(byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K',
(byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P',
(byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
(byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
(byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e',
(byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j',
(byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o',
(byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't',
(byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y',
(byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3',
(byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8',
(byte) '9', (byte) '-', (byte) '_'};
/**
* Translates a Base64 value to either its 6-bit reconstruction value
* or a negative number indicating some other meaning.
**/
private final static byte[] DECODABET = {-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
-5, -5, // Whitespace: Tab and Linefeed
-9, -9, // Decimal 11 - 12
-5, // Whitespace: Carriage Return
-9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
-9, -9, -9, -9, -9, // Decimal 27 - 31
-5, // Whitespace: Space
-9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
62, // Plus sign at decimal 43
-9, -9, -9, // Decimal 44 - 46
63, // Slash at decimal 47
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
-9, -9, -9, // Decimal 58 - 60
-1, // Equals sign at decimal 61
-9, -9, -9, // Decimal 62 - 64
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
-9, -9, -9, -9, -9, -9, // Decimal 91 - 96
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
-9, -9, -9, -9, -9 // Decimal 123 - 127
/* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */
};
/** The web safe decodabet */
private final static byte[] WEBSAFE_DECODABET =
{-9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8
-5, -5, // Whitespace: Tab and Linefeed
-9, -9, // Decimal 11 - 12
-5, // Whitespace: Carriage Return
-9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
-9, -9, -9, -9, -9, // Decimal 27 - 31
-5, // Whitespace: Space
-9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 44
62, // Dash '-' sign at decimal 45
-9, -9, // Decimal 46-47
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
-9, -9, -9, // Decimal 58 - 60
-1, // Equals sign at decimal 61
-9, -9, -9, // Decimal 62 - 64
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
-9, -9, -9, -9, // Decimal 91-94
63, // Underscore '_' at decimal 95
-9, // Decimal 96
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
-9, -9, -9, -9, -9 // Decimal 123 - 127
/* ,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 128 - 139
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243
-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */
};
// Indicates white space in encoding
private final static byte WHITE_SPACE_ENC = -5;
// Indicates equals sign in encoding
private final static byte EQUALS_SIGN_ENC = -1;
/** Defeats instantiation. */
private Base64() {
}
/* ******** E N C O D I N G M E T H O D S ******** */
/**
* Encodes up to three bytes of the array <var>source</var>
* and writes the resulting four Base64 bytes to <var>destination</var>.
* The source and destination arrays can be manipulated
* anywhere along their length by specifying
* <var>srcOffset</var> and <var>destOffset</var>.
* This method does not check to make sure your arrays
* are large enough to accommodate <var>srcOffset</var> + 3 for
* the <var>source</var> array or <var>destOffset</var> + 4 for
* the <var>destination</var> array.
* The actual number of significant bytes in your array is
* given by <var>numSigBytes</var>.
*
* @param source the array to convert
* @param srcOffset the index where conversion begins
* @param numSigBytes the number of significant bytes in your array
* @param destination the array to hold the conversion
* @param destOffset the index where output will be put
* @param alphabet is the encoding alphabet
* @return the <var>destination</var> array
* @since 1.3
*/
private static byte[] encode3to4(byte[] source, int srcOffset,
int numSigBytes, byte[] destination, int destOffset, byte[] alphabet) {
// 1 2 3
// 01234567890123456789012345678901 Bit position
// --------000000001111111122222222 Array position from threeBytes
// --------| || || || | Six bit groups to index alphabet
// >>18 >>12 >> 6 >> 0 Right shift necessary
// 0x3f 0x3f 0x3f Additional AND
// Create buffer with zero-padding if there are only one or two
// significant bytes passed in the array.
// We have to shift left 24 in order to flush out the 1's that appear
// when Java treats a value as negative that is cast from a byte to an int.
int inBuff =
(numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0)
| (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0)
| (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0);
switch (numSigBytes) {
case 3:
destination[destOffset] = alphabet[(inBuff >>> 18)];
destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f];
destination[destOffset + 3] = alphabet[(inBuff) & 0x3f];
return destination;
case 2:
destination[destOffset] = alphabet[(inBuff >>> 18)];
destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f];
destination[destOffset + 3] = EQUALS_SIGN;
return destination;
case 1:
destination[destOffset] = alphabet[(inBuff >>> 18)];
destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
destination[destOffset + 2] = EQUALS_SIGN;
destination[destOffset + 3] = EQUALS_SIGN;
return destination;
default:
return destination;
} // end switch
} // end encode3to4
/**
* Encodes a byte array into Base64 notation.
* Equivalent to calling
* {@code encodeBytes(source, 0, source.length)}
*
* @param source The data to convert
* @since 1.4
*/
public static String encode(byte[] source) {
return encode(source, 0, source.length, ALPHABET, true);
}
/**
* Encodes a byte array into web safe Base64 notation.
*
* @param source The data to convert
* @param doPadding is {@code true} to pad result with '=' chars
* if it does not fall on 3 byte boundaries
*/
public static String encodeWebSafe(byte[] source, boolean doPadding) {
return encode(source, 0, source.length, WEBSAFE_ALPHABET, doPadding);
}
/**
* Encodes a byte array into Base64 notation.
*
* @param source the data to convert
* @param off offset in array where conversion should begin
* @param len length of data to convert
* @param alphabet the encoding alphabet
* @param doPadding is {@code true} to pad result with '=' chars
* if it does not fall on 3 byte boundaries
* @since 1.4
*/
public static String encode(byte[] source, int off, int len, byte[] alphabet,
boolean doPadding) {
byte[] outBuff = encode(source, off, len, alphabet, Integer.MAX_VALUE);
int outLen = outBuff.length;
// If doPadding is false, set length to truncate '='
// padding characters
while (doPadding == false && outLen > 0) {
if (outBuff[outLen - 1] != '=') {
break;
}
outLen -= 1;
}
return new String(outBuff, 0, outLen);
}
/**
* Encodes a byte array into Base64 notation.
*
* @param source the data to convert
* @param off offset in array where conversion should begin
* @param len length of data to convert
* @param alphabet is the encoding alphabet
* @param maxLineLength maximum length of one line.
* @return the BASE64-encoded byte array
*/
public static byte[] encode(byte[] source, int off, int len, byte[] alphabet,
int maxLineLength) {
int lenDiv3 = (len + 2) / 3; // ceil(len / 3)
int len43 = lenDiv3 * 4;
byte[] outBuff = new byte[len43 // Main 4:3
+ (len43 / maxLineLength)]; // New lines
int d = 0;
int e = 0;
int len2 = len - 2;
int lineLength = 0;
for (; d < len2; d += 3, e += 4) {
// The following block of code is the same as
// encode3to4( source, d + off, 3, outBuff, e, alphabet );
// but inlined for faster encoding (~20% improvement)
int inBuff =
((source[d + off] << 24) >>> 8)
| ((source[d + 1 + off] << 24) >>> 16)
| ((source[d + 2 + off] << 24) >>> 24);
outBuff[e] = alphabet[(inBuff >>> 18)];
outBuff[e + 1] = alphabet[(inBuff >>> 12) & 0x3f];
outBuff[e + 2] = alphabet[(inBuff >>> 6) & 0x3f];
outBuff[e + 3] = alphabet[(inBuff) & 0x3f];
lineLength += 4;
if (lineLength == maxLineLength) {
outBuff[e + 4] = NEW_LINE;
e++;
lineLength = 0;
} // end if: end of line
} // end for: each piece of array
if (d < len) {
encode3to4(source, d + off, len - d, outBuff, e, alphabet);
lineLength += 4;
if (lineLength == maxLineLength) {
// Add a last newline
outBuff[e + 4] = NEW_LINE;
e++;
}
e += 4;
}
assert (e == outBuff.length);
return outBuff;
}
/* ******** D E C O D I N G M E T H O D S ******** */
/**
* Decodes four bytes from array <var>source</var>
* and writes the resulting bytes (up to three of them)
* to <var>destination</var>.
* The source and destination arrays can be manipulated
* anywhere along their length by specifying
* <var>srcOffset</var> and <var>destOffset</var>.
* This method does not check to make sure your arrays
* are large enough to accommodate <var>srcOffset</var> + 4 for
* the <var>source</var> array or <var>destOffset</var> + 3 for
* the <var>destination</var> array.
* This method returns the actual number of bytes that
* were converted from the Base64 encoding.
*
*
* @param source the array to convert
* @param srcOffset the index where conversion begins
* @param destination the array to hold the conversion
* @param destOffset the index where output will be put
* @param decodabet the decodabet for decoding Base64 content
* @return the number of decoded bytes converted
* @since 1.3
*/
private static int decode4to3(byte[] source, int srcOffset,
byte[] destination, int destOffset, byte[] decodabet) {
// Example: Dk==
if (source[srcOffset + 2] == EQUALS_SIGN) {
int outBuff =
((decodabet[source[srcOffset]] << 24) >>> 6)
| ((decodabet[source[srcOffset + 1]] << 24) >>> 12);
destination[destOffset] = (byte) (outBuff >>> 16);
return 1;
} else if (source[srcOffset + 3] == EQUALS_SIGN) {
// Example: DkL=
int outBuff =
((decodabet[source[srcOffset]] << 24) >>> 6)
| ((decodabet[source[srcOffset + 1]] << 24) >>> 12)
| ((decodabet[source[srcOffset + 2]] << 24) >>> 18);
destination[destOffset] = (byte) (outBuff >>> 16);
destination[destOffset + 1] = (byte) (outBuff >>> 8);
return 2;
} else {
// Example: DkLE
int outBuff =
((decodabet[source[srcOffset]] << 24) >>> 6)
| ((decodabet[source[srcOffset + 1]] << 24) >>> 12)
| ((decodabet[source[srcOffset + 2]] << 24) >>> 18)
| ((decodabet[source[srcOffset + 3]] << 24) >>> 24);
destination[destOffset] = (byte) (outBuff >> 16);
destination[destOffset + 1] = (byte) (outBuff >> 8);
destination[destOffset + 2] = (byte) (outBuff);
return 3;
}
} // end decodeToBytes
/**
* Decodes data from Base64 notation.
*
* @param s the string to decode (decoded in default encoding)
* @return the decoded data
* @since 1.4
*/
public static byte[] decode(String s) throws Base64DecoderException {
byte[] bytes = s.getBytes();
return decode(bytes, 0, bytes.length);
}
/**
* Decodes data from web safe Base64 notation.
* Web safe encoding uses '-' instead of '+', '_' instead of '/'
*
* @param s the string to decode (decoded in default encoding)
* @return the decoded data
*/
public static byte[] decodeWebSafe(String s) throws Base64DecoderException {
byte[] bytes = s.getBytes();
return decodeWebSafe(bytes, 0, bytes.length);
}
/**
* Decodes Base64 content in byte array format and returns
* the decoded byte array.
*
* @param source The Base64 encoded data
* @return decoded data
* @since 1.3
* @throws Base64DecoderException
*/
public static byte[] decode(byte[] source) throws Base64DecoderException {
return decode(source, 0, source.length);
}
/**
* Decodes web safe Base64 content in byte array format and returns
* the decoded data.
* Web safe encoding uses '-' instead of '+', '_' instead of '/'
*
* @param source the string to decode (decoded in default encoding)
* @return the decoded data
*/
public static byte[] decodeWebSafe(byte[] source)
throws Base64DecoderException {
return decodeWebSafe(source, 0, source.length);
}
/**
* Decodes Base64 content in byte array format and returns
* the decoded byte array.
*
* @param source the Base64 encoded data
* @param off the offset of where to begin decoding
* @param len the length of characters to decode
* @return decoded data
* @since 1.3
* @throws Base64DecoderException
*/
public static byte[] decode(byte[] source, int off, int len)
throws Base64DecoderException {
return decode(source, off, len, DECODABET);
}
/**
* Decodes web safe Base64 content in byte array format and returns
* the decoded byte array.
* Web safe encoding uses '-' instead of '+', '_' instead of '/'
*
* @param source the Base64 encoded data
* @param off the offset of where to begin decoding
* @param len the length of characters to decode
* @return decoded data
*/
public static byte[] decodeWebSafe(byte[] source, int off, int len)
throws Base64DecoderException {
return decode(source, off, len, WEBSAFE_DECODABET);
}
/**
* Decodes Base64 content using the supplied decodabet and returns
* the decoded byte array.
*
* @param source the Base64 encoded data
* @param off the offset of where to begin decoding
* @param len the length of characters to decode
* @param decodabet the decodabet for decoding Base64 content
* @return decoded data
*/
public static byte[] decode(byte[] source, int off, int len, byte[] decodabet)
throws Base64DecoderException {
int len34 = len * 3 / 4;
byte[] outBuff = new byte[2 + len34]; // Upper limit on size of output
int outBuffPosn = 0;
byte[] b4 = new byte[4];
int b4Posn = 0;
int i = 0;
byte sbiCrop = 0;
byte sbiDecode = 0;
for (i = 0; i < len; i++) {
sbiCrop = (byte) (source[i + off] & 0x7f); // Only the low seven bits
sbiDecode = decodabet[sbiCrop];
if (sbiDecode >= WHITE_SPACE_ENC) { // White space Equals sign or better
if (sbiDecode >= EQUALS_SIGN_ENC) {
// An equals sign (for padding) must not occur at position 0 or 1
// and must be the last byte[s] in the encoded value
if (sbiCrop == EQUALS_SIGN) {
int bytesLeft = len - i;
byte lastByte = (byte) (source[len - 1 + off] & 0x7f);
if (b4Posn == 0 || b4Posn == 1) {
throw new Base64DecoderException(
"invalid padding byte '=' at byte offset " + i);
} else if ((b4Posn == 3 && bytesLeft > 2)
|| (b4Posn == 4 && bytesLeft > 1)) {
throw new Base64DecoderException(
"padding byte '=' falsely signals end of encoded value "
+ "at offset " + i);
} else if (lastByte != EQUALS_SIGN && lastByte != NEW_LINE) {
throw new Base64DecoderException(
"encoded value has invalid trailing byte");
}
break;
}
b4[b4Posn++] = sbiCrop;
if (b4Posn == 4) {
outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet);
b4Posn = 0;
}
}
} else {
throw new Base64DecoderException("Bad Base64 input character at " + i
+ ": " + source[i + off] + "(decimal)");
}
}
// Because web safe encoding allows non padding base64 encodes, we
// need to pad the rest of the b4 buffer with equal signs when
// b4Posn != 0. There can be at most 2 equal signs at the end of
// four characters, so the b4 buffer must have two or three
// characters. This also catches the case where the input is
// padded with EQUALS_SIGN
if (b4Posn != 0) {
if (b4Posn == 1) {
throw new Base64DecoderException("single trailing character at offset "
+ (len - 1));
}
b4[b4Posn++] = EQUALS_SIGN;
outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet);
}
byte[] out = new byte[outBuffPosn];
System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
return out;
}
}

View file

@ -1,32 +0,0 @@
// Copyright 2002, Google, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package de.luhmer.owncloudnewsreader.util;
/**
* Exception thrown when encountering an invalid Base64 input character.
*
* @author nelson
*/
public class Base64DecoderException extends Exception {
public Base64DecoderException() {
super();
}
public Base64DecoderException(String s) {
super(s);
}
private static final long serialVersionUID = 1L;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 934 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 476 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 284 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 548 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 987 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1,004 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 291 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 595 B

View file

@ -1,107 +1,94 @@
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".LoginActivity"
android:id="@+id/login_form"
android:layout_width="match_parent"
android:layout_height="match_parent" >
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".LoginActivity"
android:id="@+id/login_form"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/abc_dialog_padding_material"
android:paddingRight="@dimen/abc_dialog_padding_material"
android:paddingTop="@dimen/abc_dialog_padding_material">
<EditText
android:id="@+id/username"
android:inputType="textEmailAddress"
style="@style/LoginDialogEditTextStyle"
android:hint="@string/pref_title_username" />
<FrameLayout
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:id="@+id/username_container">
<EditText
android:id="@+id/username"
android:inputType="textEmailAddress"
android:hint="@string/pref_title_username"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/username_container"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="@+id/password_container">
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="@string/pref_title_password"
style="@style/LoginDialogEditTextStyle"
android:fontFamily="sans-serif"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true" />
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/imgView_ShowPassword"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="right"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:src="@android:drawable/ic_menu_view"/>
</android.support.design.widget.TextInputLayout>
</FrameLayout>
<EditText
android:id="@+id/edt_owncloudRootPath"
android:fontFamily="sans-serif"
android:hint="@string/pref_default_owncloudRootPath"
android:inputType="textUri"
android:maxLines="1"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/pref_default_owncloudRootPath"
style="@style/LoginDialogEditTextStyle" />
<CheckBox
android:id="@+id/cb_AllowAllSSLCertificates"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/pref_title_DisableHostnameVerification" />
<Button
android:id="@+id/btn_importAccount"
<android.support.design.widget.TextInputLayout
android:id="@+id/url_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Import Account from other ownCloud App"/>
android:layout_below="@+id/password_container"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#383E44"
android:layout_marginTop="5dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp" />
<EditText
android:id="@+id/edt_owncloudRootPath"
android:hint="@string/pref_title_owncloudRootPath"
android:inputType="textUri"
android:maxLines="1"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/pref_default_owncloudRootPath"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</android.support.design.widget.TextInputLayout>
<Button
android:id="@+id/btn_cancel"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@android:color/transparent"
android:text="@android:string/cancel" />
<ImageView
android:id="@+id/imgView_ShowPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:src="@drawable/ic_action_visibility"
android:layout_alignTop="@+id/password_container"
android:layout_alignBottom="@+id/password_container"
android:layout_alignRight="@+id/password_container" />
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#383E44"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp" />
<CheckBox
android:id="@+id/cb_AllowAllSSLCertificates"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/pref_title_DisableHostnameVerification"
android:layout_below="@+id/url_container"
android:layout_alignRight="@+id/imgView_ShowPassword"
android:layout_alignEnd="@+id/imgView_ShowPassword" />
<Button
android:id="@+id/btn_signin"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@android:color/transparent"
android:text="@string/action_sign_in_short" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</ScrollView>
</ScrollView>

View file

@ -1,39 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginLeft="10dp"
android:baselineAligned="false"
android:orientation="vertical"
android:paddingTop="10dp" >
<!--
android:background="@drawable/checkbox_background"
android:button="@drawable/checkbox"
-->
<TextView
android:id="@+id/tv_subscription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="center_vertical"
android:singleLine="true"
android:text="@string/empty_view_header"
android:textSize="15sp" />
<TextView
android:id="@+id/summary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="center_vertical"
android:lines="1"
android:text="@string/empty_view_content"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>

View file

@ -6,4 +6,4 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimaryDark"
app:theme="@style/ToolbarTheme" />
android:theme="@style/ToolbarTheme" />

View file

@ -36,7 +36,7 @@
<string name="menu_downloadMoreItems">Download more items</string>
<!-- Import Accounts -->
<string name="import_account_dialog_title">Import Account</string>
<string name="import_account">Import Account</string>
<!-- EMAIL -->
<string name="email_sourceCode">Sourcecode of item - Bugreport</string>
@ -67,7 +67,7 @@
<!-- Strings related to login -->
<string name="pref_title_username">Username</string>
<string name="pref_title_password">Password</string>
<!-- <string name="pref_title_owncloudRootPath">ownCloud root address</string> -->
<string name="pref_title_owncloudRootPath">ownCloud root address</string>
<string name="pref_default_owncloudRootPath">https://1.2.3.4/owncloud</string>
<!-- <string name="pref_default_username">admin</string> -->
@ -87,9 +87,18 @@
<string name="pull_to_refresh_updateFolder">Synchronizing folder</string>
<string name="pull_to_refresh_updateFeeds">Synchronizing feeds</string>
<string name="pull_to_refresh_updateItems">Synchronizing items</string>
<plurals name="fetched_items_so_far">
<item quantity="one">Fetched %d item so far..</item>
<item quantity="other">Fetched %d items so far..</item>
</plurals>
<!-- Strings related to Settings -->
<string name="title_activity_settings">Settings</string>
<string name="cache_is_cleared">Cache is cleared!</string>
<plurals name="number_of_files">
<item quantity="one">%d File</item>
<item quantity="other">%d Files</item>
</plurals>
<!-- General settings -->
<string name="pref_header_general">General</string>

View file

@ -58,15 +58,4 @@
<style name="LoginDialogEditTextStyle" >
<item name="android:layout_marginTop">4dp</item>
<item name="android:layout_marginLeft">4dp</item>
<item name="android:layout_marginRight">4dp</item>
<item name="android:layout_marginBottom">4dp</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<!-- RobotoFontStyle -->
</style>
</resources>

@ -1 +0,0 @@
Subproject commit cea2318fdf41f693fd7ce2dd27fbf551c35c844d

View file

@ -2,7 +2,7 @@
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
@ -11,6 +11,6 @@ buildscript {
allprojects {
repositories {
mavenCentral()
jcenter()
}
}

View file

@ -1,7 +0,0 @@
git rm -r News-Android-App/src/main/res/values-ach/
git rm -r News-Android-App/src/main/res/values-ady/
git rm -r News-Android-App/src/main/res/values-en@pirate/
git rm -r News-Android-App/src/main/res/values-nds/
git rm -r News-Android-App/src/main/res/values-nqo/
git rm -r News-Android-App/src/main/res/values-tzm/
git rm -r News-Android-App/src/main/res/values-ast/

View file

@ -1,7 +1,6 @@
include ':News-Android-App', ':ownCloud-Account-Importer'
include ':Changeloglib:ChangeLogLibrary'
include ':ShowcaseView:library'
include ':android-HoloCircularProgressBar:library'
include 'customtabs'
project(':customtabs').projectDir = new File(settingsDir, './custom-tabs-client/customtabs')