From 4c174f1ae7099bffe0732390c3f6ed0b554ec4ee Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Mon, 28 Nov 2016 16:48:46 -0500 Subject: [PATCH 1/2] Target API 25, fix issue #46, use OkHttp for all http calls --- .gitignore | 2 +- app/build.gradle | 55 +++++++----- .../com/totsp/crossword/BrowseActivity.java | 53 +++++++++++- .../totsp/crossword/HttpDownloadActivity.java | 70 +++++++++++---- .../com/totsp/crossword/PlayActivity.java | 6 +- .../com/totsp/crossword/firstrun/NYTimes.java | 2 - .../crossword/net/AbstractDownloader.java | 5 +- .../crossword/net/AbstractJPZDownloader.java | 3 +- .../com/totsp/crossword/net/Downloaders.java | 44 ++++++---- .../com/totsp/crossword/net/Scrapers.java | 23 +++-- .../totsp/crossword/net/UclickDownloader.java | 4 +- .../versions/AndroidVersionUtils.java | 34 ++------ .../totsp/crossword/versions/DefaultUtil.java | 79 ++++++----------- .../crossword/versions/HoneycombUtil.java | 23 ----- .../crossword/versions/JellyBeanUtil.java | 86 ------------------- build.gradle | 7 +- gradle/wrapper/gradle-wrapper.properties | 4 +- puzlib/build.gradle | 3 + 18 files changed, 240 insertions(+), 263 deletions(-) delete mode 100755 app/src/main/java/com/totsp/crossword/versions/JellyBeanUtil.java diff --git a/.gitignore b/.gitignore index 0c99264f..1f64b485 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,4 @@ gen /*.eml /*.ipr /*.iws - +local.properties diff --git a/app/build.gradle b/app/build.gradle index a64d6fdf..7af4ac51 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,52 +2,69 @@ apply plugin: 'com.android.application' android { Properties props = new Properties() - props.load(new FileInputStream(System.getProperty("user.home")+"/androidkeyinfo.properties")) - compileSdkVersion 22 - buildToolsVersion "22.0.1" + + def propsPath = System.getProperty("user.home") + "/androidkeyinfo.properties" + + if (new File(propsPath).exists()) + props.load(new FileInputStream(propsPath)) + + compileSdkVersion 25 + buildToolsVersion "25.0.1" + defaultConfig { minSdkVersion 9 - targetSdkVersion 22 + targetSdkVersion 25 testInstrumentationRunner "android.test.InstrumentationTestRunner" } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + } + signingConfigs { - debug { - storeFile file(System.getProperty("user.home")+"/androidkeystore") + debugSigned { + storeFile file(System.getProperty("user.home") + "/androidkeystore") storePassword props.getProperty("storePassword") keyAlias "robert \"kebernet\" cooper" keyPassword props.getProperty("keyPassword") } release { - storeFile file(System.getProperty("user.home")+"/androidkeystore") + storeFile file(System.getProperty("user.home") + "/androidkeystore") storePassword props.getProperty("storePassword") keyAlias "robert \"kebernet\" cooper" keyPassword props.getProperty("keyPassword") } } + buildTypes { + debug { + } + debugSigned { + signingConfig signingConfigs.debugSigned + } release { - signingConfig signingConfigs.release - minifyEnabled true - proguardFile file('src/main/assemble/proguard-android.txt') + signingConfig signingConfigs.release + minifyEnabled true + proguardFile file('src/main/assemble/proguard-android.txt') } } } dependencies { - compile 'com.android.support:appcompat-v7:22.1.1' - compile 'com.android.support:recyclerview-v7:22.2.0' + compile 'com.android.support:appcompat-v7:25.0.1' + compile 'com.android.support:recyclerview-v7:25.0.1' compile 'com.google.android.gms:play-services:4.0.30' compile project(":puzlib") compile 'com.nineoldandroids:library:2.4.0' compile 'com.jenzz:materialpreference:1.3' - compile 'com.android.support:design:22.2.0' + compile 'com.android.support:design:25.0.1' compile 'com.google.api-client:google-api-client:1.20.0' compile 'com.google.api-client:google-api-client-android:1.20.0' compile 'com.google.api-client:google-api-client-gson:1.20.0' compile 'com.google.apis:google-api-services-gmail:v1-rev29-1.20.0' androidTestCompile 'com.jayway.android.robotium:robotium-solo:4.3.1' compile 'com.squareup.okhttp3:okhttp:3.2.0' - } task prepareChrome << { @@ -60,7 +77,7 @@ task prepareChrome << { include "**/*.html" filter { it.replaceAll('@@versionCode@@', versionCode) - .replaceAll('@@versionName@@', versionName) + .replaceAll('@@versionName@@', versionName) } } into "build/chrome" @@ -80,15 +97,13 @@ task assembleChrome << { into "build/chrome/vendor/chromium/crx" } } -tasks.assembleChrome.dependsOn prepareChrome -tasks.assembleChrome.dependsOn assembleRelease +tasks.assembleChrome.dependsOn "prepareChrome" +tasks.assembleChrome.dependsOn "assembleRelease" -task packageChrome(type:Zip){ +task packageChrome(type: Zip) { from "build/chrome" archiveName "shortyz-chrome.zip" } tasks.packageChrome.dependsOn assembleChrome tasks.build.dependsOn packageChrome - - diff --git a/app/src/main/java/com/totsp/crossword/BrowseActivity.java b/app/src/main/java/com/totsp/crossword/BrowseActivity.java index 76f6f742..f0c7169a 100755 --- a/app/src/main/java/com/totsp/crossword/BrowseActivity.java +++ b/app/src/main/java/com/totsp/crossword/BrowseActivity.java @@ -1,16 +1,23 @@ package com.totsp.crossword; +import android.Manifest; +import android.app.AlertDialog; import android.app.Dialog; import android.app.NotificationManager; import android.app.ProgressDialog; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; +import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Color; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; +import android.support.annotation.NonNull; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; import android.support.v7.view.ActionMode; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -60,6 +67,7 @@ public class BrowseActivity extends ShortyzActivity implements RecyclerItemClickListener.OnItemClickListener{ private static final String MENU_ARCHIVES = "Archives"; private static final int DOWNLOAD_DIALOG_ID = 0; + private static final int REQUEST_WRITE_STORAGE = 1002; private static final long DAY = 24L * 60L * 60L * 1000L; private static final Logger LOGGER = Logger.getLogger(BrowseActivity.class.getCanonicalName()); private Accessor accessor = Accessor.DATE_DESC; @@ -78,6 +86,7 @@ public class BrowseActivity extends ShortyzActivity implements RecyclerItemClick private boolean viewArchive; private MenuItem gamesItem; private boolean signedIn; + private boolean hasWritePermissions; private int playIcon = R.drawable.ic_play_games_badge_green; private FloatingActionButton download; private int highlightColor; @@ -402,15 +411,47 @@ public void onClick(View v) { } - - highlightColor = getResources().getColor(R.color.accent); normalColor = getResources().getColor(R.color.background_material_light); primaryTextColor = getResources().getColor(R.color.textColorPrimary); + if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { + new AlertDialog.Builder(this) + .setTitle("Allow Permissions") + .setMessage("Please allow writing to storage when prompted. Shortyz needs this permission to store downloaded crossword files and cannot work without it.") + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + ActivityCompat.requestPermissions(BrowseActivity.this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, REQUEST_WRITE_STORAGE); + } + }) + .create() + .show(); + } else { + ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, REQUEST_WRITE_STORAGE); + } + + return; + } else { + hasWritePermissions = true; + } + startInitialActivityOrFinishLoading(); + } + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + switch (requestCode) { + case REQUEST_WRITE_STORAGE: + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + hasWritePermissions = true; + startInitialActivityOrFinishLoading(); + } + } + } + private void startInitialActivityOrFinishLoading() { if (!crosswordsFolder.exists()) { this.downloadTen(); @@ -612,6 +653,8 @@ public void run(){ } private void checkDownload() { + if (!hasWritePermissions) return; + long lastDL = prefs.getLong("dlLast", 0); if (prefs.getBoolean("dlOnStartup", true) && @@ -708,6 +751,8 @@ private void moveTo(File puzFile, File directory){ } private void download(final Date d, final List downloaders, final boolean scrape) { + if (!hasWritePermissions) return; + final Downloaders dls = new Downloaders(prefs, nm, this); LOGGER.info("Downloading from "+downloaders); new Thread(new Runnable() { @@ -729,6 +774,8 @@ public void run() { } private void downloadTen() { + if (!hasWritePermissions) return; + new Thread(new Runnable() { public void run() { Downloaders dls = new Downloaders(prefs, nm, BrowseActivity.this); @@ -754,6 +801,8 @@ public void run() { } private void render() { + if (!hasWritePermissions) return; + if ((this.sources != null) && (this.sources.getAdapter() == null)) { final SourceListAdapter adapter = new SourceListAdapter(this, this.sourceList); this.sources.setAdapter(adapter); diff --git a/app/src/main/java/com/totsp/crossword/HttpDownloadActivity.java b/app/src/main/java/com/totsp/crossword/HttpDownloadActivity.java index de6524a2..f4442d8c 100755 --- a/app/src/main/java/com/totsp/crossword/HttpDownloadActivity.java +++ b/app/src/main/java/com/totsp/crossword/HttpDownloadActivity.java @@ -5,23 +5,30 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.URI; - -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.DefaultHttpClient; +import android.Manifest; import android.app.Activity; +import android.app.AlertDialog; import android.app.ProgressDialog; +import android.content.DialogInterface; import android.content.Intent; +import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.os.Environment; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; import android.widget.Toast; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + public class HttpDownloadActivity extends Activity { + + private static final int REQUEST_EXTERNAL_STORAGE = 1001; + private File crosswordsFolder = new File(Environment.getExternalStorageDirectory(), "crosswords"); /** @@ -61,6 +68,40 @@ public static int copyStream(InputStream sourceStream, OutputStream destinationS public void onCreate(Bundle icicle) { super.onCreate(icicle); + if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { + new AlertDialog.Builder(this) + .setTitle("Allow Permissions") + .setMessage("Please allow writing to storage when prompted. Shortyz needs this permission to store downloaded crossword files and cannot work without it.") + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + ActivityCompat.requestPermissions(HttpDownloadActivity.this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, REQUEST_EXTERNAL_STORAGE); + } + }) + .create() + .show(); + } else { + ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, REQUEST_EXTERNAL_STORAGE); + } + + return; + } + + initializeDownload(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + switch (requestCode) { + case REQUEST_EXTERNAL_STORAGE: + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + initializeDownload(); + } + } + } + + private void initializeDownload() { if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { showSDCardHelp(); finish(); @@ -77,21 +118,20 @@ public void onCreate(Bundle icicle) { dialog.setMessage("Downloading...\n" + filename); dialog.setCancelable(false); - HttpClient client = new DefaultHttpClient(); - HttpGet request = new HttpGet(); + OkHttpClient client = new OkHttpClient(); try { - request.setURI(new URI(u.toString())); + Request request = new Request.Builder() + .url(u.toString()) + .build(); - HttpResponse response = client.execute(request); + Response response = client.newCall(request).execute(); - if (response.getStatusLine() - .getStatusCode() != 200) { + if (response.code() != 200) { throw new IOException("Non 200 downloading..."); } - InputStream is = response.getEntity() - .getContent(); + InputStream is = response.body().byteStream(); File puzFile = new File(crosswordsFolder, filename); FileOutputStream fos = new FileOutputStream(puzFile); copyStream(is, fos); @@ -102,7 +142,7 @@ public void onCreate(Bundle icicle) { } catch (Exception e) { e.printStackTrace(); - Toast t = Toast.makeText(this, "Unabled to download from\n" + u.toString(), Toast.LENGTH_LONG); + Toast t = Toast.makeText(this, "Unable to download from\n" + u.toString(), Toast.LENGTH_LONG); t.show(); } diff --git a/app/src/main/java/com/totsp/crossword/PlayActivity.java b/app/src/main/java/com/totsp/crossword/PlayActivity.java index d3d3f9ad..7f9eac6f 100755 --- a/app/src/main/java/com/totsp/crossword/PlayActivity.java +++ b/app/src/main/java/com/totsp/crossword/PlayActivity.java @@ -353,8 +353,10 @@ public void swipeUp() { this.clue = (TextView) this.findViewById(R.id.clueLine); if (clue != null && clue.getVisibility() != View.GONE) { clue.setVisibility(View.GONE); - clue = (TextView) utils.onActionBarCustom(this, - R.layout.clue_line_only).findViewById(R.id.clueLine); + View custom = utils.onActionBarCustom(this, R.layout.clue_line_only); + if (custom != null) { + clue = (TextView) custom.findViewById(R.id.clueLine); + } } if(this.clue != null) { this.clue.setClickable(true); diff --git a/app/src/main/java/com/totsp/crossword/firstrun/NYTimes.java b/app/src/main/java/com/totsp/crossword/firstrun/NYTimes.java index c57f2a9a..dbd2fe32 100644 --- a/app/src/main/java/com/totsp/crossword/firstrun/NYTimes.java +++ b/app/src/main/java/com/totsp/crossword/firstrun/NYTimes.java @@ -20,8 +20,6 @@ import com.totsp.crossword.shortyz.R; import com.totsp.crossword.shortyz.ShortyzApplication; -import org.apache.http.client.HttpClient; - import java.io.IOException; import java.util.LinkedHashSet; import java.util.regex.Pattern; diff --git a/app/src/main/java/com/totsp/crossword/net/AbstractDownloader.java b/app/src/main/java/com/totsp/crossword/net/AbstractDownloader.java index 2285020b..7371fff3 100755 --- a/app/src/main/java/com/totsp/crossword/net/AbstractDownloader.java +++ b/app/src/main/java/com/totsp/crossword/net/AbstractDownloader.java @@ -91,7 +91,7 @@ protected File download(Date date, String urlSuffix, Map headers return Downloader.DEFERRED_FILE; } } else { - new DefaultUtil().downloadFile(url, f, headers, true, this.getName()); + AndroidVersionUtils.Factory.getInstance().downloadFile(url, f, headers, true, this.getName()); return f; } } catch (IOException e) { @@ -107,13 +107,12 @@ protected File download(Date date, String urlSuffix) { protected File downloadToTempFile(String fullName, Date date) { - DefaultUtil util = new DefaultUtil(); File downloaded = new File(downloadDirectory, this.createFileName(date)); try { URL url = new URL(this.baseUrl + this.createUrlSuffix(date)); LOG.log(Level.INFO, fullName +" "+url.toExternalForm()); - util.downloadFile(url, downloaded, EMPTY_MAP, false, null); + AndroidVersionUtils.Factory.getInstance().downloadFile(url, downloaded, EMPTY_MAP, false, null); } catch (Exception e) { e.printStackTrace(); downloaded.delete(); diff --git a/app/src/main/java/com/totsp/crossword/net/AbstractJPZDownloader.java b/app/src/main/java/com/totsp/crossword/net/AbstractJPZDownloader.java index bce3d663..2bbf7431 100755 --- a/app/src/main/java/com/totsp/crossword/net/AbstractJPZDownloader.java +++ b/app/src/main/java/com/totsp/crossword/net/AbstractJPZDownloader.java @@ -14,6 +14,7 @@ import com.totsp.crossword.io.JPZIO; import com.totsp.crossword.puz.PuzzleMeta; +import com.totsp.crossword.versions.AndroidVersionUtils; import com.totsp.crossword.versions.DefaultUtil; public abstract class AbstractJPZDownloader extends AbstractDownloader { @@ -72,7 +73,7 @@ protected File download(Date date, String urlSuffix, Map headers return Downloader.DEFERRED_FILE; } } else { - new DefaultUtil().downloadFile(url, f, headers, true, this.getName()); + AndroidVersionUtils.Factory.getInstance().downloadFile(url, f, headers, true, this.getName()); return f; } } catch (IOException e) { diff --git a/app/src/main/java/com/totsp/crossword/net/Downloaders.java b/app/src/main/java/com/totsp/crossword/net/Downloaders.java index aad20fd1..b14c1840 100755 --- a/app/src/main/java/com/totsp/crossword/net/Downloaders.java +++ b/app/src/main/java/com/totsp/crossword/net/Downloaders.java @@ -21,6 +21,7 @@ import android.content.SharedPreferences; import android.net.Uri; import android.os.Environment; +import android.support.v4.app.NotificationCompat; import com.totsp.crossword.BrowseActivity; import com.totsp.crossword.PlayActivity; @@ -185,14 +186,18 @@ public void download(Date date, List downloaders) { int i = 1; String contentTitle = "Downloading Puzzles"; - Notification not = new Notification(android.R.drawable.stat_sys_download, contentTitle, - System.currentTimeMillis()); + NotificationCompat.Builder not = + new NotificationCompat.Builder(context) + .setSmallIcon(android.R.drawable.stat_sys_download) + .setContentTitle(contentTitle) + .setWhen(System.currentTimeMillis()); + boolean somethingDownloaded = false; File crosswords = new File(Environment.getExternalStorageDirectory(), "crosswords/"); File archive = new File(Environment.getExternalStorageDirectory(), "crosswords/archive/"); crosswords.mkdirs(); - if ((crosswords != null) && (crosswords.listFiles() != null)) { + if (crosswords.listFiles() != null) { for (File isDel : crosswords.listFiles()) { if (isDel.getName() .endsWith(".tmp")) { @@ -215,10 +220,11 @@ public void download(Date date, List downloaders) { String contentText = "Downloading from " + d.getName(); Intent notificationIntent = new Intent(context, PlayActivity.class); PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0); - not.setLatestEventInfo(context, contentTitle, contentText, contentIntent); + + not.setContentText(contentText).setContentIntent(contentIntent); if (!this.supressMessages && this.notificationManager != null) { - this.notificationManager.notify(0, not); + this.notificationManager.notify(0, not.build()); } File downloaded = new File(crosswords, d.createFileName(date)); @@ -362,15 +368,19 @@ public void supressMessages(boolean b) { private void postDownloadedGeneral() { String contentTitle = "Downloaded new puzzles!"; - Notification not = new Notification( - android.R.drawable.stat_sys_download_done, contentTitle, - System.currentTimeMillis()); + Intent notificationIntent = new Intent(Intent.ACTION_EDIT, null, context, BrowseActivity.class); PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0); - not.setLatestEventInfo(context, contentTitle, - "New puzzles were downloaded.", contentIntent); + + Notification not = new NotificationCompat.Builder(context) + .setSmallIcon(android.R.drawable.stat_sys_download_done) + .setContentTitle(contentTitle) + .setContentText("New puzzles were downloaded.") + .setContentIntent(contentIntent) + .setWhen(System.currentTimeMillis()) + .build(); if (this.notificationManager != null) { this.notificationManager.notify(0, not); @@ -379,15 +389,19 @@ private void postDownloadedGeneral() { private void postDownloadedNotification(int i, String name, File puzFile) { String contentTitle = "Downloaded " + name; - Notification not = new Notification( - android.R.drawable.stat_sys_download_done, contentTitle, - System.currentTimeMillis()); + Intent notificationIntent = new Intent(Intent.ACTION_EDIT, Uri.fromFile(puzFile), context, PlayActivity.class); PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0); - not.setLatestEventInfo(context, contentTitle, puzFile.getName(), - contentIntent); + + Notification not = new NotificationCompat.Builder(context) + .setSmallIcon(android.R.drawable.stat_sys_download_done) + .setContentTitle(contentTitle) + .setContentText(puzFile.getName()) + .setContentIntent(contentIntent) + .setWhen(System.currentTimeMillis()) + .build(); if (this.notificationManager != null) { this.notificationManager.notify(i, not); diff --git a/app/src/main/java/com/totsp/crossword/net/Scrapers.java b/app/src/main/java/com/totsp/crossword/net/Scrapers.java index df2bf75e..7d46d070 100755 --- a/app/src/main/java/com/totsp/crossword/net/Scrapers.java +++ b/app/src/main/java/com/totsp/crossword/net/Scrapers.java @@ -11,6 +11,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; +import android.support.v4.app.NotificationCompat; import com.totsp.crossword.PlayActivity; @@ -49,18 +50,20 @@ public void scrape() { int i = 1; String contentTitle = "Downloading Scrape Puzzles"; - Notification not = new Notification(android.R.drawable.stat_sys_download, contentTitle, - System.currentTimeMillis()); + NotificationCompat.Builder not = new NotificationCompat.Builder(context) + .setSmallIcon(android.R.drawable.stat_sys_download) + .setContentTitle(contentTitle) + .setWhen(System.currentTimeMillis()); for (AbstractPageScraper scraper : scrapers) { try { String contentText = "Downloading from " + scraper.getSourceName(); Intent notificationIntent = new Intent(context, PlayActivity.class); PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0); - not.setLatestEventInfo(context, contentTitle, contentText, contentIntent); + not.setContentText(contentText).setContentIntent(contentIntent); if (!this.supressMessages && this.notificationManager != null) { - this.notificationManager.notify(0, not); + this.notificationManager.notify(0, not.build()); } List downloaded = scraper.scrape(); @@ -86,11 +89,17 @@ public void supressMessages(boolean b) { private void postDownloadedNotification(int i, String name, File puzFile) { String contentTitle = "Downloaded Puzzle From " + name; - Notification not = new Notification(android.R.drawable.stat_sys_download_done, contentTitle, - System.currentTimeMillis()); + Intent notificationIntent = new Intent(Intent.ACTION_EDIT, Uri.fromFile(puzFile), context, PlayActivity.class); PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0); - not.setLatestEventInfo(context, contentTitle, puzFile.getName(), contentIntent); + + Notification not = new NotificationCompat.Builder(context) + .setSmallIcon(android.R.drawable.stat_sys_download_done) + .setContentTitle(contentTitle) + .setContentText(puzFile.getName()) + .setContentIntent(contentIntent) + .setWhen(System.currentTimeMillis()) + .build(); if (this.notificationManager != null) { this.notificationManager.notify(i, not); diff --git a/app/src/main/java/com/totsp/crossword/net/UclickDownloader.java b/app/src/main/java/com/totsp/crossword/net/UclickDownloader.java index e1589ad3..6ad248fc 100755 --- a/app/src/main/java/com/totsp/crossword/net/UclickDownloader.java +++ b/app/src/main/java/com/totsp/crossword/net/UclickDownloader.java @@ -13,6 +13,7 @@ import java.util.logging.Level; import com.totsp.crossword.io.UclickXMLIO; +import com.totsp.crossword.versions.AndroidVersionUtils; import com.totsp.crossword.versions.DefaultUtil; @@ -99,13 +100,12 @@ protected String createUrlSuffix(Date date) { } private File downloadToTempFile(Date date) { - DefaultUtil util = new DefaultUtil(); File f = new File(downloadDirectory, this.createFileName(date)); try { URL url = new URL(this.baseUrl + this.createUrlSuffix(date)); LOG.log(Level.INFO, this.fullName+" "+url.toExternalForm()); - util.downloadFile(url, f, EMPTY_MAP, false, null); + AndroidVersionUtils.Factory.getInstance().downloadFile(url, f, EMPTY_MAP, false, null); } catch (Exception e) { e.printStackTrace(); f = null; diff --git a/app/src/main/java/com/totsp/crossword/versions/AndroidVersionUtils.java b/app/src/main/java/com/totsp/crossword/versions/AndroidVersionUtils.java index a5ddfeb6..f767d2a2 100755 --- a/app/src/main/java/com/totsp/crossword/versions/AndroidVersionUtils.java +++ b/app/src/main/java/com/totsp/crossword/versions/AndroidVersionUtils.java @@ -41,33 +41,13 @@ public static AndroidVersionUtils getInstance() { System.out.println("Creating utils for version: " + android.os.Build.VERSION.SDK_INT); - - try { - if(android.os.Build.VERSION.SDK_INT >= 16){ - return INSTANCE = (AndroidVersionUtils) Class.forName( - "com.totsp.crossword.versions.JellyBeanUtil") - .newInstance(); - } - switch (android.os.Build.VERSION.SDK_INT) { - case 10: - case 9: - System.out.println("Using Gingerbread."); - return INSTANCE = (AndroidVersionUtils) Class.forName( - "com.totsp.crossword.versions.GingerbreadUtil") - .newInstance(); - case 12: - case 13: - case 14: - case 15: - - return INSTANCE = (AndroidVersionUtils) Class.forName( - "com.totsp.crossword.versions.HoneycombUtil") - .newInstance(); - default: - return INSTANCE = new DefaultUtil(); - } - } catch (Exception e) { - return INSTANCE = new DefaultUtil(); + switch (android.os.Build.VERSION.SDK_INT) { + case 10: + case 9: + System.out.println("Using Gingerbread."); + return INSTANCE = new GingerbreadUtil(); + default: + return INSTANCE = new HoneycombUtil(); } } } diff --git a/app/src/main/java/com/totsp/crossword/versions/DefaultUtil.java b/app/src/main/java/com/totsp/crossword/versions/DefaultUtil.java index 78138da9..c01ca0ab 100755 --- a/app/src/main/java/com/totsp/crossword/versions/DefaultUtil.java +++ b/app/src/main/java/com/totsp/crossword/versions/DefaultUtil.java @@ -8,12 +8,6 @@ import java.util.Map; import java.util.Map.Entry; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.DefaultHttpClient; - -import android.app.Activity; import android.content.Context; import android.net.Uri; import android.support.v7.app.ActionBarActivity; @@ -23,38 +17,39 @@ import android.view.Window; import com.totsp.crossword.io.IO; -import com.totsp.crossword.net.AbstractDownloader; import com.totsp.crossword.puz.PuzzleMeta; -public class DefaultUtil implements AndroidVersionUtils { - public void setContext(Context ctx) { - // TODO Auto-generated method stub - } +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +public abstract class DefaultUtil implements AndroidVersionUtils { + public abstract void setContext(Context ctx); public boolean downloadFile(URL url, File destination, Map headers, boolean notification, String title) { - DefaultHttpClient httpclient = new DefaultHttpClient(); - httpclient - .getParams() - .setParameter( - "User-Agent", - "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6"); + OkHttpClient httpclient = new OkHttpClient(); + + Request.Builder requestBuilder = new Request.Builder() + .url(url.toString()); - HttpGet httpget = new HttpGet(url.toString()); - for(Entry e : headers.entrySet()){ - httpget.setHeader(e.getKey(), e.getValue()); + for (Entry e : headers.entrySet()){ + requestBuilder.header(e.getKey(), e.getValue()); } + try { - HttpResponse response = httpclient.execute(httpget); - HttpEntity entity = response.getEntity(); + Response response = httpclient.newCall(requestBuilder.build()).execute(); + FileOutputStream fos = new FileOutputStream(destination); ByteArrayOutputStream baos = new ByteArrayOutputStream(); - IO.copyStream(entity.getContent(), baos); - if(url.toExternalForm().indexOf("crnet") != -1){ + IO.copyStream(response.body().byteStream(), baos); + + if (url.toExternalForm().contains("crnet")){ System.out.println(new String(baos.toByteArray())); } + IO.copyStream(new ByteArrayInputStream(baos.toByteArray()), fos); fos.close(); return true; @@ -66,43 +61,25 @@ public boolean downloadFile(URL url, File destination, } - public void finishOnHomeButton(ActionBarActivity a) { - // no op - } + public abstract void finishOnHomeButton(ActionBarActivity a); - public void holographic(ActionBarActivity playActivity) { - // no op - } + public abstract void holographic(ActionBarActivity playActivity); - public void onActionBarWithText(MenuItem a) { - // no op - } + public abstract void onActionBarWithText(MenuItem a); - public void onActionBarWithText(SubMenu reveal) { - // no op - } + public abstract void onActionBarWithText(SubMenu reveal); - public void storeMetas(Uri uri, PuzzleMeta meta) { - // no op - } + public abstract void storeMetas(Uri uri, PuzzleMeta meta); - public View onActionBarCustom(ActionBarActivity a, int id) { - return null; - } + public abstract View onActionBarCustom(ActionBarActivity a, int id); public void hideWindowTitle(ActionBarActivity a) { a.requestWindowFeature(Window.FEATURE_NO_TITLE); } - public void hideActionBar(ActionBarActivity a) { - ; //no op; - } + public abstract void hideActionBar(ActionBarActivity a); - public void onActionBarWithoutText(MenuItem a) { - ; //no op; - } + public abstract void onActionBarWithoutText(MenuItem a); - public void hideTitleOnPortrait(ActionBarActivity a) { - ; //no op; - } + public abstract void hideTitleOnPortrait(ActionBarActivity a); } diff --git a/app/src/main/java/com/totsp/crossword/versions/HoneycombUtil.java b/app/src/main/java/com/totsp/crossword/versions/HoneycombUtil.java index d180dbdc..76a5ce2f 100755 --- a/app/src/main/java/com/totsp/crossword/versions/HoneycombUtil.java +++ b/app/src/main/java/com/totsp/crossword/versions/HoneycombUtil.java @@ -77,30 +77,7 @@ public void hideTitleOnPortrait(ActionBarActivity a) { public void onActionBarWithText(SubMenu a) { this.onActionBarWithText(a.getItem()); } - - @Override - public boolean downloadFile(URL url, File destination, Map headers, boolean notification, - String title) { - DownloadManager mgr = (DownloadManager) ctx.getSystemService(Context.DOWNLOAD_SERVICE); - - Request request = new Request(Uri.parse(url.toString())); - request.setDestinationUri(Uri.fromFile(destination)); - - - for (Entry entry : headers.entrySet()) { - request.addRequestHeader(entry.getKey(), entry.getValue()); - } - request.setMimeType("application/x-crossword"); - - request.setNotificationVisibility(notification ? Request.VISIBILITY_VISIBLE : Request.VISIBILITY_HIDDEN); - - request.setTitle(title); - mgr.enqueue(request); - - return false; - } - public View onActionBarCustom(ActionBarActivity a, int id) { System.out.println("Setting custom ActionBar view"); ActionBar bar = a.getSupportActionBar(); diff --git a/app/src/main/java/com/totsp/crossword/versions/JellyBeanUtil.java b/app/src/main/java/com/totsp/crossword/versions/JellyBeanUtil.java deleted file mode 100755 index c1728111..00000000 --- a/app/src/main/java/com/totsp/crossword/versions/JellyBeanUtil.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.totsp.crossword.versions; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.net.URL; -import java.util.Map; -import java.util.Map.Entry; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.DefaultHttpClient; - -import com.totsp.crossword.io.IO; -import com.totsp.crossword.net.AbstractDownloader; - -public class JellyBeanUtil extends HoneycombUtil { - - - @Override - public boolean downloadFile(URL url, File destination, - Map headers, boolean notification, String title) { - - DefaultHttpClient httpclient = new DefaultHttpClient(); - httpclient - .getParams() - .setParameter( - "User-Agent", - "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6"); - - HttpGet httpget = new HttpGet(url.toString()); - for(Entry e : headers.entrySet()){ - httpget.setHeader(e.getKey(), e.getValue()); - } - try { - HttpResponse response = httpclient.execute(httpget); - HttpEntity entity = response.getEntity(); - FileOutputStream fos = new FileOutputStream(destination); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - IO.copyStream(entity.getContent(), baos); - if(url.toExternalForm().indexOf("crnet") != -1){ - System.out.println(new String(baos.toByteArray())); - } - IO.copyStream(new ByteArrayInputStream(baos.toByteArray()), fos); - fos.close(); - return true; - - } catch (Exception e) { - e.printStackTrace(); - return false; - } - // try { - // HttpURLConnection connection = (HttpURLConnection) - // url.openConnection(); - // connection.setDoOutput(true); - // connection.setRequestMethod("GET"); - // - // for (Entry entry : headers.entrySet()) { - // System.out.println(entry.getKey()+" "+entry.getValue()); - // connection.setRequestProperty(entry.getKey(), entry.getValue()); - // } - // - // System.out.println(url + "\n Response : " + - // connection.getResponseCode()); - // - // if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { - // FileOutputStream fos = new FileOutputStream(destination); - // AbstractDownloader.copyStream(connection.getInputStream(), fos); - // fos.close(); - // - // return true; - // } else { - // ByteArrayOutputStream baos = new ByteArrayOutputStream(); - // JPZIO.copyStream(connection.getInputStream(), baos); - // System.out.println("CONTENT: "+ new String(baos.toByteArray())); - // throw new RuntimeException(); - // } - // } catch (IOException ioe) { - // throw new RuntimeException(ioe); - // } - } - -} diff --git a/build.gradle b/build.gradle index 5e4a2d2f..d27cf137 100755 --- a/build.gradle +++ b/build.gradle @@ -1,17 +1,16 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { - mavenCentral() - + jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.0-alpha1' + classpath 'com.android.tools.build:gradle:2.2.2' } } allprojects { repositories { - mavenCentral() + jcenter() maven { url 'https://oss.sonatype.org/content/groups/public' } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8c224ccf..2783f3b9 100755 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Mar 15 15:37:31 EDT 2016 +#Mon Nov 28 13:54:41 EST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip diff --git a/puzlib/build.gradle b/puzlib/build.gradle index 41389e5a..823f3231 100755 --- a/puzlib/build.gradle +++ b/puzlib/build.gradle @@ -4,4 +4,7 @@ group 'com.totsp.crossword' dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile group: 'junit', name: 'junit', version: '3.+' + + sourceCompatibility = 1.7 + targetCompatibility = 1.7 } From 9013a11a11219fcd6bf7d87eac8349e916c5f9b0 Mon Sep 17 00:00:00 2001 From: Paul Irwin Date: Tue, 29 Nov 2016 15:04:43 -0500 Subject: [PATCH 2/2] Assign fluent call result for request headers in DefaultUtil --- app/src/main/java/com/totsp/crossword/versions/DefaultUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/totsp/crossword/versions/DefaultUtil.java b/app/src/main/java/com/totsp/crossword/versions/DefaultUtil.java index c01ca0ab..d4f5abfc 100755 --- a/app/src/main/java/com/totsp/crossword/versions/DefaultUtil.java +++ b/app/src/main/java/com/totsp/crossword/versions/DefaultUtil.java @@ -35,7 +35,7 @@ public boolean downloadFile(URL url, File destination, .url(url.toString()); for (Entry e : headers.entrySet()){ - requestBuilder.header(e.getKey(), e.getValue()); + requestBuilder = requestBuilder.header(e.getKey(), e.getValue()); } try {