Add original project.
42
.gitignore
vendored
@ -33,3 +33,45 @@ google-services.json
|
||||
# Android Profiling
|
||||
*.hprof
|
||||
|
||||
## Suggested ^^
|
||||
|
||||
## From TicTacToe project for good measure. vv
|
||||
|
||||
# Gradle files
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
# Log/OS Files
|
||||
*.log
|
||||
|
||||
# Android Studio generated files and folders
|
||||
captures/
|
||||
.externalNativeBuild/
|
||||
.cxx/
|
||||
*.apk
|
||||
output.json
|
||||
|
||||
# IntelliJ
|
||||
*.iml
|
||||
.idea/
|
||||
misc.xml
|
||||
deploymentTargetDropDown.xml
|
||||
render.experimental.xml
|
||||
|
||||
# Keystore files
|
||||
*.jks
|
||||
*.keystore
|
||||
|
||||
# Google Services (e.g. APIs or Firebase)
|
||||
google-services.json
|
||||
|
||||
# Android Profiling
|
||||
*.hprof
|
||||
/app/debug/output-metadata.json
|
||||
|
||||
# Ha!
|
||||
keystore/*
|
||||
release
|
||||
|
1
app/.gitignore
vendored
Executable file
@ -0,0 +1 @@
|
||||
/build
|
33
app/build.gradle
Executable file
@ -0,0 +1,33 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 24
|
||||
buildToolsVersion "24.0.2"
|
||||
defaultConfig {
|
||||
applicationId "com.hyperling.apps.wheretheriverfrowns"
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 24
|
||||
versionCode 3
|
||||
versionName "1.02"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
|
||||
exclude group: 'com.android.support', module: 'support-annotations'
|
||||
})
|
||||
compile 'com.android.support:appcompat-v7:24.2.1'
|
||||
compile 'com.android.support:support-v4:24.2.1'
|
||||
compile 'com.android.support:support-vector-drawable:24.2.1'
|
||||
testCompile 'junit:junit:4.12'
|
||||
compile 'com.google.android.gms:play-services-appindexing:8.4.0'
|
||||
}
|
17
app/proguard-rules.pro
vendored
Executable file
@ -0,0 +1,17 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /home/ling/Android/Sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
@ -0,0 +1,26 @@
|
||||
package com.hyperling.apps.wheretheriverfrowns;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumentation test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() throws Exception {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getTargetContext();
|
||||
|
||||
assertEquals("com.hyperling.apps.wheretheriverfrowns", appContext.getPackageName());
|
||||
}
|
||||
}
|
49
app/src/main/AndroidManifest.xml
Executable file
@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.hyperling.apps.wheretheriverfrowns">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:fullBackupContent="false"
|
||||
android:icon="@drawable/wtrf"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/wtrf">
|
||||
<activity android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service android:name=".MyService" />
|
||||
|
||||
<receiver android:name=".ServiceReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="com.hyperling.wheretheriverfrowns.ALARM_STARTED" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||
|
||||
<data android:scheme="package" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<activity android:name=".DebugActivity"/>
|
||||
<!-- ATTENTION: This was auto-generated to add Google Play services to your project for
|
||||
App Indexing. See https://g.co/AppIndexing/AndroidStudio for more information. -->
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.version"
|
||||
android:value="@integer/google_play_services_version" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
158
app/src/main/java/com/hyperling/apps/wheretheriverfrowns/DebugActivity.java
Executable file
@ -0,0 +1,158 @@
|
||||
package com.hyperling.apps.wheretheriverfrowns;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class DebugActivity extends AppCompatActivity {
|
||||
|
||||
private ActionBar actionBar;
|
||||
|
||||
private SharedPreferences sharedPreferences;
|
||||
|
||||
private String sharedPreferencesKey, debugKey,
|
||||
TAG;
|
||||
|
||||
private LinearLayout debugLayout;
|
||||
|
||||
private Button btnDebug, btnResetPreferences;
|
||||
|
||||
private boolean DEBUG;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_debug);
|
||||
|
||||
// Load Strings
|
||||
sharedPreferencesKey = getString(R.string.sharedPreferencesKey);
|
||||
debugKey = getString(R.string.debugKey);
|
||||
|
||||
TAG = getString(R.string.TAG);
|
||||
|
||||
// Get Preferences
|
||||
sharedPreferences = getSharedPreferences(sharedPreferencesKey, MODE_PRIVATE);
|
||||
DEBUG = sharedPreferences.getBoolean(debugKey, false);
|
||||
|
||||
Map<String, ?> sharedPreferencesAll = sharedPreferences.getAll();
|
||||
|
||||
// Initialize UI
|
||||
actionBar = DebugActivity.this.getSupportActionBar();
|
||||
actionBar.setTitle(getString(R.string.debugActivityTitle));
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
btnDebug = (Button) findViewById(R.id.btnDebugExit);
|
||||
btnResetPreferences = (Button) findViewById(R.id.btnResetPreferences);
|
||||
|
||||
// Disable buttons so they aren't accidentally clicked
|
||||
setButtonsEnabled(false);
|
||||
|
||||
if (DEBUG){
|
||||
btnDebug.setBackgroundColor(Color.GREEN);
|
||||
}
|
||||
else{
|
||||
btnDebug.setBackgroundColor(Color.RED);
|
||||
}
|
||||
btnDebug.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putBoolean(debugKey, !DEBUG);
|
||||
editor.apply();
|
||||
|
||||
resetScreen();
|
||||
}
|
||||
});
|
||||
|
||||
btnResetPreferences.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.clear();
|
||||
editor.apply();
|
||||
|
||||
resetScreen();
|
||||
}
|
||||
});
|
||||
|
||||
debugLayout = (LinearLayout) findViewById(R.id.debugLayout);
|
||||
|
||||
for (String key : sharedPreferencesAll.keySet()){
|
||||
if (DEBUG){
|
||||
Log.d(TAG, "DebugActivity: key=" + key + " value=" + sharedPreferencesAll.get(key));
|
||||
}
|
||||
TextView textView = new TextView(btnDebug.getContext());
|
||||
textView.setText(key + "=" + sharedPreferencesAll.get(key));
|
||||
|
||||
debugLayout.addView(textView);
|
||||
}
|
||||
|
||||
Runnable runnable = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (DEBUG) Log.d(TAG, "DebugActivity: Waiting 2 seconds to enable buttons.");
|
||||
synchronized (this){
|
||||
try{
|
||||
wait(2000);
|
||||
if (DEBUG) Log.d(TAG, "DebugActivity: Done waiting.");
|
||||
}
|
||||
catch (Exception e){
|
||||
e.printStackTrace();
|
||||
if (DEBUG) Log.d(TAG, "DebugActivity: Failed to wait.");
|
||||
}
|
||||
}
|
||||
enableButtonsHandler.sendEmptyMessage(0);
|
||||
}
|
||||
};
|
||||
|
||||
Thread thread = new Thread(runnable);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
int id = item.getItemId();
|
||||
|
||||
switch (id){
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void resetScreen(){
|
||||
finish();
|
||||
Intent refreshDebugActivity = new Intent(DebugActivity.this, DebugActivity.class);
|
||||
startActivity(refreshDebugActivity);
|
||||
}
|
||||
|
||||
private void setButtonsEnabled(boolean enabled){
|
||||
btnDebug.setEnabled(enabled);
|
||||
btnResetPreferences.setEnabled(enabled);
|
||||
}
|
||||
|
||||
private Handler enableButtonsHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
super.handleMessage(msg);
|
||||
|
||||
setButtonsEnabled(true);
|
||||
}
|
||||
};
|
||||
}
|
394
app/src/main/java/com/hyperling/apps/wheretheriverfrowns/MainActivity.java
Executable file
@ -0,0 +1,394 @@
|
||||
package com.hyperling.apps.wheretheriverfrowns;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.StrictMode;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.gms.appindexing.Action;
|
||||
import com.google.android.gms.appindexing.AppIndex;
|
||||
import com.google.android.gms.appindexing.Thing;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private SharedPreferences sharedPreferences;
|
||||
|
||||
private String sharedPreferencesKey, topArticleKey, externalBrowserKey, checkForNewArticlesKey, debugKey,
|
||||
networkConnected, networkRoaming, networkDisconnected,
|
||||
TAG,
|
||||
action, url;
|
||||
|
||||
private ActionBar actionBar;
|
||||
|
||||
private ProgressBar progressBar;
|
||||
|
||||
private LinearLayout layout;
|
||||
private Button btnExample;
|
||||
|
||||
private boolean homePage, externalBrowser;
|
||||
|
||||
private boolean DEBUG;
|
||||
|
||||
private WebPage webPage;
|
||||
|
||||
private int debugCount, debugMax = 13;
|
||||
/**
|
||||
* ATTENTION: This was auto-generated to implement the App Indexing API.
|
||||
* See https://g.co/AppIndexing/AndroidStudio for more information.
|
||||
*/
|
||||
private GoogleApiClient client;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
/*** Initialize Strings ***/
|
||||
// Keys
|
||||
sharedPreferencesKey = getResources().getString(R.string.sharedPreferencesKey);
|
||||
topArticleKey = getResources().getString(R.string.topArticleKey);
|
||||
externalBrowserKey = getResources().getString(R.string.externalBrowserKey);
|
||||
checkForNewArticlesKey = getResources().getString(R.string.checkForNewArticlesKey);
|
||||
debugKey = getString(R.string.debugKey);
|
||||
|
||||
// Strings
|
||||
networkConnected = getResources().getString(R.string.networkConnected);
|
||||
networkRoaming = getResources().getString(R.string.networkRoaming);
|
||||
networkDisconnected = getResources().getString(R.string.networkDisconnected);
|
||||
TAG = getResources().getString(R.string.TAG);
|
||||
|
||||
/*** Get Preferences ***/
|
||||
sharedPreferences = getSharedPreferences(sharedPreferencesKey, MODE_PRIVATE);
|
||||
externalBrowser = sharedPreferences.getBoolean(externalBrowserKey, true);
|
||||
DEBUG = sharedPreferences.getBoolean(debugKey, false);
|
||||
|
||||
/*** Initialize UI Objects ***/
|
||||
actionBar = MainActivity.this.getSupportActionBar();
|
||||
actionBar.setTitle(getString(R.string.app_title));
|
||||
actionBar.setHomeButtonEnabled(true);
|
||||
|
||||
progressBar = (ProgressBar) findViewById(R.id.progressBar);
|
||||
|
||||
layout = (LinearLayout) findViewById(R.id.layout);
|
||||
layout.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
debugCount++;
|
||||
if (debugCount >= debugMax) {
|
||||
Intent debugIntent = new Intent(MainActivity.this, DebugActivity.class);
|
||||
startActivity(debugIntent);
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "MainActivity: debugCount=" + debugCount);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
btnExample = (Button) findViewById(R.id.btnExample);
|
||||
|
||||
// Data checks
|
||||
action = MainActivity.this.getIntent().getAction();
|
||||
if (action.isEmpty() || !action.contains("http")) {
|
||||
url = getResources().getString(R.string.allStories);
|
||||
homePage = true;
|
||||
} else {
|
||||
url = action;
|
||||
homePage = false;
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, "MainActivity: action=" + action + " url=" + url);
|
||||
|
||||
// Allow webpage download
|
||||
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
|
||||
StrictMode.setThreadPolicy(policy);
|
||||
|
||||
// Start the fun
|
||||
this.refreshWebPage();
|
||||
|
||||
// ATTENTION: This was auto-generated to implement the App Indexing API.
|
||||
// See https://g.co/AppIndexing/AndroidStudio for more information.
|
||||
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
|
||||
}
|
||||
|
||||
private String isNetworkAvailable() {
|
||||
NetworkInfo info = ((ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
|
||||
|
||||
try {
|
||||
if (info.isConnected()) {
|
||||
return networkConnected;
|
||||
} else if (info.isRoaming()) {
|
||||
return networkRoaming;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return networkDisconnected;
|
||||
}
|
||||
|
||||
private void refreshWebPage() {
|
||||
String status = isNetworkAvailable();
|
||||
|
||||
if (status.equals(networkConnected)) {
|
||||
Runnable getWebsiteData = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
webPage = new WebPage(getBaseContext(), url);
|
||||
loadArticles.sendEmptyMessage(0);
|
||||
}
|
||||
};
|
||||
|
||||
Thread t = new Thread(getWebsiteData);
|
||||
progressBar.setIndeterminate(true);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
t.start();
|
||||
} else if (status.equals(networkRoaming)) {
|
||||
Toast.makeText(this, "Currently Roaming -- Not Updating", Toast.LENGTH_LONG).show();
|
||||
} else if (status.equals(networkDisconnected)) {
|
||||
Toast.makeText(this, "Network Connection Not Found", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
private Handler loadArticles = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
|
||||
layout.removeAllViews();
|
||||
|
||||
progressBar.setMax(webPage.getTitles().size());
|
||||
|
||||
int index;
|
||||
|
||||
for (String title : webPage.getTitles()) {
|
||||
index = webPage.getTitles().indexOf(title);
|
||||
|
||||
progressBar.setProgress(index);
|
||||
progressBar.invalidate();
|
||||
|
||||
String date = webPage.getDates().get(index);
|
||||
if (DEBUG) Log.d(TAG, "MainActivity: date=" + date + " title=" + title);
|
||||
String text = date + '\n' + title;
|
||||
|
||||
// If we are on all-stories and on the first article
|
||||
if (homePage && webPage.getTitles().indexOf(title) == 0) {
|
||||
// Only update the Top Article if necessary
|
||||
String oldTitle = sharedPreferences.getString(topArticleKey, "");
|
||||
if (!oldTitle.equals(title)) {
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putString(topArticleKey, title);
|
||||
editor.apply();
|
||||
if (DEBUG) Log.d(TAG, "MainActivity: Top Article updated.");
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "MainActivity: title=" + title);
|
||||
Log.d(TAG, "MainActivity: oldTitle=" + oldTitle);
|
||||
Log.d(TAG, "MainActivity: sharedPreferences.TopArticle=" + sharedPreferences.getString(topArticleKey, ""));
|
||||
}
|
||||
}
|
||||
|
||||
// Display all articles
|
||||
if (!action.equals(url)) {
|
||||
TextView spacer = new TextView(btnExample.getContext());
|
||||
Button btn = new Button(btnExample.getContext());
|
||||
btn.setText(text);
|
||||
if (sharedPreferences.getBoolean(title, false)) {
|
||||
btn.setBackgroundColor(getResources().getColor(R.color.articleRead));
|
||||
} else {
|
||||
btn.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
|
||||
}
|
||||
btn.setTextColor(Color.WHITE);
|
||||
btn.setVisibility(View.VISIBLE);
|
||||
btn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Button b = (Button) v;
|
||||
|
||||
String text = b.getText().toString();
|
||||
int newline = text.indexOf('\n');
|
||||
|
||||
String articleTitle = text.substring(newline + 1);
|
||||
String articleLink = webPage.getLinks().get(webPage.getTitles().indexOf(articleTitle));
|
||||
|
||||
if (externalBrowser) {
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(articleLink));
|
||||
startActivity(browserIntent);
|
||||
} else {
|
||||
Intent openArticle = new Intent(MainActivity.this, MainActivity.class);
|
||||
openArticle.setAction(articleLink);
|
||||
MainActivity.this.startActivity(openArticle);
|
||||
}
|
||||
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putBoolean(articleTitle, true);
|
||||
editor.apply();
|
||||
|
||||
b.setBackgroundColor(getResources().getColor(R.color.articleRead));
|
||||
}
|
||||
});
|
||||
layout.addView(spacer);
|
||||
layout.addView(btn);
|
||||
}
|
||||
// Internal browser
|
||||
else {
|
||||
TextView btn = new TextView(btnExample.getContext());
|
||||
btn.setText(date + '\n' + title);
|
||||
btn.setTextColor(getResources().getColor(R.color.colorPrimary));
|
||||
btn.setTextSize(20);
|
||||
btn.setVisibility(View.VISIBLE);
|
||||
btn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
TextView b = (TextView) v;
|
||||
|
||||
String text = b.getText().toString();
|
||||
int newline = text.indexOf('\n');
|
||||
|
||||
String articleTitle = text.substring(newline + 1);
|
||||
String articleLink = webPage.getLinks().get(webPage.getTitles().indexOf(articleTitle));
|
||||
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(articleLink));
|
||||
startActivity(browserIntent);
|
||||
}
|
||||
});
|
||||
|
||||
layout.addView(btn);
|
||||
}
|
||||
}
|
||||
|
||||
if (webPage.getTitles().size() == 1) {
|
||||
layout.addView(webPage.getContent());
|
||||
}
|
||||
|
||||
progressBar.setVisibility(View.GONE);
|
||||
|
||||
// Reschedule the service
|
||||
Intent restartService = new Intent(MainActivity.this, MyService.class);
|
||||
startService(restartService);
|
||||
|
||||
super.handleMessage(msg);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||
|
||||
MenuItem refresh = menu.findItem(R.id.refresh);
|
||||
refresh.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
refreshWebPage();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
MenuItem checkForNewArticles = menu.findItem(R.id.checkForNewArticles);
|
||||
checkForNewArticles.setChecked(sharedPreferences.getBoolean(checkForNewArticlesKey, true));
|
||||
|
||||
MenuItem externalBrowser = menu.findItem(R.id.externalBrowser);
|
||||
externalBrowser.setChecked(sharedPreferences.getBoolean(externalBrowserKey, true));
|
||||
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
/*
|
||||
@Override
|
||||
public void onOptionsMenuClosed(Menu menu) {
|
||||
super.onOptionsMenuClosed(menu);
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
int id = item.getItemId();
|
||||
|
||||
String menuItemKey;
|
||||
|
||||
switch (id) {
|
||||
case R.id.externalBrowser:
|
||||
menuItemKey = externalBrowserKey;
|
||||
break;
|
||||
case R.id.checkForNewArticles:
|
||||
menuItemKey = checkForNewArticlesKey;
|
||||
break;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
boolean newValue = !sharedPreferences.getBoolean(menuItemKey, true);
|
||||
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.putBoolean(menuItemKey, newValue);
|
||||
editor.apply();
|
||||
|
||||
if (id == R.id.externalBrowser) {
|
||||
finish();
|
||||
startActivity(this.getIntent());
|
||||
}
|
||||
|
||||
item.setChecked(newValue);
|
||||
|
||||
Toast.makeText(this, "Settings saved.", Toast.LENGTH_LONG).show();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
debugCount = 0;
|
||||
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
/**
|
||||
* ATTENTION: This was auto-generated to implement the App Indexing API.
|
||||
* See https://g.co/AppIndexing/AndroidStudio for more information.
|
||||
*/
|
||||
public Action getIndexApiAction() {
|
||||
Thing object = new Thing.Builder()
|
||||
.setName("Main Page") // TODO: Define a title for the content shown.
|
||||
// TODO: Make sure this auto-generated URL is correct.
|
||||
.setUrl(Uri.parse("http://[ENTER-YOUR-URL-HERE]"))
|
||||
.build();
|
||||
return new Action.Builder(Action.TYPE_VIEW)
|
||||
.setObject(object)
|
||||
.setActionStatus(Action.STATUS_TYPE_COMPLETED)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
|
||||
// ATTENTION: This was auto-generated to implement the App Indexing API.
|
||||
// See https://g.co/AppIndexing/AndroidStudio for more information.
|
||||
client.connect();
|
||||
AppIndex.AppIndexApi.start(client, getIndexApiAction());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
|
||||
// ATTENTION: This was auto-generated to implement the App Indexing API.
|
||||
// See https://g.co/AppIndexing/AndroidStudio for more information.
|
||||
AppIndex.AppIndexApi.end(client, getIndexApiAction());
|
||||
client.disconnect();
|
||||
}
|
||||
}
|
164
app/src/main/java/com/hyperling/apps/wheretheriverfrowns/MyService.java
Executable file
@ -0,0 +1,164 @@
|
||||
package com.hyperling.apps.wheretheriverfrowns;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.IntentService;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.PowerManager;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.app.TaskStackBuilder;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by ling on 10/2/16.
|
||||
*/
|
||||
|
||||
public class MyService extends IntentService {
|
||||
|
||||
private String sharedPreferencesKey, topArticleKey, checkForNewArticlesKey, debugKey, lastServiceRunKey, nextServiceRunKey,
|
||||
TAG,
|
||||
url;
|
||||
|
||||
private SharedPreferences sharedPreferences;
|
||||
|
||||
private PowerManager.WakeLock wakeLock;
|
||||
|
||||
private AlarmManager alarmManager;
|
||||
private PendingIntent reschedule;
|
||||
|
||||
private boolean DEBUG;
|
||||
|
||||
public MyService(){
|
||||
super("MyService");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
// Keys
|
||||
sharedPreferencesKey = getString(R.string.sharedPreferencesKey);
|
||||
topArticleKey = getString(R.string.topArticleKey);
|
||||
checkForNewArticlesKey = getString(R.string.checkForNewArticlesKey);
|
||||
debugKey = getString(R.string.debugKey);
|
||||
lastServiceRunKey = getString(R.string.lastServiceRunKey);
|
||||
nextServiceRunKey = getString(R.string.nextServiceRunKey);
|
||||
|
||||
// Strings
|
||||
TAG = getString(R.string.TAG);
|
||||
url = getString(R.string.allStories);
|
||||
|
||||
// Preferences
|
||||
sharedPreferences = getSharedPreferences(sharedPreferencesKey, MODE_PRIVATE);
|
||||
DEBUG = sharedPreferences.getBoolean(debugKey, false);
|
||||
|
||||
// Wake Lock
|
||||
wakeLock = ((PowerManager) getSystemService(POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
|
||||
wakeLock.acquire();
|
||||
|
||||
if (DEBUG) Log.d(TAG, "MyService: Service started.");
|
||||
|
||||
// Check if we have a connection
|
||||
NetworkInfo info = ((ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
|
||||
if (info == null || !info.isConnected() || info.isRoaming()){
|
||||
if (DEBUG) Log.d(TAG, "MyService: Not polling due to network.");
|
||||
rescheduleService(1);
|
||||
stopSelf();
|
||||
return;
|
||||
}
|
||||
|
||||
if (sharedPreferences.getBoolean(checkForNewArticlesKey, true)) {
|
||||
wakeLock.acquire();
|
||||
WebPage webPage = new WebPage(this, url);
|
||||
if (!webPage.getTitles().isEmpty()) {
|
||||
String newTopArticle = webPage.getTitles().get(0);
|
||||
String newDate = webPage.getDates().get(0);
|
||||
|
||||
String lastTopArticle = sharedPreferences.getString("TopArticle", newTopArticle);
|
||||
|
||||
if (DEBUG){
|
||||
Log.d(TAG, "MyService: lastTopArticle=" + lastTopArticle);
|
||||
Log.d(TAG, "MyService: newTopArticle=" + newTopArticle);
|
||||
}
|
||||
|
||||
if (!newTopArticle.equals(lastTopArticle)) {
|
||||
createNotification(newDate, newTopArticle);
|
||||
} else {
|
||||
rescheduleService(1);
|
||||
}
|
||||
|
||||
// Release lock and resources
|
||||
wakeLock.release();
|
||||
stopSelf();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createNotification(String articleDate, String articleTitle){
|
||||
if (DEBUG){
|
||||
Log.d(TAG, "MyService: createNotification");
|
||||
}
|
||||
|
||||
// Create notification
|
||||
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
|
||||
.setSmallIcon(R.drawable.wtrf_anarchy)
|
||||
.setColor(getResources().getColor(R.color.colorPrimary))
|
||||
.setContentTitle(getResources().getString(R.string.newArticleNotificationTitle) + " - " + articleDate)
|
||||
.setContentText(articleTitle)
|
||||
.setAutoCancel(true);
|
||||
|
||||
// Link so the notification opens WTRF
|
||||
Intent notificationLink = new Intent(this, MainActivity.class);
|
||||
notificationLink.setAction("");
|
||||
|
||||
// Allow using back to leave app
|
||||
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
|
||||
stackBuilder.addParentStack(MainActivity.class);
|
||||
stackBuilder.addNextIntent(notificationLink);
|
||||
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
// Add it all to the notification
|
||||
notificationBuilder.setContentIntent(pendingIntent);
|
||||
|
||||
// Display notification
|
||||
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
manager.notify(TAG, 0, notificationBuilder.build());
|
||||
}
|
||||
|
||||
private void rescheduleService(int hours){
|
||||
// Schedule next run after an hour or so
|
||||
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
|
||||
reschedule = PendingIntent.getBroadcast(this, 0, new Intent("com.hyperling.wheretheriverfrowns.ALARM_STARTED"), 0);
|
||||
|
||||
long convertedHours = 1000*60*60*hours;
|
||||
|
||||
long currentTime = System.currentTimeMillis();
|
||||
|
||||
alarmManager.cancel(reschedule);
|
||||
alarmManager.set(AlarmManager.RTC_WAKEUP, currentTime + convertedHours, reschedule);
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "MyService: rescheduleService: Rescheduled for " + hours + " hour(s).");
|
||||
Log.d(TAG, "MyService: rescheduleService: Current time= " + currentTime + ", reschedule time=" + currentTime + convertedHours);
|
||||
|
||||
Date date = new Date();
|
||||
String prettyDate;
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
|
||||
date.setTime(currentTime);
|
||||
prettyDate = date.toString();
|
||||
editor.putString(lastServiceRunKey, prettyDate);
|
||||
|
||||
date.setTime(currentTime + convertedHours);
|
||||
prettyDate = date.toString();
|
||||
editor.putString(nextServiceRunKey, prettyDate);
|
||||
|
||||
editor.apply();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.hyperling.apps.wheretheriverfrowns;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.support.v4.content.WakefulBroadcastReceiver;
|
||||
import android.util.Log;
|
||||
|
||||
import static android.content.Context.MODE_PRIVATE;
|
||||
|
||||
/**
|
||||
* Created by ling on 10/11/16.
|
||||
*/
|
||||
|
||||
public class ServiceReceiver extends WakefulBroadcastReceiver {
|
||||
private SharedPreferences sharedPreferences;
|
||||
|
||||
private String sharedPreferencesKey, debugKey, TAG;
|
||||
|
||||
private static boolean DEBUG;
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
|
||||
// Keys
|
||||
sharedPreferencesKey = context.getString(R.string.sharedPreferencesKey);
|
||||
debugKey = context.getString(R.string.debugKey);
|
||||
|
||||
// Strings
|
||||
TAG = context.getResources().getString(R.string.TAG);
|
||||
|
||||
// Preferences
|
||||
sharedPreferences = context.getSharedPreferences(sharedPreferencesKey, MODE_PRIVATE);
|
||||
DEBUG = sharedPreferences.getBoolean(debugKey, false);
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "ServiceReceiver: onReceive: intent.getAction()=" + intent.getAction());
|
||||
}
|
||||
|
||||
Intent serviceIntent = new Intent(context, MyService.class);
|
||||
context.startService(serviceIntent);
|
||||
}
|
||||
}
|
234
app/src/main/java/com/hyperling/apps/wheretheriverfrowns/WebPage.java
Executable file
@ -0,0 +1,234 @@
|
||||
package com.hyperling.apps.wheretheriverfrowns;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.util.Log;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by ling on 9/24/16.
|
||||
*/
|
||||
|
||||
public class WebPage {
|
||||
private Context context;
|
||||
|
||||
private String link;
|
||||
private String html = "";
|
||||
|
||||
private int index;
|
||||
|
||||
private ArrayList<String> titles;
|
||||
private ArrayList<String> links;
|
||||
private ArrayList<String> dates;
|
||||
|
||||
private LinearLayout content;
|
||||
|
||||
private boolean DEBUG = false;
|
||||
private String TAG;
|
||||
|
||||
public WebPage(Context context, String link) {
|
||||
TAG = context.getResources().getString(R.string.TAG);
|
||||
|
||||
this.context = context;
|
||||
this.link = link;
|
||||
URL url;
|
||||
InputStream is = null;
|
||||
BufferedReader br;
|
||||
String line;
|
||||
|
||||
titles = new ArrayList<>();
|
||||
links = new ArrayList<>();
|
||||
dates = new ArrayList<>();
|
||||
|
||||
try {
|
||||
url = new URL(link);
|
||||
is = url.openStream(); // throws an IOException
|
||||
br = new BufferedReader(new InputStreamReader(is));
|
||||
|
||||
while ((line = br.readLine()) != null) {
|
||||
html = html.concat(line);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (is != null) is.close();
|
||||
} catch (IOException ioe) {
|
||||
// nothing to see here
|
||||
}
|
||||
}
|
||||
|
||||
if (html.length() > 0) {
|
||||
html = html.replace(""", "\"");
|
||||
|
||||
int nextArticle;
|
||||
index = 0;
|
||||
while (findArticle() > 0) {
|
||||
// Move to the next article
|
||||
nextArticle = findArticle();
|
||||
html = html.substring(nextArticle);
|
||||
|
||||
// Get the url
|
||||
html = html.substring(html.indexOf("href=") + 6);
|
||||
String articleLink = html.substring(0, html.indexOf('\"'));
|
||||
links.add(index, articleLink);
|
||||
|
||||
// Get the title
|
||||
html = html.substring(html.indexOf('>') + 1);
|
||||
String articleTitle = html.substring(0, html.indexOf("</a>"));
|
||||
articleTitle = removeSpaces(articleTitle);
|
||||
titles.add(index, articleTitle);
|
||||
|
||||
// Get the date
|
||||
/* Date looks like:
|
||||
<p class="blog-date">
|
||||
<span class="date-text">9/21/2016</span>
|
||||
</p>
|
||||
*/
|
||||
html = html.substring(html.indexOf("<p class=\"blog-date\">"));
|
||||
html = html.substring(html.indexOf('>') + 1);
|
||||
html = html.substring(html.indexOf('>') + 1);
|
||||
String articleDate = html.substring(0, html.indexOf("</span>"));
|
||||
articleDate = removeSpaces(articleDate);
|
||||
dates.add(index, articleDate);
|
||||
|
||||
index += 1;
|
||||
}
|
||||
|
||||
if (context != null) {
|
||||
if (index == 1) {
|
||||
// Page is an article, get text
|
||||
/* Text starts at:
|
||||
<div class="blog-content">
|
||||
*/
|
||||
content = new LinearLayout(context);
|
||||
content.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
html = html.substring(html.indexOf("<div class=\"blog-content\">"));
|
||||
html = html.substring(html.indexOf('>') + 1);
|
||||
|
||||
if (DEBUG) Log.d(TAG, "DEBUG: WebPage: html=" + html);
|
||||
|
||||
int level = 1;
|
||||
String contentText = "";
|
||||
while (level > 0) {
|
||||
/*
|
||||
Paragraphs looks like:
|
||||
<div class="paragraph">
|
||||
|
||||
New TextViews at:
|
||||
<br></br>
|
||||
|
||||
level += 1 at <
|
||||
level -= 2 at </
|
||||
|
||||
Otherwise just grab everything between ><
|
||||
*/
|
||||
|
||||
while (html.indexOf('&') < html.indexOf('<')) {
|
||||
contentText = contentText.concat(html.substring(0, html.indexOf('&')));
|
||||
html = html.substring(html.indexOf(';') + 1);
|
||||
}
|
||||
|
||||
contentText = contentText.concat(html.substring(0, html.indexOf('<')));
|
||||
contentText = removeSpaces(contentText);
|
||||
|
||||
|
||||
html = html.substring(html.indexOf('<'));
|
||||
|
||||
// TODO: Testing only
|
||||
if (level > 0) {
|
||||
//System.out.println("DEBUG: level=" + level + " html=" + html);
|
||||
//System.out.println("DEBUG: contentText=" + contentText);
|
||||
}
|
||||
|
||||
if (html.indexOf("<div class=\"paragraph\">") == 0) {
|
||||
|
||||
TextView newView = new TextView(context);
|
||||
newView.setText(contentText);
|
||||
newView.setTextColor(Color.BLACK);
|
||||
content.addView(newView);
|
||||
|
||||
contentText = "";
|
||||
} else if (html.indexOf("<br>") == 0 || html.indexOf("<br />") == 0) {
|
||||
contentText = contentText.concat("\n");
|
||||
level -= 1;
|
||||
} else if (html.indexOf("<meta ") == 0) {
|
||||
level -= 1;
|
||||
} else if (html.indexOf("<img ") == 0) {
|
||||
level -= 1;
|
||||
} else if (html.indexOf("<!--") == 0) {
|
||||
level -= 1;
|
||||
} else if (html.indexOf("</") == 0) {
|
||||
level -= 2;
|
||||
}
|
||||
|
||||
if (html.indexOf("/>") < html.indexOf(">")) {
|
||||
level -= 1;
|
||||
}
|
||||
|
||||
html = html.substring(html.indexOf('>') + 1);
|
||||
level += 1;
|
||||
}
|
||||
|
||||
TextView newView = new TextView(context);
|
||||
newView.setText(contentText);
|
||||
newView.setTextColor(Color.BLACK);
|
||||
content.addView(newView);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int findArticle(){
|
||||
/* Example of an article title:
|
||||
<a class="blog-title-link blog-link" href="http://www.wheretheriverfrowns.com/all-stories/kite-line-september-16-2016-national-prison-strike-updates">Kite Line – September 16, 2016: National Prison Strike Updates</a>
|
||||
*/
|
||||
return html.indexOf("<a class=\"blog-title-link blog-link\"");
|
||||
}
|
||||
|
||||
// TODO: Testing only
|
||||
public String getHTML(){
|
||||
return html;
|
||||
}
|
||||
public String getLink(){
|
||||
return link;
|
||||
}
|
||||
|
||||
public ArrayList<String> getTitles(){
|
||||
return titles;
|
||||
}
|
||||
|
||||
public ArrayList<String> getLinks(){
|
||||
return links;
|
||||
}
|
||||
|
||||
public ArrayList<String> getDates(){
|
||||
return dates;
|
||||
}
|
||||
|
||||
public LinearLayout getContent(){
|
||||
return content;
|
||||
}
|
||||
|
||||
private String removeSpaces(String string){
|
||||
while(string.contains(" ")) {
|
||||
string = string.replace(" ", " ");
|
||||
}
|
||||
//string = string.replace("\n", "");
|
||||
string = string.replace("\t", "");
|
||||
return string;
|
||||
}
|
||||
|
||||
public void setDEBUG(boolean debug){
|
||||
this.DEBUG = debug;
|
||||
}
|
||||
}
|
9
app/src/main/res/drawable/ic_info_black_24dp.xml
Executable file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zm1,15h-2v-6h2v6zm0,-8h-2V7h2v2z" />
|
||||
</vector>
|
9
app/src/main/res/drawable/ic_notifications_black_24dp.xml
Executable file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M11.5,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.9,2 2,2zm6.5,-6v-5.5c0,-3.07 -2.13,-5.64 -5,-6.32V3.5c0,-0.83 -0.67,-1.5 -1.5,-1.5S10,2.67 10,3.5v0.68c-2.87,0.68 -5,3.25 -5,6.32V16l-2,2v1h17v-1l-2,-2z" />
|
||||
</vector>
|
9
app/src/main/res/drawable/ic_sync_black_24dp.xml
Executable file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01,-.25 1.97,-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0,-4.42,-3.58,-8,-8,-8zm0 14c-3.31 0,-6,-2.69,-6,-6 0,-1.01.25,-1.97.7,-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4,-4,-4,-4v3z" />
|
||||
</vector>
|
BIN
app/src/main/res/drawable/wtrf.png
Executable file
After Width: | Height: | Size: 311 KiB |
BIN
app/src/main/res/drawable/wtrf_anarchy.png
Executable file
After Width: | Height: | Size: 1.8 KiB |
26
app/src/main/res/layout/activity_debug.xml
Executable file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/debugLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
tools:context="com.hyperling.apps.wheretheriverfrowns.DebugActivity">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnDebugExit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/btnDebug"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnResetPreferences"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/btnResetPreferences"/>
|
||||
|
||||
</LinearLayout>
|
43
app/src/main/res/layout/activity_main.xml
Executable file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/activity_main"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
tools:context="com.hyperling.apps.wheretheriverfrowns.MainActivity">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/app_version"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
style="?android:attr/progressBarStyleLarge"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<LinearLayout
|
||||
android:id="@+id/layout"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<Button
|
||||
android:id="@+id/btnExample"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"/>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
28
app/src/main/res/menu/menu_main.xml
Executable file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<group android:id="@+id/functionality">
|
||||
|
||||
<item
|
||||
android:id="@+id/refresh"
|
||||
android:enabled="true"
|
||||
android:visible="true"
|
||||
android:title="@string/refresh"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/checkForNewArticles"
|
||||
android:checkable="true"
|
||||
android:enabled="true"
|
||||
android:visible="true"
|
||||
android:title="@string/checkForNewArticles"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/externalBrowser"
|
||||
android:checkable="true"
|
||||
android:enabled="false"
|
||||
android:visible="false"
|
||||
android:title="@string/externalBrowser"/>
|
||||
|
||||
</group>
|
||||
|
||||
</menu>
|
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Executable file
After Width: | Height: | Size: 3.3 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Executable file
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Executable file
After Width: | Height: | Size: 4.7 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Executable file
After Width: | Height: | Size: 7.5 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Executable file
After Width: | Height: | Size: 10 KiB |
6
app/src/main/res/values-w820dp/dimens.xml
Executable file
@ -0,0 +1,6 @@
|
||||
<resources>
|
||||
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
|
||||
(such as screen margins) for screens with more than 820dp of available width. This
|
||||
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
|
||||
<dimen name="activity_horizontal_margin">64dp</dimen>
|
||||
</resources>
|
19
app/src/main/res/values/colors.xml
Executable file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- DEFAULTS
|
||||
<color name="colorPrimary">#3F51B5</color>
|
||||
<color name="colorPrimaryDark">#303F9F</color>
|
||||
<color name="colorAccent">#FF4081</color>
|
||||
-->
|
||||
<!-- Facebook icon + website
|
||||
<color name="colorPrimary">#BBC4CB</color>
|
||||
<color name="colorPrimaryDark">#223E90</color>
|
||||
<color name="colorAccent">#564A37</color>
|
||||
-->
|
||||
<!-- Website Only. if need white, use FDFDFE-->
|
||||
<color name="colorPrimary">#68A2C1</color>
|
||||
<color name="colorPrimaryDark">#000000</color>
|
||||
<color name="colorAccent">#68A2C1</color>
|
||||
|
||||
<color name="articleRead">#999999</color>
|
||||
</resources>
|
5
app/src/main/res/values/dimens.xml
Executable file
@ -0,0 +1,5 @@
|
||||
<resources>
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
</resources>
|
39
app/src/main/res/values/strings.xml
Executable file
@ -0,0 +1,39 @@
|
||||
<resources>
|
||||
<string name="app_name">WtRF News</string>
|
||||
<string name="app_title">Where the River Frowns</string>
|
||||
<string name="app_version">v201611121043</string>
|
||||
<string name="title_activity_settings">Settings</string>
|
||||
<string name="TAG">com.hyperling.apps.wheretheriverfrowns</string>
|
||||
|
||||
<!-- WTRF URL of where all the stories are -->
|
||||
<string name="allStories">http://www.wheretheriverfrowns.com/all-stories</string>
|
||||
|
||||
<!-- Shared Preference Key -->
|
||||
<string name="sharedPreferencesKey">wtrf</string>
|
||||
|
||||
<!-- Shared preference entries -->
|
||||
<string name="topArticleKey">TopArticle</string>
|
||||
<string name="externalBrowserKey">ExternalBrowser</string>
|
||||
<string name="checkForNewArticlesKey">CheckForNewArticles</string>
|
||||
<string name="debugKey">DEBUG</string>
|
||||
<string name="lastServiceRunKey">LastServiceRun</string>
|
||||
<string name="nextServiceRunKey">NextServiceRun</string>
|
||||
|
||||
<!-- Connection types -->
|
||||
<string name="networkConnected">c</string>
|
||||
<string name="networkRoaming">r</string>
|
||||
<string name="networkDisconnected">d</string>
|
||||
|
||||
<!-- Strings related to Action Menu -->
|
||||
<string name="refresh">Refresh</string>
|
||||
<string name="checkForNewArticles">Notify on New Articles?</string>
|
||||
<string name="externalBrowser">Use External Browser?</string>
|
||||
|
||||
<!-- Notification Title -->
|
||||
<string name="newArticleNotificationTitle">New WtRF Article</string>
|
||||
|
||||
<!-- Debug Activity -->
|
||||
<string name="debugActivityTitle">Debug Menu</string>
|
||||
<string name="btnDebug">DEBUG MODE</string>
|
||||
<string name="btnResetPreferences">Reset Preferences</string>
|
||||
</resources>
|
12
app/src/main/res/values/styles.xml
Executable file
@ -0,0 +1,12 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="wtrf" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="android:textAllCaps">false</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
@ -0,0 +1,17 @@
|
||||
package com.hyperling.apps.wheretheriverfrowns;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() throws Exception {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
24
build.gradle
Executable file
@ -0,0 +1,24 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
google()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.1.3'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
BIN
gimp/banner.png
Executable file
After Width: | Height: | Size: 828 KiB |
BIN
gimp/banner.xcf
Executable file
BIN
gimp/map.jpg
Executable file
After Width: | Height: | Size: 606 KiB |
BIN
gimp/wtrf.png
Executable file
After Width: | Height: | Size: 311 KiB |
BIN
gimp/wtrf_anarchy.png
Executable file
After Width: | Height: | Size: 1.8 KiB |
17
gradle.properties
Executable file
@ -0,0 +1,17 @@
|
||||
# Project-wide Gradle settings.
|
||||
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Executable file
6
gradle/wrapper/gradle-wrapper.properties
vendored
Executable file
@ -0,0 +1,6 @@
|
||||
#Sat Jun 16 09:49:57 CDT 2018
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
|
160
gradlew
vendored
Executable file
@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
90
gradlew.bat
vendored
Executable file
@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
1
settings.gradle
Executable file
@ -0,0 +1 @@
|
||||
include ':app'
|