Initial Commit
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea/workspace.xml
|
||||||
|
/.idea/libraries
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/captures
|
||||||
|
.externalNativeBuild
|
||||||
112
.idea/assetWizardSettings.xml
generated
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="WizardSettings">
|
||||||
|
<option name="children">
|
||||||
|
<map>
|
||||||
|
<entry key="imageWizard">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="children">
|
||||||
|
<map>
|
||||||
|
<entry key="imageAssetPanel">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="children">
|
||||||
|
<map>
|
||||||
|
<entry key="actionbar">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="children">
|
||||||
|
<map>
|
||||||
|
<entry key="clipArt">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="values">
|
||||||
|
<map>
|
||||||
|
<entry key="paddingPercent" value="-10" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="clipartAsset">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="values">
|
||||||
|
<map>
|
||||||
|
<entry key="url" value="jar:file:/C:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/action/ic_home_black_24dp.xml" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
<option name="values">
|
||||||
|
<map>
|
||||||
|
<entry key="outputName" value="ic_home" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="launcherLegacy">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="children">
|
||||||
|
<map>
|
||||||
|
<entry key="clipArt">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="values">
|
||||||
|
<map>
|
||||||
|
<entry key="color" value="ffffff" />
|
||||||
|
<entry key="paddingPercent" value="-10" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="clipartAsset">
|
||||||
|
<value>
|
||||||
|
<PersistentState>
|
||||||
|
<option name="values">
|
||||||
|
<map>
|
||||||
|
<entry key="url" value="jar:file:/C:/Program%20Files/Android/Android%20Studio/plugins/android/lib/android.jar!/images/material_design_icons/action/ic_grade_black_24dp.xml" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
<option name="values">
|
||||||
|
<map>
|
||||||
|
<entry key="assetType" value="IMAGE" />
|
||||||
|
<entry key="iconShape" value="NONE" />
|
||||||
|
<entry key="imageAsset" value="C:\Users\h_mal\Desktop\Atlas weather\notif.png" />
|
||||||
|
<entry key="outputName" value="ic_notif" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
<option name="values">
|
||||||
|
<map>
|
||||||
|
<entry key="outputIconType" value="LAUNCHER_LEGACY" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</PersistentState>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
BIN
.idea/caches/build_file_checksums.ser
generated
Normal file
29
.idea/codeStyles/Project.xml
generated
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<Objective-C-extensions>
|
||||||
|
<file>
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
||||||
|
</file>
|
||||||
|
<class>
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
||||||
|
</class>
|
||||||
|
<extensions>
|
||||||
|
<pair source="cpp" header="h" fileNamingConvention="NONE" />
|
||||||
|
<pair source="c" header="h" fileNamingConvention="NONE" />
|
||||||
|
</extensions>
|
||||||
|
</Objective-C-extensions>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
||||||
18
.idea/gradle.xml
generated
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GradleSettings">
|
||||||
|
<option name="linkedExternalProjectsSettings">
|
||||||
|
<GradleProjectSettings>
|
||||||
|
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="modules">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$" />
|
||||||
|
<option value="$PROJECT_DIR$/app" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
<option name="resolveModulePerSourceSet" value="false" />
|
||||||
|
</GradleProjectSettings>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
34
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="NullableNotNullManager">
|
||||||
|
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
|
||||||
|
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
||||||
|
<option name="myNullables">
|
||||||
|
<value>
|
||||||
|
<list size="5">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
|
||||||
|
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
|
||||||
|
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="myNotNulls">
|
||||||
|
<value>
|
||||||
|
<list size="4">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
|
||||||
|
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
|
||||||
|
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
|
||||||
|
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectType">
|
||||||
|
<option name="id" value="Android" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
9
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/Weather_app.iml" filepath="$PROJECT_DIR$/Weather_app.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
12
.idea/runConfigurations.xml
generated
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RunConfigurationProducerService">
|
||||||
|
<option name="ignoredProducers">
|
||||||
|
<set>
|
||||||
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
1
app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/build
|
||||||
36
app/build.gradle
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 26
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "com.appttude.h_mal.atlas_weather"
|
||||||
|
minSdkVersion 23
|
||||||
|
targetSdkVersion 26
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
|
vectorDrawables.useSupportLibrary = true
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
implementation 'com.android.support:appcompat-v7:26.1.0'
|
||||||
|
implementation 'com.android.support:design:26.1.0'
|
||||||
|
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||||
|
implementation 'com.android.support:support-v4:26.1.0'
|
||||||
|
implementation 'com.squareup.picasso:picasso:2.71828'
|
||||||
|
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
|
||||||
|
implementation 'com.android.support:support-vector-drawable:26.1.0'
|
||||||
|
implementation "com.google.android.gms:play-services-location:16.0.0"
|
||||||
|
testImplementation 'junit:junit:4.12'
|
||||||
|
androidTestImplementation 'com.android.support.test:runner:1.0.1'
|
||||||
|
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
|
||||||
|
implementation 'com.android.support:cardview-v7:26.1.0'
|
||||||
|
}
|
||||||
21
app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# 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 *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
||||||
BIN
app/release/app-release.apk
Normal file
1
app/release/output.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
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.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instrumented 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.example.h_mal.weather_app", appContext.getPackageName());
|
||||||
|
}
|
||||||
|
}
|
||||||
81
app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.appttude.h_mal.atlas_weather">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.SET_ALARM" />
|
||||||
|
|
||||||
|
<uses-feature
|
||||||
|
android:name="android.hardware.location"
|
||||||
|
android:required="true" />
|
||||||
|
<uses-feature
|
||||||
|
android:name="android.hardware.location.gps"
|
||||||
|
android:required="true" />
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/AppTheme">
|
||||||
|
<activity
|
||||||
|
android:name="com.appttude.h_mal.atlas_weather.MainActivity"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:launchMode="singleTop"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<receiver android:name="com.appttude.h_mal.atlas_weather.NotificationReceiver"
|
||||||
|
android:parentActivityName="com.appttude.h_mal.atlas_weather.MainActivity"/>
|
||||||
|
|
||||||
|
<activity android:name="com.appttude.h_mal.atlas_weather.FurtherInfoActivity"
|
||||||
|
android:parentActivityName="com.appttude.h_mal.atlas_weather.MainActivity"/>
|
||||||
|
<activity
|
||||||
|
android:name="com.appttude.h_mal.atlas_weather.AddForecast"
|
||||||
|
android:parentActivityName="com.appttude.h_mal.atlas_weather.MainActivity" />
|
||||||
|
<activity android:name="com.appttude.h_mal.atlas_weather.UnitSettings"
|
||||||
|
android:parentActivityName="com.appttude.h_mal.atlas_weather.MainActivity"/>
|
||||||
|
|
||||||
|
<provider
|
||||||
|
android:name="com.appttude.h_mal.atlas_weather.dbfiles.ForecastProvider"
|
||||||
|
android:authorities="com.appttude.h_mal.atlas_weather"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
|
<receiver android:name="com.appttude.h_mal.atlas_weather.AppWidget.NewAppWidget">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||||
|
<action android:name="android.appwidget.action.APPWIDGET_ENABLED" />
|
||||||
|
<action android:name="com.example.h_mal.weather_app.app.ACTION_DATA_UPDATED" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="android.appwidget.provider"
|
||||||
|
android:resource="@xml/new_app_widget_info" />
|
||||||
|
</receiver>
|
||||||
|
|
||||||
|
<activity android:name="com.appttude.h_mal.atlas_weather.WorldItemActivity"
|
||||||
|
android:parentActivityName="com.appttude.h_mal.atlas_weather.MainActivity">
|
||||||
|
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name="com.appttude.h_mal.atlas_weather.AppWidget.WidgetRemoteViewsService"
|
||||||
|
android:permission="android.permission.BIND_REMOTEVIEWS"></service>
|
||||||
|
|
||||||
|
<activity android:name="com.appttude.h_mal.atlas_weather.InfoActivity"
|
||||||
|
android:parentActivityName="com.appttude.h_mal.atlas_weather.MainActivity">
|
||||||
|
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
BIN
app/src/main/ic_home-web.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
app/src/main/ic_notif-web.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
app/src/main/ic_world-web.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,143 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.content.ContentValues;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.appttude.h_mal.atlas_weather.dbfiles.ForecastContract.ForecastEntry;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.UriBuilder;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.createUrl;
|
||||||
|
|
||||||
|
public class AddForecast extends AppCompatActivity {
|
||||||
|
|
||||||
|
private EditText tv;
|
||||||
|
private String nameString;
|
||||||
|
public ProgressBar progBarAdd;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_add_forecast);
|
||||||
|
|
||||||
|
tv = findViewById(R.id.location_name_tv);
|
||||||
|
progBarAdd = findViewById(R.id.pb_add);
|
||||||
|
progBarAdd.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
Button button = findViewById(R.id.submit);
|
||||||
|
button.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
nameString = tv.getText().toString().trim();
|
||||||
|
submitEntry(nameString);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void submitEntry(String s){
|
||||||
|
|
||||||
|
if (TextUtils.isEmpty(s)) {
|
||||||
|
Toast.makeText(AddForecast.this, "please insert a location name", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
new RetrieveFeedTask().execute(s);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void insertIntoDb(){
|
||||||
|
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put(ForecastEntry.COLUMN_FORECAST_NAME, nameString);
|
||||||
|
|
||||||
|
Uri newUri = getContentResolver().insert(ForecastEntry.CONTENT_URI, values);
|
||||||
|
|
||||||
|
if (newUri == null) {
|
||||||
|
Toast.makeText(this, getString(R.string.insert_entry_failed),
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, getString(R.string.insert_entry_successful),
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RetrieveFeedTask extends AsyncTask<String, Void, Boolean> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPreExecute() {
|
||||||
|
super.onPreExecute();
|
||||||
|
|
||||||
|
progBarAdd.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Boolean doInBackground(String... urls) {
|
||||||
|
HttpURLConnection urlConnection = null;
|
||||||
|
URL url = createUrl(UriBuilder(urls[0]));
|
||||||
|
|
||||||
|
Boolean b = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
urlConnection = (HttpURLConnection) url.openConnection();
|
||||||
|
urlConnection.setReadTimeout(30000);
|
||||||
|
urlConnection.setConnectTimeout(30000);
|
||||||
|
urlConnection.setRequestMethod("GET");
|
||||||
|
urlConnection.connect();
|
||||||
|
|
||||||
|
if (urlConnection.getResponseCode() == 200) {
|
||||||
|
b = true;
|
||||||
|
Log.i("", "checkHttpRequest: good response");
|
||||||
|
} else {
|
||||||
|
b = false;
|
||||||
|
Log.e("", "Error response code: " + urlConnection.getResponseCode());
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("", "Problem retrieving the response results.", e);
|
||||||
|
} finally {
|
||||||
|
if (urlConnection != null) {
|
||||||
|
urlConnection.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onPostExecute(Boolean feed) {
|
||||||
|
|
||||||
|
progBarAdd.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
if (feed == null){
|
||||||
|
Toast.makeText(AddForecast.this, "No connection", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (feed){
|
||||||
|
|
||||||
|
insertIntoDb();
|
||||||
|
Intent returnIntent = new Intent();
|
||||||
|
returnIntent.putExtra("result", getClass().getSimpleName());
|
||||||
|
setResult(RESULT_OK, returnIntent);
|
||||||
|
finish();
|
||||||
|
}else{
|
||||||
|
Toast.makeText(AddForecast.this, "Location not found", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather.AppWidget;
|
||||||
|
|
||||||
|
import android.appwidget.AppWidgetManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.RemoteViews;
|
||||||
|
import android.widget.RemoteViewsService;
|
||||||
|
|
||||||
|
import com.appttude.h_mal.atlas_weather.Forecast;
|
||||||
|
import com.appttude.h_mal.atlas_weather.ForecastItem;
|
||||||
|
import com.appttude.h_mal.atlas_weather.R;
|
||||||
|
import com.appttude.h_mal.atlas_weather.dbfiles.ForecastDBHelper;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.appttude.h_mal.atlas_weather.MainActivity.getImageResource;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.extractFeatureFromJson;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.dbfiles.ForecastContract.ForecastEntry.COLUMN_FORECAST_NAME;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.dbfiles.ForecastContract.ForecastEntry.COLUMN_WIDGET_FORECAST_ITEM;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.dbfiles.ForecastContract.ForecastEntry.TABLE_NAME_WIDGET;
|
||||||
|
|
||||||
|
public class MyWidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
// private ForecastItem forecastItem;
|
||||||
|
private List<Forecast> forecastList;
|
||||||
|
private String TAG = this.getClass().getSimpleName();
|
||||||
|
private Cursor cursor;
|
||||||
|
private SQLiteDatabase database;
|
||||||
|
private int appWidgetId;
|
||||||
|
private SharedPreferences mSettings;
|
||||||
|
|
||||||
|
public MyWidgetRemoteViewsFactory(Context context, Intent intent) {
|
||||||
|
this.mContext = context;
|
||||||
|
this.appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
|
||||||
|
AppWidgetManager.INVALID_APPWIDGET_ID);
|
||||||
|
mSettings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
Log.i(TAG, "onCreate: widget oncreate executed");
|
||||||
|
ForecastDBHelper forecastsDbhelper = new ForecastDBHelper(mContext);
|
||||||
|
database = forecastsDbhelper.getWritableDatabase();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDataSetChanged() {
|
||||||
|
if (cursor != null){
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
String[] projection = {COLUMN_FORECAST_NAME, COLUMN_WIDGET_FORECAST_ITEM};
|
||||||
|
|
||||||
|
cursor = database.query(TABLE_NAME_WIDGET,
|
||||||
|
projection,
|
||||||
|
COLUMN_FORECAST_NAME + " IS ?",new String[]{"Current"},null,null,null);
|
||||||
|
|
||||||
|
String json;
|
||||||
|
if (cursor != null && cursor.getCount() > 0) {
|
||||||
|
Log.i(TAG, "onDataSetChanged: cursor loaded, count: " + cursor.getCount());
|
||||||
|
cursor.moveToFirst();
|
||||||
|
json = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_WIDGET_FORECAST_ITEM));
|
||||||
|
ForecastItem forecastItem = extractFeatureFromJson(json);
|
||||||
|
if (forecastItem != null) {
|
||||||
|
forecastList = forecastItem.getForecastArrayList();
|
||||||
|
forecastList.remove(0);
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
|
}else{
|
||||||
|
Log.i(TAG, "onDataSetChanged: cursor is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
Log.i(TAG, "getCount: size = " + forecastList.size());
|
||||||
|
return forecastList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RemoteViews getViewAt(int i) {
|
||||||
|
if (i == AdapterView.INVALID_POSITION ||
|
||||||
|
forecastList == null || forecastList.get(i) == null ) {
|
||||||
|
Log.i(this.getClass().getSimpleName(), "getViewAt: no views" );
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(this.getClass().getSimpleName(), "getViewAt: views exist " + i);
|
||||||
|
|
||||||
|
RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item);
|
||||||
|
|
||||||
|
Date updatedate = new Date(forecastList.get(i).getDate_epoch()*1000);
|
||||||
|
SimpleDateFormat format = new SimpleDateFormat("EEE");
|
||||||
|
|
||||||
|
String dateText = format.format(updatedate);
|
||||||
|
// if (dateText.equals("Wednesday")){
|
||||||
|
// dateText = "Wednes..";
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Log.i(TAG, "getViewAt: dateText: " + dateText);
|
||||||
|
//
|
||||||
|
// if(i == 0){
|
||||||
|
// SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
|
||||||
|
// String result = sdf.format(Calendar.getInstance().getTime());
|
||||||
|
// rv.setTextViewText(R.id.widget_item_day, result);
|
||||||
|
// }else {
|
||||||
|
rv.setTextViewText(R.id.widget_item_day, dateText);
|
||||||
|
// }
|
||||||
|
|
||||||
|
rv.setImageViewResource(R.id.widget_item_image,
|
||||||
|
getImageResource(forecastList.get(i).getIconURL(),mContext));
|
||||||
|
|
||||||
|
String maxtemp;
|
||||||
|
String mintemp;
|
||||||
|
|
||||||
|
if (mSettings.getString("temp_units","").equals("F°")){
|
||||||
|
maxtemp = String.valueOf(Math.round(forecastList.get(i).getMaxtemp_f())) + "°";
|
||||||
|
mintemp = String.valueOf(Math.round(forecastList.get(i).getMintemp_f())) + "°";
|
||||||
|
}else{
|
||||||
|
maxtemp = String.valueOf(Math.round(forecastList.get(i).getMaxtemp_c())) + "°";
|
||||||
|
mintemp = String.valueOf(Math.round(forecastList.get(i).getMintemp_c())) + "°";
|
||||||
|
}
|
||||||
|
|
||||||
|
rv.setTextViewText(R.id.widget_item_temp_high,maxtemp);
|
||||||
|
rv.setTextViewText(R.id.widget_item_temp_low,mintemp);
|
||||||
|
|
||||||
|
Intent fillInIntent = new Intent();
|
||||||
|
fillInIntent.putExtra("currentForcast", forecastList.get(i));
|
||||||
|
rv.setOnClickFillInIntent(R.id.widget_item_layout, fillInIntent);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RemoteViews getLoadingView() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getViewTypeCount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int i) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasStableIds() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,278 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather.AppWidget;
|
||||||
|
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.app.TaskStackBuilder;
|
||||||
|
import android.appwidget.AppWidgetManager;
|
||||||
|
import android.appwidget.AppWidgetProvider;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.ContentValues;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.RemoteViews;
|
||||||
|
|
||||||
|
import com.appttude.h_mal.atlas_weather.CurrentForecast;
|
||||||
|
import com.appttude.h_mal.atlas_weather.ForecastItem;
|
||||||
|
import com.appttude.h_mal.atlas_weather.FurtherInfoActivity;
|
||||||
|
import com.appttude.h_mal.atlas_weather.R;
|
||||||
|
import com.appttude.h_mal.atlas_weather.dbfiles.ForecastDBHelper;
|
||||||
|
import com.appttude.h_mal.atlas_weather.getLatLong;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import static com.appttude.h_mal.atlas_weather.MainActivity.changeToInt;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.MainActivity.getImageResource;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.MainActivity.getLocationName;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.UriBuilder;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.createUrl;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.extractFeatureFromJson;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.makeHttpRequest;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.dbfiles.ForecastContract.ForecastEntry.COLUMN_FORECAST_NAME;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.dbfiles.ForecastContract.ForecastEntry.COLUMN_WIDGET_FORECAST_ITEM;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.dbfiles.ForecastContract.ForecastEntry.TABLE_NAME_WIDGET;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of App Widget functionality.
|
||||||
|
*/
|
||||||
|
public class NewAppWidget extends AppWidgetProvider{
|
||||||
|
|
||||||
|
private static String TAG = NewAppWidget.class.getSimpleName();
|
||||||
|
private static int request = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
|
||||||
|
// There may be multiple widgets active, so update all of them
|
||||||
|
|
||||||
|
for (int appWidgetId : appWidgetIds) {
|
||||||
|
getLatLong.configLatLong(context);
|
||||||
|
forecastAsyncTask task = new forecastAsyncTask(context,appWidgetManager,appWidgetId);
|
||||||
|
task.execute(UriBuilder(6));
|
||||||
|
Log.i(TAG, "onUpdate: widget onUpdate called at " + getCurrentTimeUsingDate());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onUpdate(context, appWidgetManager, appWidgetIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnabled(Context context) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
|
||||||
|
|
||||||
|
ComponentName thisAppWidget = new ComponentName(context.getPackageName(), NewAppWidget.class.getName());
|
||||||
|
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
|
||||||
|
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.widget_listview);
|
||||||
|
|
||||||
|
Log.i(TAG, "onEnabled: called at " + getCurrentTimeUsingDate());
|
||||||
|
}catch (Exception e){
|
||||||
|
Log.e(TAG, "onEnabled: ", e);
|
||||||
|
}
|
||||||
|
// Enter relevant functionality for when the first widget is created
|
||||||
|
// getLatLong.configLatLong(context);
|
||||||
|
// forecastAsyncTask task = new forecastAsyncTask();
|
||||||
|
// task.execute(UriBuilder(5));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisabled(Context context) {
|
||||||
|
// Enter relevant functionality for when the last widget is disabled
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
|
||||||
|
if (intent.getAction().equals(
|
||||||
|
AppWidgetManager.ACTION_APPWIDGET_UPDATE)) {
|
||||||
|
|
||||||
|
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
|
||||||
|
|
||||||
|
ComponentName thisAppWidget = new ComponentName(context.getPackageName(), NewAppWidget.class.getName());
|
||||||
|
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
|
||||||
|
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.widget_listview);
|
||||||
|
Log.i(TAG, "onReceive: widget onReceive called at " + getCurrentTimeUsingDate());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onReceive(context, intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class forecastAsyncTask extends AsyncTask<String,Void,String>{
|
||||||
|
|
||||||
|
private Context context;
|
||||||
|
AppWidgetManager appWidgetManager;
|
||||||
|
int appWidgetId;
|
||||||
|
|
||||||
|
public forecastAsyncTask(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
|
||||||
|
this.context = context;
|
||||||
|
this.appWidgetManager = appWidgetManager;
|
||||||
|
this.appWidgetId = appWidgetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String doInBackground(String... urlString) {
|
||||||
|
Log.i(TAG, "doInBackground: started at " + getCurrentTimeUsingDate());
|
||||||
|
String jsonResponse = null;
|
||||||
|
|
||||||
|
if (urlString.length < 1 || urlString[0] == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
URL url = createUrl(urlString[0]);
|
||||||
|
jsonResponse = makeHttpRequest(url);
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e( TAG, "Problem making the HTTP request.", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(String result) {
|
||||||
|
super.onPostExecute(result);
|
||||||
|
|
||||||
|
Log.i(TAG, "onPostExecute: SQL data result: " + result);
|
||||||
|
|
||||||
|
if(result == null){
|
||||||
|
Log.i(TAG, "onPostExecute: result null");
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
|
||||||
|
|
||||||
|
Intent intentUpdate = new Intent(context, NewAppWidget.class);
|
||||||
|
intentUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
|
||||||
|
|
||||||
|
int[] idArray = new int[]{appWidgetId};
|
||||||
|
intentUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, idArray);
|
||||||
|
|
||||||
|
PendingIntent pendingUpdate = PendingIntent.getBroadcast(
|
||||||
|
context, request++, intentUpdate,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
|
// float opacity = 0.3f; //opacity = 0: fully transparent, opacity = 1: no transparancy
|
||||||
|
// int backgroundColor = 0x000000; //background color (here black)
|
||||||
|
// views.setInt( R.id.whole_widget_view, "setBackgroundColor", (int)(opacity * 0xFF) << 24 | backgroundColor);
|
||||||
|
|
||||||
|
if (result != null) {
|
||||||
|
|
||||||
|
ForecastDBHelper forecastsDbhelper = new ForecastDBHelper(context);
|
||||||
|
SQLiteDatabase database = forecastsDbhelper.getWritableDatabase();
|
||||||
|
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
values.put(COLUMN_FORECAST_NAME, "Current");
|
||||||
|
values.put(COLUMN_WIDGET_FORECAST_ITEM, result);
|
||||||
|
|
||||||
|
String[] projection = {COLUMN_FORECAST_NAME, COLUMN_WIDGET_FORECAST_ITEM};
|
||||||
|
|
||||||
|
Cursor cursor = null;
|
||||||
|
try {
|
||||||
|
cursor = database.query(TABLE_NAME_WIDGET,
|
||||||
|
projection,
|
||||||
|
COLUMN_FORECAST_NAME + " IS ?",
|
||||||
|
new String[]{"Current"},
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "onPostExecute: ", e);
|
||||||
|
} finally {
|
||||||
|
if(cursor != null){
|
||||||
|
while (cursor.moveToNext()){
|
||||||
|
String currentDB = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_WIDGET_FORECAST_ITEM));
|
||||||
|
Log.i(TAG, "onPostExecute: current db: " + currentDB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cursor != null && cursor.getCount() > 0) {
|
||||||
|
database.update(TABLE_NAME_WIDGET, values, COLUMN_FORECAST_NAME + " IS ?", new String[]{"Current"});
|
||||||
|
Log.i(TAG, "onPostExecute: attempted to update sql, size:" + cursor.getCount());
|
||||||
|
cursor.close();
|
||||||
|
} else {
|
||||||
|
database.insert(TABLE_NAME_WIDGET, null, values);
|
||||||
|
Log.i(TAG, "onPostExecute: attempted to insert sql");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ForecastItem forecastItem = extractFeatureFromJson(result);
|
||||||
|
CurrentForecast cf = forecastItem.getCurrentForecast();
|
||||||
|
|
||||||
|
Intent intent = new Intent(context, WidgetRemoteViewsService.class);
|
||||||
|
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
|
||||||
|
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
|
||||||
|
|
||||||
|
SharedPreferences mSettings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
String temp;
|
||||||
|
String unit;
|
||||||
|
if (mSettings.getString("temp_units","").equals("°F")){
|
||||||
|
temp =changeToInt(cf.getTemp_f());
|
||||||
|
unit = "°F";
|
||||||
|
}else {
|
||||||
|
temp = changeToInt(cf.getTemp_c());
|
||||||
|
unit = "°C";
|
||||||
|
}
|
||||||
|
|
||||||
|
views.setRemoteAdapter(R.id.widget_listview, intent);
|
||||||
|
views.setTextViewText(R.id.widget_main_temp,temp);
|
||||||
|
views.setTextViewText(R.id.widget_feel_temp,unit);
|
||||||
|
views.setTextViewText(R.id.dash," / ");
|
||||||
|
views.setTextViewText(R.id.widget_item_temp_high,changeToInt(forecastItem.getForecastArrayList().get(0).getMaxtemp_c())+"°");
|
||||||
|
views.setTextViewText(R.id.widget_item_temp_low,changeToInt(forecastItem.getForecastArrayList().get(0).getMintemp_c())+"°");
|
||||||
|
views.setTextViewText(R.id.widget_current_location,getLocationName(context,cf.getLatitude(),cf.getLongitude()));
|
||||||
|
views.setImageViewResource(R.id.location_icon, R.drawable.location_flag);
|
||||||
|
views.setImageViewResource(R.id.widget_current_icon,
|
||||||
|
getImageResource(cf.getIconURL(),context));
|
||||||
|
|
||||||
|
Intent clickIntentTemplate = new Intent(context, FurtherInfoActivity.class);
|
||||||
|
PendingIntent clickPendingIntentTemplate = TaskStackBuilder.create(context)
|
||||||
|
.addNextIntentWithParentStack(clickIntentTemplate)
|
||||||
|
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
views.setPendingIntentTemplate(R.id.widget_listview, clickPendingIntentTemplate);
|
||||||
|
|
||||||
|
views.setOnClickPendingIntent(R.id.widget_current_icon, pendingUpdate);
|
||||||
|
views.setOnClickPendingIntent(R.id.widget_current_location,pendingUpdate);
|
||||||
|
|
||||||
|
// Instruct the widget manager to update the widget
|
||||||
|
appWidgetManager.updateAppWidget(appWidgetId, views);
|
||||||
|
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview);
|
||||||
|
Log.i(TAG, "onPostExecute: finished at " + getCurrentTimeUsingDate());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Log.i(TAG, "onPostExecute: null part executed");
|
||||||
|
|
||||||
|
views.setTextViewText(R.id.widget_current_location,"Refresh");
|
||||||
|
views.setImageViewResource(R.id.widget_current_icon, R.drawable.widget_error_icon);
|
||||||
|
views.setImageViewResource(R.id.location_icon, R.drawable.refreshing);
|
||||||
|
|
||||||
|
views.setOnClickPendingIntent(R.id.widget_current_icon, pendingUpdate);
|
||||||
|
views.setOnClickPendingIntent(R.id.widget_current_location,pendingUpdate);
|
||||||
|
|
||||||
|
appWidgetManager.updateAppWidget(appWidgetId, views);
|
||||||
|
// appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview);
|
||||||
|
//add a listener to the view
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String getCurrentTimeUsingDate() {
|
||||||
|
Date date = new Date();
|
||||||
|
String strDateFormat = "hh:mm:ss.SSS";
|
||||||
|
DateFormat dateFormat = new SimpleDateFormat(strDateFormat);
|
||||||
|
|
||||||
|
return dateFormat.format(date);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather.AppWidget;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.widget.RemoteViewsService;
|
||||||
|
|
||||||
|
|
||||||
|
public class WidgetRemoteViewsService extends RemoteViewsService{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RemoteViewsFactory onGetViewFactory(Intent intent) {
|
||||||
|
return new MyWidgetRemoteViewsFactory(getApplicationContext(),intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,358 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
public class CurrentForecast implements Parcelable{
|
||||||
|
|
||||||
|
private String location;
|
||||||
|
private Double latitude;
|
||||||
|
private Double longitude;
|
||||||
|
private int last_updated_epoch;
|
||||||
|
private Double temp_c;
|
||||||
|
private Double temp_f;
|
||||||
|
private String condition_text;
|
||||||
|
private String iconURL;
|
||||||
|
private Double wind_mph;
|
||||||
|
private Double wind_kph;
|
||||||
|
private String wind_dir;
|
||||||
|
private Double pressure_mb;
|
||||||
|
private Double pressure_in;
|
||||||
|
private Double precip_mm;
|
||||||
|
private Double precip_in;
|
||||||
|
private Double humidity;
|
||||||
|
private Double cloud;
|
||||||
|
private Double feelslike_c;
|
||||||
|
private Double feelslike_f;
|
||||||
|
private Double vis_km;
|
||||||
|
private Double vis_miles;
|
||||||
|
|
||||||
|
public CurrentForecast() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public CurrentForecast(String location, Double latitude, Double longitude, int last_updated_epoch,
|
||||||
|
Double temp_c, Double temp_f, String condition_text, String iconURL, Double wind_mph,
|
||||||
|
Double wind_kph, String wind_dir, Double pressure_mb, Double pressure_in, Double precip_mm,
|
||||||
|
Double precip_in, Double humidity, Double cloud, Double feelslike_c, Double feelslike_f,
|
||||||
|
Double vis_km, Double vis_miles) {
|
||||||
|
this.location = location;
|
||||||
|
this.latitude = latitude;
|
||||||
|
this.longitude = longitude;
|
||||||
|
this.last_updated_epoch = last_updated_epoch;
|
||||||
|
this.temp_c = temp_c;
|
||||||
|
this.temp_f = temp_f;
|
||||||
|
this.condition_text = condition_text;
|
||||||
|
this.iconURL = iconURL;
|
||||||
|
this.wind_mph = wind_mph;
|
||||||
|
this.wind_kph = wind_kph;
|
||||||
|
this.wind_dir = wind_dir;
|
||||||
|
this.pressure_mb = pressure_mb;
|
||||||
|
this.pressure_in = pressure_in;
|
||||||
|
this.precip_mm = precip_mm;
|
||||||
|
this.precip_in = precip_in;
|
||||||
|
this.humidity = humidity;
|
||||||
|
this.cloud = cloud;
|
||||||
|
this.feelslike_c = feelslike_c;
|
||||||
|
this.feelslike_f = feelslike_f;
|
||||||
|
this.vis_km = vis_km;
|
||||||
|
this.vis_miles = vis_miles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getLatitude() {
|
||||||
|
return latitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getLongitude() {
|
||||||
|
return longitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLast_updated_epoch() {
|
||||||
|
return last_updated_epoch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getTemp_c() {
|
||||||
|
return temp_c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getTemp_f() {
|
||||||
|
return temp_f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCondition_text() {
|
||||||
|
return condition_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIconURL() {
|
||||||
|
return iconURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getWind_mph() {
|
||||||
|
return wind_mph;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getWind_kph() {
|
||||||
|
return wind_kph;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWind_dir() {
|
||||||
|
return wind_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getPressure_mb() {
|
||||||
|
return pressure_mb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getPressure_in() {
|
||||||
|
return pressure_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getPrecip_mm() {
|
||||||
|
return precip_mm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getPrecip_in() {
|
||||||
|
return precip_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getHumidity() {
|
||||||
|
return humidity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getCloud() {
|
||||||
|
return cloud;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getFeelslike_c() {
|
||||||
|
return feelslike_c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getFeelslike_f() {
|
||||||
|
return feelslike_f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getVis_km() {
|
||||||
|
return vis_km;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getVis_miles() {
|
||||||
|
return vis_miles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Creator<CurrentForecast> getCREATOR() {
|
||||||
|
return CREATOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CurrentForecast(Parcel in) {
|
||||||
|
location = in.readString();
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
latitude = null;
|
||||||
|
} else {
|
||||||
|
latitude = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
longitude = null;
|
||||||
|
} else {
|
||||||
|
longitude = in.readDouble();
|
||||||
|
}
|
||||||
|
last_updated_epoch = in.readInt();
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
temp_c = null;
|
||||||
|
} else {
|
||||||
|
temp_c = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
temp_f = null;
|
||||||
|
} else {
|
||||||
|
temp_f = in.readDouble();
|
||||||
|
}
|
||||||
|
condition_text = in.readString();
|
||||||
|
iconURL = in.readString();
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
wind_mph = null;
|
||||||
|
} else {
|
||||||
|
wind_mph = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
wind_kph = null;
|
||||||
|
} else {
|
||||||
|
wind_kph = in.readDouble();
|
||||||
|
}
|
||||||
|
wind_dir = in.readString();
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
pressure_mb = null;
|
||||||
|
} else {
|
||||||
|
pressure_mb = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
pressure_in = null;
|
||||||
|
} else {
|
||||||
|
pressure_in = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
precip_mm = null;
|
||||||
|
} else {
|
||||||
|
precip_mm = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
precip_in = null;
|
||||||
|
} else {
|
||||||
|
precip_in = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
humidity = null;
|
||||||
|
} else {
|
||||||
|
humidity = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
cloud = null;
|
||||||
|
} else {
|
||||||
|
cloud = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
feelslike_c = null;
|
||||||
|
} else {
|
||||||
|
feelslike_c = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
feelslike_f = null;
|
||||||
|
} else {
|
||||||
|
feelslike_f = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
vis_km = null;
|
||||||
|
} else {
|
||||||
|
vis_km = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
vis_miles = null;
|
||||||
|
} else {
|
||||||
|
vis_miles = in.readDouble();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<CurrentForecast> CREATOR = new Creator<CurrentForecast>() {
|
||||||
|
@Override
|
||||||
|
public CurrentForecast createFromParcel(Parcel in) {
|
||||||
|
return new CurrentForecast(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CurrentForecast[] newArray(int size) {
|
||||||
|
return new CurrentForecast[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel parcel, int i) {
|
||||||
|
parcel.writeString(location);
|
||||||
|
if (latitude == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(latitude);
|
||||||
|
}
|
||||||
|
if (longitude == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(longitude);
|
||||||
|
}
|
||||||
|
parcel.writeInt(last_updated_epoch);
|
||||||
|
if (temp_c == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(temp_c);
|
||||||
|
}
|
||||||
|
if (temp_f == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(temp_f);
|
||||||
|
}
|
||||||
|
parcel.writeString(condition_text);
|
||||||
|
parcel.writeString(iconURL);
|
||||||
|
if (wind_mph == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(wind_mph);
|
||||||
|
}
|
||||||
|
if (wind_kph == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(wind_kph);
|
||||||
|
}
|
||||||
|
parcel.writeString(wind_dir);
|
||||||
|
if (pressure_mb == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(pressure_mb);
|
||||||
|
}
|
||||||
|
if (pressure_in == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(pressure_in);
|
||||||
|
}
|
||||||
|
if (precip_mm == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(precip_mm);
|
||||||
|
}
|
||||||
|
if (precip_in == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(precip_in);
|
||||||
|
}
|
||||||
|
if (humidity == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(humidity);
|
||||||
|
}
|
||||||
|
if (cloud == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(cloud);
|
||||||
|
}
|
||||||
|
if (feelslike_c == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(feelslike_c);
|
||||||
|
}
|
||||||
|
if (feelslike_f == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(feelslike_f);
|
||||||
|
}
|
||||||
|
if (vis_km == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(vis_km);
|
||||||
|
}
|
||||||
|
if (vis_miles == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(vis_miles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.appttude.h_mal.atlas_weather.MainActivity.changeToInt;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.MainActivity.getImageResource;
|
||||||
|
|
||||||
|
public class CurrentForecastAdapter extends ArrayAdapter<ForecastItem> {
|
||||||
|
Context context;
|
||||||
|
private SharedPreferences mSettings;
|
||||||
|
|
||||||
|
public CurrentForecastAdapter(@NonNull Context context, @NonNull List<ForecastItem> objects) {
|
||||||
|
super(context, 0, objects);
|
||||||
|
this.context = context;
|
||||||
|
|
||||||
|
mSettings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
|
||||||
|
View listItemView = convertView;
|
||||||
|
|
||||||
|
if (listItemView == null) {
|
||||||
|
listItemView = LayoutInflater.from(getContext()).inflate(R.layout.db_list_item, parent,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentForecast currentForecast = null;
|
||||||
|
try {
|
||||||
|
currentForecast = getItem(position).getCurrentForecast();
|
||||||
|
}catch (Exception e){
|
||||||
|
Log.e(getClass().getSimpleName(), "error: ", e);
|
||||||
|
}finally {
|
||||||
|
if (currentForecast != null){
|
||||||
|
TextView location = listItemView.findViewById(R.id.db_location);
|
||||||
|
location.setText(currentForecast.getLocation());
|
||||||
|
|
||||||
|
TextView conditionTV = listItemView.findViewById(R.id.db_condition);
|
||||||
|
conditionTV.setText(currentForecast.getCondition_text());
|
||||||
|
|
||||||
|
ImageView weatherIV = listItemView.findViewById(R.id.db_icon);
|
||||||
|
weatherIV.setImageResource(getImageResource(currentForecast.getIconURL(), context));
|
||||||
|
|
||||||
|
TextView mainTempTV = listItemView.findViewById(R.id.db_main_temp);
|
||||||
|
TextView tempUnit = listItemView.findViewById(R.id.db_minor_temp);
|
||||||
|
if (mSettings.getString("temp_units","").equals("°F")){
|
||||||
|
mainTempTV.setText(changeToInt(currentForecast.getTemp_f()));
|
||||||
|
tempUnit.setText("°F");
|
||||||
|
}else {
|
||||||
|
mainTempTV.setText(changeToInt(currentForecast.getTemp_c()));
|
||||||
|
tempUnit.setText("°C");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return listItemView;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openWorldItem(ForecastItem forcast){
|
||||||
|
Intent i = new Intent(context,WorldItemActivity.class);
|
||||||
|
i.putExtra("ForecastItem",forcast);
|
||||||
|
context.startActivity(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
351
app/src/main/java/com/appttude/h_mal/atlas_weather/Forecast.java
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by h_mal on 19/04/2018.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Forecast implements Parcelable {
|
||||||
|
|
||||||
|
private Long date_epoch;
|
||||||
|
private Double maxtemp_c;
|
||||||
|
private Double maxtemp_f;
|
||||||
|
private Double mintemp_c;
|
||||||
|
private Double mintemp_f;
|
||||||
|
private Double avgtemp_c;
|
||||||
|
private Double avgtemp_f;
|
||||||
|
private Double maxwind_mph;
|
||||||
|
private Double maxwind_kph;
|
||||||
|
private Double totalprecip_mm;
|
||||||
|
private Double totalprecip_in;
|
||||||
|
private Double avgvis_km;
|
||||||
|
private Double avgvis_miles;
|
||||||
|
private Double avghumidity;
|
||||||
|
private String forecast_text;
|
||||||
|
private String iconURL;
|
||||||
|
private Double uv;
|
||||||
|
private String sunrise;
|
||||||
|
private String sunset;
|
||||||
|
private String moonrise;
|
||||||
|
private String moonset;
|
||||||
|
|
||||||
|
public Forecast(Long date_epoch, Double maxtemp_c, Double maxtemp_f, Double mintemp_c, Double mintemp_f, Double avgtemp_c, Double avgtemp_f,
|
||||||
|
Double maxwind_mph, Double maxwind_kph, Double totalprecip_mm, Double totalprecip_in, Double avgvis_km, Double avgvis_miles,
|
||||||
|
Double avghumidity, String forecast_text, String iconURL, Double uv, String sunrise, String sunset, String moonrise, String moonset) {
|
||||||
|
this.date_epoch = date_epoch;
|
||||||
|
this.maxtemp_c = maxtemp_c;
|
||||||
|
this.maxtemp_f = maxtemp_f;
|
||||||
|
this.mintemp_c = mintemp_c;
|
||||||
|
this.mintemp_f = mintemp_f;
|
||||||
|
this.avgtemp_c = avgtemp_c;
|
||||||
|
this.avgtemp_f = avgtemp_f;
|
||||||
|
this.maxwind_mph = maxwind_mph;
|
||||||
|
this.maxwind_kph = maxwind_kph;
|
||||||
|
this.totalprecip_mm = totalprecip_mm;
|
||||||
|
this.totalprecip_in = totalprecip_in;
|
||||||
|
this.avgvis_km = avgvis_km;
|
||||||
|
this.avgvis_miles = avgvis_miles;
|
||||||
|
this.avghumidity = avghumidity;
|
||||||
|
this.forecast_text = forecast_text;
|
||||||
|
this.iconURL = iconURL;
|
||||||
|
this.uv = uv;
|
||||||
|
this.sunrise = sunrise;
|
||||||
|
this.sunset = sunset;
|
||||||
|
this.moonrise = moonrise;
|
||||||
|
this.moonset = moonset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Forecast(Long date_epoch, Double avgtemp_c,String forecast_text, String iconURL) {
|
||||||
|
this.date_epoch = date_epoch;
|
||||||
|
this.avgtemp_c = avgtemp_c;
|
||||||
|
this.forecast_text = forecast_text;
|
||||||
|
this.iconURL = iconURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Forecast(Parcel in) {
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
date_epoch = null;
|
||||||
|
} else {
|
||||||
|
date_epoch = in.readLong();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
maxtemp_c = null;
|
||||||
|
} else {
|
||||||
|
maxtemp_c = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
maxtemp_f = null;
|
||||||
|
} else {
|
||||||
|
maxtemp_f = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
mintemp_c = null;
|
||||||
|
} else {
|
||||||
|
mintemp_c = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
mintemp_f = null;
|
||||||
|
} else {
|
||||||
|
mintemp_f = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
avgtemp_c = null;
|
||||||
|
} else {
|
||||||
|
avgtemp_c = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
avgtemp_f = null;
|
||||||
|
} else {
|
||||||
|
avgtemp_f = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
maxwind_mph = null;
|
||||||
|
} else {
|
||||||
|
maxwind_mph = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
maxwind_kph = null;
|
||||||
|
} else {
|
||||||
|
maxwind_kph = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
totalprecip_mm = null;
|
||||||
|
} else {
|
||||||
|
totalprecip_mm = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
totalprecip_in = null;
|
||||||
|
} else {
|
||||||
|
totalprecip_in = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
avgvis_km = null;
|
||||||
|
} else {
|
||||||
|
avgvis_km = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
avgvis_miles = null;
|
||||||
|
} else {
|
||||||
|
avgvis_miles = in.readDouble();
|
||||||
|
}
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
avghumidity = null;
|
||||||
|
} else {
|
||||||
|
avghumidity = in.readDouble();
|
||||||
|
}
|
||||||
|
forecast_text = in.readString();
|
||||||
|
iconURL = in.readString();
|
||||||
|
if (in.readByte() == 0) {
|
||||||
|
uv = null;
|
||||||
|
} else {
|
||||||
|
uv = in.readDouble();
|
||||||
|
}
|
||||||
|
sunrise = in.readString();
|
||||||
|
sunset = in.readString();
|
||||||
|
moonrise = in.readString();
|
||||||
|
moonset = in.readString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<Forecast> CREATOR = new Creator<Forecast>() {
|
||||||
|
@Override
|
||||||
|
public Forecast createFromParcel(Parcel in) {
|
||||||
|
return new Forecast(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Forecast[] newArray(int size) {
|
||||||
|
return new Forecast[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public Long getDate_epoch() {
|
||||||
|
return date_epoch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getMaxtemp_c() {
|
||||||
|
return maxtemp_c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getMaxtemp_f() {
|
||||||
|
return maxtemp_f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getMintemp_c() {
|
||||||
|
return mintemp_c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getMintemp_f() {
|
||||||
|
return mintemp_f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getAvgtemp_c() {
|
||||||
|
return avgtemp_c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getAvgtemp_f() {
|
||||||
|
return avgtemp_f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getMaxwind_mph() {
|
||||||
|
return maxwind_mph;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getMaxwind_kph() {
|
||||||
|
return maxwind_kph;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getTotalprecip_mm() {
|
||||||
|
return totalprecip_mm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getTotalprecip_in() {
|
||||||
|
return totalprecip_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getAvgvis_km() {
|
||||||
|
return avgvis_km;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getAvgvis_miles() {
|
||||||
|
return avgvis_miles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getAvghumidity() {
|
||||||
|
return avghumidity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getForecast_text() {
|
||||||
|
return forecast_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIconURL() {
|
||||||
|
return iconURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getUv() {
|
||||||
|
return uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSunrise() {
|
||||||
|
return sunrise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSunset() {
|
||||||
|
return sunset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMoonrise() {
|
||||||
|
return moonrise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMoonset() {
|
||||||
|
return moonset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel parcel, int i) {
|
||||||
|
if (date_epoch == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeLong(date_epoch);
|
||||||
|
}
|
||||||
|
if (maxtemp_c == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(maxtemp_c);
|
||||||
|
}
|
||||||
|
if (maxtemp_f == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(maxtemp_f);
|
||||||
|
}
|
||||||
|
if (mintemp_c == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(mintemp_c);
|
||||||
|
}
|
||||||
|
if (mintemp_f == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(mintemp_f);
|
||||||
|
}
|
||||||
|
if (avgtemp_c == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(avgtemp_c);
|
||||||
|
}
|
||||||
|
if (avgtemp_f == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(avgtemp_f);
|
||||||
|
}
|
||||||
|
if (maxwind_mph == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(maxwind_mph);
|
||||||
|
}
|
||||||
|
if (maxwind_kph == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(maxwind_kph);
|
||||||
|
}
|
||||||
|
if (totalprecip_mm == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(totalprecip_mm);
|
||||||
|
}
|
||||||
|
if (totalprecip_in == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(totalprecip_in);
|
||||||
|
}
|
||||||
|
if (avgvis_km == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(avgvis_km);
|
||||||
|
}
|
||||||
|
if (avgvis_miles == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(avgvis_miles);
|
||||||
|
}
|
||||||
|
if (avghumidity == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(avghumidity);
|
||||||
|
}
|
||||||
|
parcel.writeString(forecast_text);
|
||||||
|
parcel.writeString(iconURL);
|
||||||
|
if (uv == null) {
|
||||||
|
parcel.writeByte((byte) 0);
|
||||||
|
} else {
|
||||||
|
parcel.writeByte((byte) 1);
|
||||||
|
parcel.writeDouble(uv);
|
||||||
|
}
|
||||||
|
parcel.writeString(sunrise);
|
||||||
|
parcel.writeString(sunset);
|
||||||
|
parcel.writeString(moonrise);
|
||||||
|
parcel.writeString(moonset);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ForecastItem implements Parcelable {
|
||||||
|
|
||||||
|
private CurrentForecast currentForecast;
|
||||||
|
private List<Forecast> forecastArrayList;
|
||||||
|
|
||||||
|
public ForecastItem(CurrentForecast currentForecast, List<Forecast> forecastArrayList) {
|
||||||
|
this.currentForecast = currentForecast;
|
||||||
|
this.forecastArrayList = forecastArrayList;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ForecastItem(Parcel in) {
|
||||||
|
currentForecast = in.readParcelable(CurrentForecast.class.getClassLoader());
|
||||||
|
forecastArrayList = in.createTypedArrayList(Forecast.CREATOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<ForecastItem> CREATOR = new Creator<ForecastItem>() {
|
||||||
|
@Override
|
||||||
|
public ForecastItem createFromParcel(Parcel in) {
|
||||||
|
return new ForecastItem(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ForecastItem[] newArray(int size) {
|
||||||
|
return new ForecastItem[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public CurrentForecast getCurrentForecast() {
|
||||||
|
return currentForecast;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Forecast> getForecastArrayList() {
|
||||||
|
return forecastArrayList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel parcel, int i) {
|
||||||
|
parcel.writeParcelable(currentForecast, i);
|
||||||
|
parcel.writeTypedList(forecastArrayList);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.createUrl;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.extractFeatureFromJson;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.makeHttpRequest;
|
||||||
|
|
||||||
|
public class ForecastLoader extends android.support.v4.content.AsyncTaskLoader<List<ForecastItem>> {
|
||||||
|
|
||||||
|
private ArrayList<String> mUrl;
|
||||||
|
|
||||||
|
public ForecastLoader(Context context, ArrayList<String> url) {
|
||||||
|
super(context);
|
||||||
|
this.mUrl = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStartLoading() {
|
||||||
|
forceLoad();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ForecastItem> loadInBackground() {
|
||||||
|
if (mUrl == null) {
|
||||||
|
Log.i("", "loadInBackground: " + "null");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String json = null;
|
||||||
|
List<ForecastItem> forecastItems = new ArrayList<ForecastItem>();
|
||||||
|
|
||||||
|
for (int i = 0; i < mUrl.size(); i++) {
|
||||||
|
try {
|
||||||
|
URL url = createUrl(mUrl.get(i));
|
||||||
|
json = makeHttpRequest(url);
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("", "Problem making the HTTP request.", e);
|
||||||
|
}finally {
|
||||||
|
if (!TextUtils.isEmpty(json)) {
|
||||||
|
forecastItems.add(extractFeatureFromJson(json));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forecastItems.size() < 1){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return forecastItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,186 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.design.widget.FloatingActionButton;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v4.app.LoaderManager;
|
||||||
|
import android.support.v4.content.Loader;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.appttude.h_mal.atlas_weather.dbfiles.ForecastContract;
|
||||||
|
import com.appttude.h_mal.atlas_weather.dbfiles.ForecastContract.ForecastEntry;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.appttude.h_mal.atlas_weather.MainActivity.networkInfo;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.UriBuilder;
|
||||||
|
|
||||||
|
public class Fragment_Two extends Fragment implements android.support.v4.app.LoaderManager.LoaderCallbacks<List<ForecastItem>>{
|
||||||
|
|
||||||
|
private static final int NEWS_LOADER_ID = 1;
|
||||||
|
private String TAG = getClass().getSimpleName();
|
||||||
|
|
||||||
|
CurrentForecastAdapter mAdapter;
|
||||||
|
ProgressBar pb_2;
|
||||||
|
LinearLayout emptyView;
|
||||||
|
ListView lv;
|
||||||
|
android.support.v4.app.LoaderManager loaderManager;
|
||||||
|
|
||||||
|
public Fragment_Two() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
View rootView = inflater.inflate(R.layout.fragment__two, container, false);
|
||||||
|
|
||||||
|
emptyView = rootView.findViewById(R.id.emptyView);
|
||||||
|
pb_2 = rootView.findViewById(R.id.progressBar2);
|
||||||
|
|
||||||
|
lv = rootView.findViewById(R.id.listview);
|
||||||
|
|
||||||
|
final LoaderManager.LoaderCallbacks callbacks = this;
|
||||||
|
loaderManager = getLoaderManager();
|
||||||
|
loaderManager.initLoader(NEWS_LOADER_ID, null, callbacks);
|
||||||
|
|
||||||
|
mAdapter = new CurrentForecastAdapter(getActivity(), new ArrayList<ForecastItem>());
|
||||||
|
lv.setAdapter(mAdapter);
|
||||||
|
lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onItemLongClick(AdapterView<?> adapterView, View view, final int i, long l) {
|
||||||
|
|
||||||
|
new AlertDialog.Builder(getContext())
|
||||||
|
.setTitle("Delete?")
|
||||||
|
.setMessage("Continue?")
|
||||||
|
.setNegativeButton(android.R.string.no, null)
|
||||||
|
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface arg0, int arg1) {
|
||||||
|
Cursor cursor = getActivity().getContentResolver().query(ForecastContract.ForecastEntry.CONTENT_URI,
|
||||||
|
new String[]{ForecastContract.ForecastEntry._ID,ForecastContract.ForecastEntry.COLUMN_FORECAST_NAME},
|
||||||
|
null,null,null);
|
||||||
|
|
||||||
|
cursor.moveToPosition(i);
|
||||||
|
int id = cursor.getInt(cursor.getColumnIndexOrThrow(ForecastContract.ForecastEntry._ID));
|
||||||
|
String selection = ForecastContract.ForecastEntry._ID + "=?";
|
||||||
|
getActivity().getContentResolver().delete(ForecastContract.ForecastEntry.CONTENT_URI,
|
||||||
|
selection, new String[]{id + ""});
|
||||||
|
|
||||||
|
loaderManager.restartLoader(NEWS_LOADER_ID, null, callbacks);
|
||||||
|
}
|
||||||
|
}).create().show();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
|
||||||
|
Intent intent = new Intent(getContext(),WorldItemActivity.class);
|
||||||
|
intent.putExtra("ForecastItem",mAdapter.getItem(i));
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
FloatingActionButton fab = rootView.findViewById(R.id.floatingActionButton);
|
||||||
|
fab.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
Intent i = new Intent(getActivity(), AddForecast.class);
|
||||||
|
startActivity(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (networkInfo != null && networkInfo.isConnected()) {
|
||||||
|
loaderManager.initLoader(NEWS_LOADER_ID, null, callbacks);
|
||||||
|
} else {
|
||||||
|
// emptyList.setVisibility(View.VISIBLE);
|
||||||
|
// mainPG.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rootView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
loaderManager.restartLoader(NEWS_LOADER_ID, null, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Loader<List<ForecastItem>> onCreateLoader(int id, Bundle args) {
|
||||||
|
pb_2.setVisibility(View.VISIBLE);
|
||||||
|
lv.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
ArrayList<String> entries = new ArrayList<>();
|
||||||
|
|
||||||
|
String[] projection = {ForecastEntry.COLUMN_FORECAST_NAME};
|
||||||
|
Cursor cursor = getActivity().getContentResolver().query(ForecastEntry.CONTENT_URI,
|
||||||
|
projection,null,null,null);
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
final String descriptionColumnIndex = cursor.getString(cursor.getColumnIndexOrThrow(ForecastEntry.COLUMN_FORECAST_NAME));
|
||||||
|
entries.add(UriBuilder(descriptionColumnIndex));
|
||||||
|
}
|
||||||
|
}catch (Exception e){
|
||||||
|
Log.e(TAG, "onCreateLoader: ",e );
|
||||||
|
}finally {
|
||||||
|
if (cursor != null) {
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ForecastLoader(getContext(),entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoadFinished(Loader<List<ForecastItem>> loader, List<ForecastItem> data) {
|
||||||
|
mAdapter.clear();
|
||||||
|
|
||||||
|
TextView t = emptyView.findViewById(R.id.emptyViewText);
|
||||||
|
|
||||||
|
if (data == null){
|
||||||
|
lv.setVisibility(View.GONE);
|
||||||
|
emptyView.setVisibility(View.VISIBLE);
|
||||||
|
t.setText("Add Items");
|
||||||
|
Log.i(TAG, "onLoadFinished: data null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(networkInfo == null || !networkInfo.isConnected()){
|
||||||
|
lv.setVisibility(View.GONE);
|
||||||
|
emptyView.setVisibility(View.VISIBLE);
|
||||||
|
t.setText("Check connection...");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data != null && !data.isEmpty()) {
|
||||||
|
|
||||||
|
for (int i = 0; i < data.size(); i++) {
|
||||||
|
mAdapter.add(data.get(i));
|
||||||
|
}
|
||||||
|
emptyView.setVisibility(View.GONE);
|
||||||
|
Log.i(TAG, "onLoadFinished: data not null");
|
||||||
|
lv.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
pb_2.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoaderReset(Loader<List<ForecastItem>> loader) {
|
||||||
|
pb_2.setVisibility(View.GONE);
|
||||||
|
mAdapter.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,204 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v4.widget.SwipeRefreshLayout;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.UriBuilder;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.createUrl;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.getLatLong.latitude;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.getLatLong.longitude;
|
||||||
|
|
||||||
|
|
||||||
|
public class Fragment_home extends Fragment implements android.support.v4.app.LoaderManager.LoaderCallbacks<List<ForecastItem>>{
|
||||||
|
|
||||||
|
protected static String APIkey = "2e914b44f94a4f07853100835181104";
|
||||||
|
android.support.v4.app.LoaderManager loaderManager;
|
||||||
|
android.support.v4.app.LoaderManager.LoaderCallbacks callbacks;
|
||||||
|
public static int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
|
||||||
|
|
||||||
|
private static final int NEWS_LOADER_ID = 1;
|
||||||
|
|
||||||
|
RecyclerView forecastsListView;
|
||||||
|
LinearLayout emptyList;
|
||||||
|
ProgressBar mainPG;
|
||||||
|
Button button;
|
||||||
|
|
||||||
|
private RecyclerViewAdapter mAdapter;
|
||||||
|
SwipeRefreshLayout mSwipeRefreshLayout;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// getLatLong.configLatLong(getContext());
|
||||||
|
// }catch (Exception e){
|
||||||
|
// System.out.println("error msg: " + e);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (ActivityCompat.checkSelfPermission(getContext(),
|
||||||
|
android.Manifest.permission.ACCESS_FINE_LOCATION)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
|
|
||||||
|
if (!ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
|
||||||
|
android.Manifest.permission.ACCESS_FINE_LOCATION)) {
|
||||||
|
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
|
||||||
|
MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forecastsListView = rootView.findViewById(R.id.forecast_listview);
|
||||||
|
forecastsListView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
|
||||||
|
emptyList = rootView.findViewById(R.id.emptyView);
|
||||||
|
mainPG = rootView.findViewById(R.id.mainPB);
|
||||||
|
|
||||||
|
emptyList.setVisibility(View.GONE);
|
||||||
|
button = emptyList.findViewById(R.id.emptyViewButton);
|
||||||
|
|
||||||
|
mSwipeRefreshLayout = rootView.findViewById(R.id.swipe_refresh);
|
||||||
|
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||||
|
@Override
|
||||||
|
public void onRefresh() {
|
||||||
|
loaderManager.restartLoader(NEWS_LOADER_ID,null,callbacks);
|
||||||
|
mSwipeRefreshLayout.setRefreshing(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
loaderManager = getLoaderManager();
|
||||||
|
callbacks = this;
|
||||||
|
|
||||||
|
// if (MainActivity.networkInfo != null && MainActivity.networkInfo.isConnected()) {
|
||||||
|
loaderManager.initLoader(NEWS_LOADER_ID, null, callbacks);
|
||||||
|
// } else {
|
||||||
|
// emptyList.setVisibility(View.VISIBLE);
|
||||||
|
// mainPG.setVisibility(View.GONE);
|
||||||
|
// button.setVisibility(View.GONE);
|
||||||
|
// }
|
||||||
|
|
||||||
|
return rootView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
|
||||||
|
if (requestCode == MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION){
|
||||||
|
if (grantResults.length > 0
|
||||||
|
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
try {
|
||||||
|
getLatLong.configLatLong(getContext());
|
||||||
|
}catch (Exception e){
|
||||||
|
System.out.println("error msg: " + e);
|
||||||
|
}
|
||||||
|
loaderManager.restartLoader(NEWS_LOADER_ID, null, callbacks);
|
||||||
|
Toast.makeText(getContext(), "Permission granted", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Toast.makeText(getContext(), "Permission denied", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public android.support.v4.content.Loader<List<ForecastItem>> onCreateLoader(int id, Bundle args) {
|
||||||
|
mainPG.setVisibility(View.VISIBLE);
|
||||||
|
ArrayList<String> entries = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
getLatLong.configLatLong(getContext());
|
||||||
|
}catch (Exception e){
|
||||||
|
System.out.println("error msg: " + e);
|
||||||
|
}finally {
|
||||||
|
if (latitude != null){
|
||||||
|
URL url = createUrl(UriBuilder(7));
|
||||||
|
entries.add(url.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// getLatLong.configLatLong(getContext());
|
||||||
|
//// Toast.makeText(getContext(), "" + getLatLong.latitude.toString(), Toast.LENGTH_SHORT).show();
|
||||||
|
// URL url = createUrl(UriBuilder());
|
||||||
|
// ArrayList<String> entries = new ArrayList<>();
|
||||||
|
// entries.add(url.toString());
|
||||||
|
|
||||||
|
return new ForecastLoader(getContext(),entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoadFinished(android.support.v4.content.Loader<List<ForecastItem>> loader, List<ForecastItem> data) {
|
||||||
|
|
||||||
|
if (mSwipeRefreshLayout.isRefreshing()){
|
||||||
|
mSwipeRefreshLayout.setRefreshing(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ActivityCompat.checkSelfPermission(getContext(),
|
||||||
|
android.Manifest.permission.ACCESS_FINE_LOCATION)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED){
|
||||||
|
emptyList.setVisibility(View.VISIBLE);
|
||||||
|
TextView tv = emptyList.findViewById(R.id.emptyViewText);
|
||||||
|
tv.setText("Location Required");
|
||||||
|
|
||||||
|
button.setVisibility(View.VISIBLE);
|
||||||
|
button.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
grantPermission();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (data == null){
|
||||||
|
forecastsListView.setVisibility(View.GONE);
|
||||||
|
emptyList.setVisibility(View.VISIBLE);
|
||||||
|
button.setVisibility(View.GONE);
|
||||||
|
Toast.makeText(getContext(), "Could not retrieve data", Toast.LENGTH_SHORT).show();
|
||||||
|
}else{
|
||||||
|
mAdapter = new RecyclerViewAdapter(getContext(),data.get(0),latitude,longitude);
|
||||||
|
mAdapter.notifyDataSetChanged();
|
||||||
|
forecastsListView.setAdapter(mAdapter);
|
||||||
|
forecastsListView.setVisibility(View.VISIBLE);
|
||||||
|
emptyList.setVisibility(View.GONE);
|
||||||
|
button.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mainPG.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoaderReset(android.support.v4.content.Loader<List<ForecastItem>> loader) {
|
||||||
|
loader.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void grantPermission(){
|
||||||
|
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
|
||||||
|
MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
|
||||||
|
loaderManager.restartLoader(NEWS_LOADER_ID, null, callbacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import static com.appttude.h_mal.atlas_weather.MainActivity.changeToInt;
|
||||||
|
|
||||||
|
public class FurtherInfoActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_further_info);
|
||||||
|
|
||||||
|
Intent mIntent = getIntent();
|
||||||
|
Forecast forecast = mIntent.getParcelableExtra("currentForcast");
|
||||||
|
|
||||||
|
SharedPreferences mSettings = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
|
||||||
|
TextView maxTemp = findViewById(R.id.maxtemp);
|
||||||
|
TextView averageTemp = findViewById(R.id.averagetemp);
|
||||||
|
TextView minimumTemp = findViewById(R.id.minimumtemp);
|
||||||
|
TextView windText = findViewById(R.id.windtext);
|
||||||
|
TextView precipText = findViewById(R.id.preciptext);
|
||||||
|
TextView humidityText = findViewById(R.id.humiditytext);
|
||||||
|
TextView uvText = findViewById(R.id.uvtext);
|
||||||
|
TextView sunriseText = findViewById(R.id.sunrisetext);
|
||||||
|
TextView sunsetText = findViewById(R.id.sunsettext);
|
||||||
|
|
||||||
|
if (mSettings.getString("temp_units","").equals("°F")){
|
||||||
|
maxTemp.setText(changeToInt(forecast.getMaxtemp_f()) + mSettings.getString("temp_units","°F"));
|
||||||
|
averageTemp.setText(changeToInt(forecast.getAvgtemp_f())+mSettings.getString("temp_units","°F"));
|
||||||
|
minimumTemp.setText(changeToInt(forecast.getMintemp_f())+mSettings.getString("temp_units","°F"));
|
||||||
|
|
||||||
|
}else {
|
||||||
|
maxTemp.setText(changeToInt(forecast.getMaxtemp_c())+mSettings.getString("temp_units","°C"));
|
||||||
|
averageTemp.setText(changeToInt(forecast.getAvgtemp_c())+mSettings.getString("temp_units","°C"));
|
||||||
|
minimumTemp.setText(changeToInt(forecast.getMintemp_c())+mSettings.getString("temp_units","°C"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSettings.getString("wind_units","").equals("mph")){
|
||||||
|
windText.setText(String.valueOf(forecast.getMaxwind_mph()+mSettings.getString("wind_units","mhp")));
|
||||||
|
}else {
|
||||||
|
windText.setText(String.valueOf(forecast.getMaxwind_kph()+mSettings.getString("wind_units","kph")));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSettings.getString("precip_units","").equals("in")){
|
||||||
|
precipText.setText(String.valueOf(forecast.getTotalprecip_in()+mSettings.getString("precip_units","inches")));
|
||||||
|
}else {
|
||||||
|
precipText.setText(String.valueOf(forecast.getTotalprecip_mm()+ mSettings.getString("precip_units","mm")));
|
||||||
|
}
|
||||||
|
|
||||||
|
humidityText.setText(String.valueOf(forecast.getAvghumidity()));
|
||||||
|
uvText.setText(String.valueOf(forecast.getUv()));
|
||||||
|
sunriseText.setText(forecast.getSunrise());
|
||||||
|
sunsetText.setText(forecast.getSunset());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.widget.ListView;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class InfoActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.info_dialog_layout);
|
||||||
|
|
||||||
|
List<infopageItem> infopageItemList = new ArrayList<>();
|
||||||
|
infopageItemList.add(new infopageItem(R.drawable.day_305,
|
||||||
|
"Weather data and icons provided by: ",null,null,
|
||||||
|
"https://www.apixu.com/","APIXU"));
|
||||||
|
infopageItemList.add(new infopageItem(R.drawable.somethingnew,
|
||||||
|
"Icon made by: ",
|
||||||
|
"https://www.flaticon.com/authors/hirschwolf",
|
||||||
|
"Hirschwolf",
|
||||||
|
null,
|
||||||
|
null));
|
||||||
|
infopageItemList.add(new infopageItem(R.drawable.breeze,
|
||||||
|
"Icon made by: ",
|
||||||
|
"https://www.flaticon.com/authors/hirschwolf",
|
||||||
|
"Hirchwolf",
|
||||||
|
null,null));
|
||||||
|
infopageItemList.add(new infopageItem(R.drawable.water_drop,
|
||||||
|
"Icon made by: ",
|
||||||
|
"https://www.flaticon.com/authors/freepik",
|
||||||
|
"Freepic",
|
||||||
|
null,null));
|
||||||
|
infopageItemList.add(new infopageItem(R.drawable.cloud_symbol,
|
||||||
|
"Icon made by: ",
|
||||||
|
"https://www.flaticon.com/authors/simpleicon",
|
||||||
|
"Simple Icon",
|
||||||
|
null,null));
|
||||||
|
infopageItemList.add(new infopageItem(R.drawable.sun,
|
||||||
|
"Icon made by: ",
|
||||||
|
"https://www.flaticon.com/authors/freepik",
|
||||||
|
"Freepic",
|
||||||
|
null,null));
|
||||||
|
infopageItemList.add(new infopageItem(R.mipmap.ic_world,
|
||||||
|
"Icon made by: ",
|
||||||
|
"https://www.flaticon.com/authors/freepik",
|
||||||
|
"Freepic",
|
||||||
|
null,null));
|
||||||
|
|
||||||
|
ListView lf = findViewById(R.id.listview_info);
|
||||||
|
lf.setAdapter(new infopageItem.infoPageAdapter(this,infopageItemList));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,222 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.app.AlarmManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.location.Address;
|
||||||
|
import android.location.Geocoder;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.support.design.widget.TabLayout;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v4.app.FragmentManager;
|
||||||
|
import android.support.v4.app.FragmentPagerAdapter;
|
||||||
|
import android.support.v4.view.ViewPager;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.support.v7.widget.Toolbar;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
import com.appttude.h_mal.atlas_weather.dbfiles.ForecastDBHelper;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
|
||||||
|
private SectionsPagerAdapter mSectionsPagerAdapter;
|
||||||
|
private TabLayout tabLayout;
|
||||||
|
private ViewPager mViewPager;
|
||||||
|
public ForecastDBHelper forecastsDbhelper;
|
||||||
|
private String TAG = getClass().getSimpleName();
|
||||||
|
|
||||||
|
public static NetworkInfo networkInfo;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
|
||||||
|
|
||||||
|
mViewPager = (ViewPager) findViewById(R.id.container);
|
||||||
|
mViewPager.setAdapter(mSectionsPagerAdapter);
|
||||||
|
|
||||||
|
tabLayout = (TabLayout) findViewById(R.id.tabs);
|
||||||
|
tabLayout.setupWithViewPager(mViewPager);
|
||||||
|
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
|
||||||
|
|
||||||
|
// iconsInTabs(tabLayout);
|
||||||
|
|
||||||
|
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
|
||||||
|
|
||||||
|
boolean first_time_run = SP.getBoolean("FIRST_TIME_RUN",true);
|
||||||
|
|
||||||
|
Log.i(TAG, "onCreate: notification setup" + first_time_run);
|
||||||
|
|
||||||
|
if (first_time_run) {
|
||||||
|
setupNotificationBroadcaster(getApplicationContext());
|
||||||
|
|
||||||
|
// cal.add(Calendar.SECOND, 5);
|
||||||
|
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
|
// alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), broadcast);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
iconsInTabs(tabLayout);
|
||||||
|
|
||||||
|
ConnectivityManager connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
networkInfo = connectivityManager.getActiveNetworkInfo();
|
||||||
|
|
||||||
|
forecastsDbhelper = new ForecastDBHelper(getApplicationContext());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void iconsInTabs (TabLayout tabLayout){
|
||||||
|
|
||||||
|
int[] tabIcons = {R.mipmap.ic_home,R.mipmap.ic_world};
|
||||||
|
|
||||||
|
tabLayout.getTabAt(0).setIcon(tabIcons[0]);
|
||||||
|
tabLayout.getTabAt(1).setIcon(tabIcons[1]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
// Inflate the menu; this adds items to the action bar if it is present.
|
||||||
|
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
|
// Handle action bar item clicks here. The action bar will
|
||||||
|
// automatically handle clicks on the Home/Up button, so long
|
||||||
|
// as you specify a parent activity in AndroidManifest.xml.
|
||||||
|
int id = item.getItemId();
|
||||||
|
|
||||||
|
switch (id){
|
||||||
|
case R.id.action_settings:
|
||||||
|
Intent i = new Intent(this, UnitSettings.class);
|
||||||
|
startActivity(i);
|
||||||
|
return true;
|
||||||
|
case R.id.action_into:
|
||||||
|
Intent infoActivity = new Intent(this,InfoActivity.class);
|
||||||
|
startActivity(infoActivity);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return super.onOptionsItemSelected(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String changeToInt(Double d){
|
||||||
|
return String.valueOf(Math.round(d));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getImageResource(String s, Context context){
|
||||||
|
|
||||||
|
s =s.replace("cdn.apixu.com/weather/64x64/","");
|
||||||
|
s = s.replace(".png","");
|
||||||
|
s =s.replace("/","_");
|
||||||
|
s = s.substring(2);
|
||||||
|
|
||||||
|
return context.getResources().getIdentifier(s,"drawable",context.getPackageName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getLocationName(Context context, Double latitude, Double longitude) {
|
||||||
|
Geocoder geoCoder = new Geocoder(context, Locale.getDefault());
|
||||||
|
String result = "";
|
||||||
|
List<Address> list = null;
|
||||||
|
try {
|
||||||
|
list = geoCoder.getFromLocation(latitude, longitude, 1);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}finally {
|
||||||
|
if (list != null & list.size() > 0) {
|
||||||
|
Address address = list.get(0);
|
||||||
|
result = address.getLocality();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setupNotificationBroadcaster(Context context){
|
||||||
|
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||||
|
|
||||||
|
Intent notificationIntent = new Intent(context, NotificationReceiver.class);
|
||||||
|
PendingIntent broadcast = PendingIntent.getBroadcast(context, 100, notificationIntent,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
|
Calendar cal = Calendar.getInstance();
|
||||||
|
|
||||||
|
cal.set(Calendar.HOUR_OF_DAY, 6);
|
||||||
|
cal.set(Calendar.MINUTE, 8);
|
||||||
|
cal.set(Calendar.SECOND, 5);
|
||||||
|
|
||||||
|
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A placeholder fragment containing a simple view.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
|
||||||
|
* one of the sections/tabs/pages.
|
||||||
|
*/
|
||||||
|
public class SectionsPagerAdapter extends FragmentPagerAdapter {
|
||||||
|
|
||||||
|
public SectionsPagerAdapter(FragmentManager fm) {
|
||||||
|
super(fm);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fragment getItem(int position) {
|
||||||
|
switch (position){
|
||||||
|
case 0:
|
||||||
|
Fragment_home tab1 = new Fragment_home();
|
||||||
|
return tab1;
|
||||||
|
case 1:
|
||||||
|
Fragment_Two tab2 = new Fragment_Two();
|
||||||
|
return tab2;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
// Show 2 total pages.
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence getPageTitle(int position) {
|
||||||
|
// switch (position) {
|
||||||
|
// case 0:
|
||||||
|
// return "Home";
|
||||||
|
// case 1:
|
||||||
|
// return "World";
|
||||||
|
// }
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.app.TaskStackBuilder;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.graphics.drawable.Icon;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.squareup.picasso.Picasso;
|
||||||
|
import com.squareup.picasso.Target;
|
||||||
|
import com.squareup.picasso.Transformation;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.MainActivity.changeToInt;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.MainActivity.getImageResource;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.createUrl;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.extractFeatureFromJson;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.makeHttpRequest;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.getLatLong.latitude;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.getLatLong.longitude;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by h_mal on 29/04/2018.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class NotificationReceiver extends BroadcastReceiver{
|
||||||
|
|
||||||
|
private String TAG = getClass().getSimpleName();
|
||||||
|
|
||||||
|
private static final String NOTIFICATION_CHANNEL_ID = "my_notification_channel_1";
|
||||||
|
Context mContext;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
this.mContext = context;
|
||||||
|
|
||||||
|
Log.i(TAG, "onReceive: notif fired");
|
||||||
|
|
||||||
|
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
|
||||||
|
boolean notif = SP.getBoolean("notif_boolean",true);
|
||||||
|
|
||||||
|
if(notif) {
|
||||||
|
try {
|
||||||
|
getLatLong.configLatLong(mContext);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "onReceive: ", e);
|
||||||
|
} finally {
|
||||||
|
if (latitude != null && longitude != null) {
|
||||||
|
String stringURL = RetrieveJSON.UriBuilder(5);
|
||||||
|
NotifAsyncTask task = new NotifAsyncTask();
|
||||||
|
task.execute(stringURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SP.edit().putBoolean("FIRST_TIME_RUN",false).apply();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pushNotif(Context context, ForecastItem forecastItem){
|
||||||
|
Intent notificationIntent = new Intent(context, MainActivity.class);
|
||||||
|
|
||||||
|
CurrentForecast currentForecast = forecastItem.getCurrentForecast();
|
||||||
|
|
||||||
|
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
|
||||||
|
stackBuilder.addParentStack(MainActivity.class);
|
||||||
|
stackBuilder.addNextIntent(notificationIntent);
|
||||||
|
|
||||||
|
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
|
SharedPreferences mSettings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
String temp;
|
||||||
|
if (mSettings.getString("temp_units","").equals("°F")){
|
||||||
|
temp =changeToInt(currentForecast.getTemp_f());
|
||||||
|
}else {
|
||||||
|
temp = changeToInt(currentForecast.getTemp_c());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Notification.Builder builder = new Notification.Builder(context);
|
||||||
|
Notification notification = builder.setContentTitle("Weather App")
|
||||||
|
.setContentText(temp + "° - " + currentForecast.getCondition_text())
|
||||||
|
.setSmallIcon(R.mipmap.ic_notif) //change icon
|
||||||
|
.setLargeIcon(Icon.createWithResource(context,getImageResource(forecastItem.getCurrentForecast().getIconURL(),context)))
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setContentIntent(pendingIntent).build();
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
builder.setChannelId(NOTIFICATION_CHANNEL_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
NotificationChannel channel = new NotificationChannel(
|
||||||
|
NOTIFICATION_CHANNEL_ID,
|
||||||
|
"NotificationDemo",
|
||||||
|
IMPORTANCE_DEFAULT
|
||||||
|
);
|
||||||
|
notificationManager.createNotificationChannel(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
notificationManager.notify(0, notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NotifAsyncTask extends AsyncTask<String, Void, String> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String doInBackground(String... urlString) {
|
||||||
|
String jsonResponse = null;
|
||||||
|
|
||||||
|
if (urlString.length < 1 || urlString[0] == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
URL url = createUrl(urlString[0]);
|
||||||
|
jsonResponse = makeHttpRequest(url);
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(TAG, "Problem making the HTTP request.", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonResponse;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPreExecute() {
|
||||||
|
super.onPreExecute();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(String result) {
|
||||||
|
super.onPostExecute(result);
|
||||||
|
|
||||||
|
Log.i(TAG, "onPostExecute: " +result);
|
||||||
|
if (result != null && !result.isEmpty()) {
|
||||||
|
final ForecastItem forecastItem = extractFeatureFromJson(result);
|
||||||
|
|
||||||
|
|
||||||
|
pushNotif(mContext,forecastItem);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,256 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.appttude.h_mal.atlas_weather.MainActivity.changeToInt;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.MainActivity.getImageResource;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.MainActivity.getLocationName;
|
||||||
|
|
||||||
|
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||||
|
|
||||||
|
private Context context;
|
||||||
|
private ForecastItem forecastItem;
|
||||||
|
|
||||||
|
private CurrentForecast currentForecast;
|
||||||
|
private List<Forecast> forecast;
|
||||||
|
private SharedPreferences mSettings;
|
||||||
|
private String location;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ViewHolderCurrent extends RecyclerView.ViewHolder {
|
||||||
|
TextView locationTV;
|
||||||
|
TextView conditionTV;
|
||||||
|
ImageView weatherIV;
|
||||||
|
TextView avgTempTV;
|
||||||
|
TextView feels;
|
||||||
|
TextView tempUnit;
|
||||||
|
|
||||||
|
public ViewHolderCurrent(View listItemView) {
|
||||||
|
super(listItemView);
|
||||||
|
locationTV = listItemView.findViewById(R.id.location_main_4);
|
||||||
|
conditionTV = listItemView.findViewById(R.id.condition_main_4);
|
||||||
|
weatherIV = listItemView.findViewById(R.id.icon_main_4);
|
||||||
|
avgTempTV = listItemView.findViewById(R.id.temp_main_4);
|
||||||
|
// feels = listItemView.findViewById(R.id.feelstemp);
|
||||||
|
tempUnit = listItemView.findViewById(R.id.temp_unit_4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewHolderForecast extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
TextView dateTV;
|
||||||
|
TextView dayTV;
|
||||||
|
TextView conditionTV;
|
||||||
|
ImageView weatherIV;
|
||||||
|
TextView mainTempTV;
|
||||||
|
TextView minorTempTV;
|
||||||
|
|
||||||
|
public ViewHolderForecast(View itemView){
|
||||||
|
super(itemView);
|
||||||
|
dateTV = itemView.findViewById(R.id.list_date);
|
||||||
|
dayTV = itemView.findViewById(R.id.list_day);
|
||||||
|
conditionTV = itemView.findViewById(R.id.list_condition);
|
||||||
|
weatherIV = itemView.findViewById(R.id.list_icon);
|
||||||
|
mainTempTV = itemView.findViewById(R.id.list_main_temp);
|
||||||
|
minorTempTV = itemView.findViewById(R.id.list_minor_temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewHolderFurtherDetails extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
TextView windSpeed;
|
||||||
|
TextView windDirection;
|
||||||
|
TextView precipitation;
|
||||||
|
TextView humidity;
|
||||||
|
TextView clouds;
|
||||||
|
|
||||||
|
|
||||||
|
public ViewHolderFurtherDetails(View itemView){
|
||||||
|
super(itemView);
|
||||||
|
windSpeed = itemView.findViewById(R.id.windspeed);
|
||||||
|
windDirection = itemView.findViewById(R.id.winddirection);
|
||||||
|
precipitation = itemView.findViewById(R.id.precip_);
|
||||||
|
humidity = itemView.findViewById(R.id.humidity_);
|
||||||
|
clouds = itemView.findViewById(R.id.clouds_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public RecyclerViewAdapter(@NonNull Context context, @NonNull ForecastItem forecastItem, Double latitude, Double longitude) {
|
||||||
|
this.context = context;
|
||||||
|
this.forecastItem = forecastItem;
|
||||||
|
this.currentForecast = forecastItem.getCurrentForecast();
|
||||||
|
this.location = getLocationName(context,currentForecast.getLatitude(),currentForecast.getLongitude());
|
||||||
|
|
||||||
|
|
||||||
|
List<Forecast> f = forecastItem.getForecastArrayList();
|
||||||
|
f.remove(0);
|
||||||
|
forecast = f;
|
||||||
|
|
||||||
|
mSettings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RecyclerViewAdapter(@NonNull Context context, @NonNull ForecastItem forecastItem) {
|
||||||
|
this.context = context;
|
||||||
|
this.forecastItem = forecastItem;
|
||||||
|
this.currentForecast = forecastItem.getCurrentForecast();
|
||||||
|
|
||||||
|
List<Forecast> f = forecastItem.getForecastArrayList();
|
||||||
|
f.remove(0);
|
||||||
|
forecast = f;
|
||||||
|
|
||||||
|
mSettings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||||
|
switch (viewType) {
|
||||||
|
case 1:
|
||||||
|
View viewCurrent = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item4, parent, false);
|
||||||
|
return new ViewHolderCurrent(viewCurrent);
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
View viewForecast = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_layout2, parent, false);
|
||||||
|
return new ViewHolderForecast(viewForecast);
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
View viewFurther = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item3, parent, false);
|
||||||
|
return new ViewHolderFurtherDetails(viewFurther);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
|
||||||
|
|
||||||
|
switch (holder.getItemViewType()) {
|
||||||
|
case 1:
|
||||||
|
final ViewHolderCurrent viewHolderCurrent = (ViewHolderCurrent) holder;
|
||||||
|
|
||||||
|
if (location != null) {
|
||||||
|
viewHolderCurrent.locationTV.setText(location);
|
||||||
|
}else{
|
||||||
|
viewHolderCurrent.locationTV.setText(currentForecast.getLocation());
|
||||||
|
}
|
||||||
|
viewHolderCurrent.conditionTV.setText(currentForecast.getCondition_text());
|
||||||
|
|
||||||
|
viewHolderCurrent.weatherIV.setImageResource(getImageResource(currentForecast.getIconURL(),context));
|
||||||
|
|
||||||
|
if (mSettings.getString("temp_units","").equals("°F")){
|
||||||
|
viewHolderCurrent.avgTempTV.setText(changeToInt(currentForecast.getTemp_f()));
|
||||||
|
// viewHolderCurrent.feels.setText(changeToInt(currentForecast.getFeelslike_f()));
|
||||||
|
viewHolderCurrent.tempUnit.setText("°F");
|
||||||
|
}else {
|
||||||
|
viewHolderCurrent.avgTempTV.setText(changeToInt(currentForecast.getTemp_c()));
|
||||||
|
// viewHolderCurrent.feels.setText(changeToInt(currentForecast.getFeelslike_c()));
|
||||||
|
viewHolderCurrent.tempUnit.setText("°C");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
final ViewHolderForecast viewHolderForecast = (ViewHolderForecast) holder;
|
||||||
|
final Forecast f = forecast.get(position -1);
|
||||||
|
|
||||||
|
Date updatedate = new Date(f.getDate_epoch() * 1000);
|
||||||
|
SimpleDateFormat format = new SimpleDateFormat("EEEE");
|
||||||
|
String day = format.format(updatedate);
|
||||||
|
viewHolderForecast.dayTV.setText(day);
|
||||||
|
format = new SimpleDateFormat("d MMM");
|
||||||
|
String date = format.format(updatedate);
|
||||||
|
viewHolderForecast.dateTV.setText(date);
|
||||||
|
|
||||||
|
if(f.getForecast_text().equals("Moderate or heavy rain shower")){
|
||||||
|
viewHolderForecast.conditionTV.setText("Moderate/Heavy Showers");
|
||||||
|
}else{
|
||||||
|
viewHolderForecast.conditionTV.setText(f.getForecast_text());
|
||||||
|
}
|
||||||
|
|
||||||
|
viewHolderForecast.weatherIV.setImageResource(getImageResource(f.getIconURL(), context));
|
||||||
|
|
||||||
|
if (mSettings.getString("temp_units","").equals("°F")){
|
||||||
|
viewHolderForecast.mainTempTV.setText(changeToInt(f.getMaxtemp_f()));
|
||||||
|
viewHolderForecast.minorTempTV.setText(changeToInt(f.getMintemp_f()));
|
||||||
|
}else {
|
||||||
|
viewHolderForecast.mainTempTV.setText(changeToInt(f.getMaxtemp_c()));
|
||||||
|
viewHolderForecast.minorTempTV.setText(changeToInt(f.getMintemp_c()));
|
||||||
|
}
|
||||||
|
|
||||||
|
viewHolderForecast.itemView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
openFurtherInfo(f);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
final ViewHolderFurtherDetails viewHolderFurtherDetails = (ViewHolderFurtherDetails) holder;
|
||||||
|
|
||||||
|
|
||||||
|
if (mSettings.getString("wind_units","").equals("mph")) {
|
||||||
|
viewHolderFurtherDetails.windSpeed.setText(new StringBuilder().append(changeToInt(currentForecast.getWind_mph()))
|
||||||
|
.append(context.getResources().getStringArray(R.array.list_preference_wind_values)[0]));
|
||||||
|
}else{
|
||||||
|
viewHolderFurtherDetails.windSpeed.setText(new StringBuilder().append(changeToInt(currentForecast.getWind_kph()))
|
||||||
|
.append(context.getResources().getStringArray(R.array.list_preference_wind_values)[1]).toString());
|
||||||
|
|
||||||
|
}
|
||||||
|
viewHolderFurtherDetails.windDirection.setText(currentForecast.getWind_dir());
|
||||||
|
viewHolderFurtherDetails.humidity.setText(new StringBuilder().append(changeToInt(currentForecast.getHumidity()))
|
||||||
|
.append("%").toString());
|
||||||
|
|
||||||
|
if (mSettings.getString("precip_units","").equals("in")) {
|
||||||
|
viewHolderFurtherDetails.precipitation.setText(new StringBuilder().append(changeToInt(currentForecast.getPrecip_mm()))
|
||||||
|
.append(context.getResources().getStringArray(R.array.list_preference_precip_values)[1]));
|
||||||
|
}else{
|
||||||
|
viewHolderFurtherDetails.precipitation.setText(new StringBuilder().append(changeToInt(currentForecast.getPrecip_mm()))
|
||||||
|
.append(context.getResources().getStringArray(R.array.list_preference_precip_values)[0]));
|
||||||
|
}
|
||||||
|
viewHolderFurtherDetails.clouds.setText(changeToInt(currentForecast.getCloud()) + "%");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return forecastItem.getForecastArrayList().size() + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
int type = 0;
|
||||||
|
if (position == 0){
|
||||||
|
type = 1;
|
||||||
|
}else if (position >= 1 && position < getItemCount() -1){
|
||||||
|
type = 2;
|
||||||
|
}else if (position == getItemCount() -1){
|
||||||
|
type = 3;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openFurtherInfo(Forecast forcast){
|
||||||
|
Intent i = new Intent(context,FurtherInfoActivity.class);
|
||||||
|
i.putExtra("currentForcast",forcast);
|
||||||
|
context.startActivity(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,223 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.appttude.h_mal.atlas_weather.Fragment_home.APIkey;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.getLatLong.latitude;
|
||||||
|
import static com.appttude.h_mal.atlas_weather.getLatLong.longitude;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by h_mal on 05/05/2018.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class RetrieveJSON {
|
||||||
|
|
||||||
|
public RetrieveJSON(){}
|
||||||
|
|
||||||
|
public static String UriBuilder(int days){
|
||||||
|
|
||||||
|
String latLong = latitude + "," + longitude;
|
||||||
|
|
||||||
|
Uri.Builder builder = new Uri.Builder();
|
||||||
|
builder.scheme("http")
|
||||||
|
.authority("api.apixu.com")
|
||||||
|
.appendPath("v1")
|
||||||
|
.appendPath("forecast.json")
|
||||||
|
.appendQueryParameter("key",APIkey)
|
||||||
|
.appendQueryParameter("q",latLong)
|
||||||
|
.appendQueryParameter("days",days+"");
|
||||||
|
|
||||||
|
return builder.build().toString().replace("%2C",",");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static String UriBuilder(String q){
|
||||||
|
|
||||||
|
Uri.Builder builder = new Uri.Builder();
|
||||||
|
builder.scheme("http")
|
||||||
|
.authority("api.apixu.com")
|
||||||
|
.appendPath("v1")
|
||||||
|
.appendPath("forecast.json")
|
||||||
|
.appendQueryParameter("key",APIkey)
|
||||||
|
.appendQueryParameter("q",q)
|
||||||
|
.appendQueryParameter("days","7");
|
||||||
|
|
||||||
|
return builder.build().toString().replace("%2C",",");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static URL createUrl(String stringUrl) {
|
||||||
|
URL url = null;
|
||||||
|
try {
|
||||||
|
url = new URL(stringUrl);
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
Log.e("ERROR", "Error with creating URL ", e);
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String makeHttpRequest(URL url) throws IOException {
|
||||||
|
String jsonResponse = null;
|
||||||
|
|
||||||
|
if (url == null) {
|
||||||
|
return jsonResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpURLConnection urlConnection = null;
|
||||||
|
InputStream inputStream = null;
|
||||||
|
try {
|
||||||
|
urlConnection = (HttpURLConnection) url.openConnection();
|
||||||
|
urlConnection.setReadTimeout(30000);
|
||||||
|
urlConnection.setConnectTimeout(30000);
|
||||||
|
urlConnection.setRequestMethod("GET");
|
||||||
|
urlConnection.connect();
|
||||||
|
|
||||||
|
if (urlConnection.getResponseCode() == 200) {
|
||||||
|
inputStream = urlConnection.getInputStream();
|
||||||
|
jsonResponse = readFromStream(inputStream);
|
||||||
|
} else {
|
||||||
|
Log.e("", "Error response code: " + urlConnection.getResponseCode());
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("", "Problem retrieving the JSON results.", e);
|
||||||
|
} finally {
|
||||||
|
if (urlConnection != null) {
|
||||||
|
urlConnection.disconnect();
|
||||||
|
}
|
||||||
|
if (inputStream != null) {
|
||||||
|
inputStream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String readFromStream(InputStream inputStream) throws IOException {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
if (inputStream != null) {
|
||||||
|
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
|
||||||
|
BufferedReader reader = new BufferedReader(inputStreamReader);
|
||||||
|
String line = "";
|
||||||
|
while (line != null) {
|
||||||
|
output.append(line);
|
||||||
|
line = reader.readLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.d("", output.toString());
|
||||||
|
return output.toString();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ForecastItem extractFeatureFromJson(String newsJSON) {
|
||||||
|
|
||||||
|
if (TextUtils.isEmpty(newsJSON)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentForecast forecastCurrent = new CurrentForecast();
|
||||||
|
List<Forecast> forecasts = new ArrayList<Forecast>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject baseJsonResponse = new JSONObject(newsJSON);
|
||||||
|
JSONObject locationObject = baseJsonResponse.getJSONObject("location");
|
||||||
|
Double latitude = locationObject.getDouble("lat");
|
||||||
|
Double longitude = locationObject.getDouble("lon");
|
||||||
|
String location = locationObject.getString("name");
|
||||||
|
int last_updated_epoch = locationObject.getInt("localtime_epoch");
|
||||||
|
|
||||||
|
JSONObject currentObject = baseJsonResponse.getJSONObject("current");
|
||||||
|
Double temp_c = currentObject.getDouble("temp_c");
|
||||||
|
Double temp_f = currentObject.getDouble("temp_f");
|
||||||
|
|
||||||
|
JSONObject conditionObject = currentObject.getJSONObject("condition");
|
||||||
|
String condition_text = conditionObject.getString("text");
|
||||||
|
String iconURL = conditionObject.getString("icon");
|
||||||
|
|
||||||
|
Double wind_mph = currentObject.getDouble("wind_mph");
|
||||||
|
Double wind_kph = currentObject.getDouble("wind_kph");
|
||||||
|
String wind_dir = currentObject.getString("wind_dir");
|
||||||
|
Double pressure_mb = currentObject.getDouble("pressure_mb");
|
||||||
|
Double pressure_in = currentObject.getDouble("pressure_in");
|
||||||
|
Double precip_mm = currentObject.getDouble("precip_mm");
|
||||||
|
Double precip_in = currentObject.getDouble("precip_in");
|
||||||
|
Double humidity = currentObject.getDouble("humidity");
|
||||||
|
Double cloud = currentObject.getDouble("cloud");
|
||||||
|
Double feelslike_c = currentObject.getDouble("feelslike_c");
|
||||||
|
Double feelslike_f = currentObject.getDouble("feelslike_f");
|
||||||
|
Double vis_km = currentObject.getDouble("vis_km");
|
||||||
|
Double vis_miles = currentObject.getDouble("vis_miles");
|
||||||
|
|
||||||
|
forecastCurrent = new CurrentForecast(location, latitude, longitude,
|
||||||
|
last_updated_epoch, temp_c, temp_f, condition_text,
|
||||||
|
iconURL, wind_mph, wind_kph, wind_dir,
|
||||||
|
pressure_mb, pressure_in, precip_mm, precip_in,
|
||||||
|
humidity, cloud, feelslike_c, feelslike_f,
|
||||||
|
vis_km, vis_miles
|
||||||
|
);
|
||||||
|
|
||||||
|
JSONObject forecastObject = baseJsonResponse.getJSONObject("forecast");
|
||||||
|
JSONArray forecastsArray = forecastObject.getJSONArray("forecastday");
|
||||||
|
|
||||||
|
for (int i = 0; i < forecastsArray.length(); i++) {
|
||||||
|
JSONObject currentForecastObject = forecastsArray.getJSONObject(i);
|
||||||
|
Long date = currentForecastObject.getLong("date_epoch");
|
||||||
|
|
||||||
|
JSONObject day = currentForecastObject.getJSONObject("day");
|
||||||
|
Double maxtemp_c = day.getDouble ("maxtemp_c");
|
||||||
|
Double maxtemp_f = day.getDouble ("maxtemp_f");
|
||||||
|
Double mintemp_c = day.getDouble ("mintemp_c");
|
||||||
|
Double mintemp_f = day.getDouble ("mintemp_f");
|
||||||
|
Double avgtemp_c = day.getDouble ("avgtemp_c");
|
||||||
|
Double avgtemp_f = day.getDouble ("avgtemp_f");
|
||||||
|
Double maxwind_mph = day.getDouble ("maxwind_mph");
|
||||||
|
Double maxwind_kph = day.getDouble ("maxwind_kph");
|
||||||
|
Double totalprecip_mm = day.getDouble ("totalprecip_mm");
|
||||||
|
Double totalprecip_in = day.getDouble ("totalprecip_in");
|
||||||
|
Double avgvis_km = day.getDouble ("avgvis_km");
|
||||||
|
Double avgvis_miles = day.getDouble ("avgvis_miles");
|
||||||
|
Double avghumidity = day.getDouble ("avghumidity");
|
||||||
|
Double uv = day.getDouble("uv");
|
||||||
|
|
||||||
|
JSONObject condition = day.getJSONObject("condition");
|
||||||
|
String conditionText = condition.getString("text");
|
||||||
|
String imageURL = condition.getString("icon");
|
||||||
|
|
||||||
|
JSONObject astro = currentForecastObject.getJSONObject("astro");
|
||||||
|
String sunrise = astro.getString("sunrise");
|
||||||
|
String sunset = astro.getString("sunset");
|
||||||
|
String moonrise = astro.getString("moonrise");
|
||||||
|
String moonset = astro.getString("moonset");
|
||||||
|
|
||||||
|
Forecast forecast = new Forecast(date, maxtemp_c, maxtemp_f, mintemp_c, mintemp_f, avgtemp_c, avgtemp_f,
|
||||||
|
maxwind_mph, maxwind_kph, totalprecip_mm, totalprecip_in, avgvis_km, avgvis_miles,
|
||||||
|
avghumidity, conditionText, imageURL, uv, sunrise, sunset, moonrise, moonset)
|
||||||
|
;
|
||||||
|
|
||||||
|
forecasts.add(forecast);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e("Error", "Problem parsing the book JSON results", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ForecastItem(forecastCurrent,forecasts);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.appwidget.AppWidgetManager;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.preference.PreferenceActivity;
|
||||||
|
import android.preference.PreferenceFragment;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.appttude.h_mal.atlas_weather.AppWidget.NewAppWidget;
|
||||||
|
|
||||||
|
import static com.appttude.h_mal.atlas_weather.MainActivity.setupNotificationBroadcaster;
|
||||||
|
|
||||||
|
public class UnitSettings extends PreferenceActivity {
|
||||||
|
|
||||||
|
private String TAG = getClass().getSimpleName();
|
||||||
|
private SharedPreferences.OnSharedPreferenceChangeListener prefListener;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
PreferenceManager.setDefaultValues(this, R.xml.prefs, false);
|
||||||
|
getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit();
|
||||||
|
|
||||||
|
//listener on changed sort order preference:
|
||||||
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
||||||
|
|
||||||
|
prefListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
|
||||||
|
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
|
||||||
|
|
||||||
|
if(key.equals("temp_units")){
|
||||||
|
Intent intent = new Intent(getBaseContext(), NewAppWidget.class);
|
||||||
|
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
|
||||||
|
|
||||||
|
int[] ids = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), NewAppWidget.class));
|
||||||
|
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
|
||||||
|
sendBroadcast(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(key.equals("notif_boolean")){
|
||||||
|
setupNotificationBroadcaster(getBaseContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
prefs.registerOnSharedPreferenceChangeListener(prefListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
super.onBackPressed();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
|
||||||
|
// Log.i(TAG, "onSharedPreferenceChanged: " + s);
|
||||||
|
// if (s == "temp_units"){
|
||||||
|
// Intent intent = new Intent(getBaseContext(), NewAppWidget.class);
|
||||||
|
// intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
|
||||||
|
//
|
||||||
|
// int[] ids = AppWidgetManager.getInstance(getApplication()).getAppWidgetIds(new ComponentName(getApplication(), NewAppWidget.class));
|
||||||
|
// intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
|
||||||
|
// sendBroadcast(intent);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
public static class MyPreferenceFragment extends PreferenceFragment
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onCreate(final Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
addPreferencesFromResource(R.xml.prefs);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.support.v4.widget.SwipeRefreshLayout;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.appttude.h_mal.atlas_weather.RetrieveJSON.UriBuilder;
|
||||||
|
|
||||||
|
public class WorldItemActivity extends AppCompatActivity
|
||||||
|
implements android.support.v4.app.LoaderManager.LoaderCallbacks<List<ForecastItem>> {
|
||||||
|
|
||||||
|
private static final int NEWS_LOADER_ID = 1;
|
||||||
|
|
||||||
|
RecyclerView forecastsListView;
|
||||||
|
LinearLayout emptyList;
|
||||||
|
ProgressBar mainPG;
|
||||||
|
SwipeRefreshLayout mSwipeRefreshLayout;
|
||||||
|
|
||||||
|
private RecyclerViewAdapter mAdapter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.fragment_main);
|
||||||
|
|
||||||
|
Intent mIntent = getIntent();
|
||||||
|
ForecastItem forecast = mIntent.getParcelableExtra("ForecastItem");
|
||||||
|
|
||||||
|
forecastsListView = findViewById(R.id.forecast_listview);
|
||||||
|
forecastsListView.setLayoutManager(new LinearLayoutManager(this));
|
||||||
|
emptyList = findViewById(R.id.emptyView);
|
||||||
|
mainPG = findViewById(R.id.mainPB);
|
||||||
|
|
||||||
|
emptyList.setVisibility(View.GONE);
|
||||||
|
mainPG.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
mAdapter = new RecyclerViewAdapter(this,forecast);
|
||||||
|
forecastsListView.setAdapter(mAdapter);
|
||||||
|
|
||||||
|
mSwipeRefreshLayout = findViewById(R.id.swipe_refresh);
|
||||||
|
mSwipeRefreshLayout.setRefreshing(false);
|
||||||
|
|
||||||
|
// if (networkInfo != null && networkInfo.isConnected()) {
|
||||||
|
// android.support.v4.app.LoaderManager loaderManager = getSupportLoaderManager();
|
||||||
|
// loaderManager.initLoader(NEWS_LOADER_ID, null, this);
|
||||||
|
// } else {
|
||||||
|
// emptyList.setVisibility(View.VISIBLE);
|
||||||
|
// mainPG.setVisibility(View.GONE);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public android.support.v4.content.Loader<List<ForecastItem>> onCreateLoader(int id, Bundle args) {
|
||||||
|
// URL url = createUrl(UriBuilder());
|
||||||
|
// ArrayList<String> entries = new ArrayList<>();
|
||||||
|
// entries.add(url.toString());
|
||||||
|
// return new ForecastLoader(this,entries);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoadFinished(android.support.v4.content.Loader<List<ForecastItem>> loader, List<ForecastItem> data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoaderReset(android.support.v4.content.Loader<List<ForecastItem>> loader) {
|
||||||
|
// loader.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather.dbfiles;
|
||||||
|
|
||||||
|
import android.content.ContentResolver;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.provider.BaseColumns;
|
||||||
|
|
||||||
|
public class ForecastContract {
|
||||||
|
|
||||||
|
public ForecastContract() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String CONTENT_AUTHORITY = "com.appttude.h_mal.atlas_weather";
|
||||||
|
|
||||||
|
public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
|
||||||
|
|
||||||
|
public static final String PATH_FORECASTS = "forecasts";
|
||||||
|
public static final String PATH_FORECASTS_WIDGET = "widgetitems";
|
||||||
|
|
||||||
|
public static final class ForecastEntry implements BaseColumns {
|
||||||
|
|
||||||
|
public static final Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, PATH_FORECASTS);
|
||||||
|
|
||||||
|
public static final Uri CONTENT_URI_WIDGET = Uri.withAppendedPath(BASE_CONTENT_URI, PATH_FORECASTS_WIDGET);
|
||||||
|
|
||||||
|
|
||||||
|
public static final String CONTENT_LIST_TYPE =
|
||||||
|
ContentResolver.CURSOR_DIR_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_FORECASTS;
|
||||||
|
|
||||||
|
|
||||||
|
public static final String CONTENT_ITEM_TYPE =
|
||||||
|
ContentResolver.CURSOR_ITEM_BASE_TYPE + "/" + CONTENT_AUTHORITY + "/" + PATH_FORECASTS;
|
||||||
|
|
||||||
|
|
||||||
|
public final static String TABLE_NAME = "forecasts";
|
||||||
|
|
||||||
|
public final static String TABLE_NAME_WIDGET = "widgetitems";
|
||||||
|
|
||||||
|
public final static String _ID = BaseColumns._ID;
|
||||||
|
|
||||||
|
public final static String COLUMN_FORECAST_NAME = "name";
|
||||||
|
|
||||||
|
public final static String COLUMN_WIDGET_FORECAST_ITEM = "widgetforcastitem";
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather.dbfiles;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
|
|
||||||
|
import com.appttude.h_mal.atlas_weather.dbfiles.ForecastContract.ForecastEntry;
|
||||||
|
|
||||||
|
public class ForecastDBHelper extends SQLiteOpenHelper {
|
||||||
|
|
||||||
|
public static final String name = "forecasts.db";
|
||||||
|
public static final int version = 1;
|
||||||
|
|
||||||
|
public ForecastDBHelper(Context context) {
|
||||||
|
super(context, name, null, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(SQLiteDatabase sqLiteDatabase) {
|
||||||
|
String SQL_CREATE_PRODUCTS_TABLE = "CREATE TABLE " + ForecastEntry.TABLE_NAME + " ("
|
||||||
|
+ ForecastEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||||
|
+ ForecastEntry.COLUMN_FORECAST_NAME + " TEXT NOT NULL)";
|
||||||
|
|
||||||
|
sqLiteDatabase.execSQL(SQL_CREATE_PRODUCTS_TABLE);
|
||||||
|
sqLiteDatabase.execSQL(SQL_CREATE_PRODUCTS_TABLE_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String SQL_CREATE_PRODUCTS_TABLE_2 = "CREATE TABLE " + ForecastEntry.TABLE_NAME_WIDGET + " ("
|
||||||
|
+ ForecastEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||||
|
+ ForecastEntry.COLUMN_FORECAST_NAME + " TEXT NOT NULL, "
|
||||||
|
+ ForecastEntry.COLUMN_WIDGET_FORECAST_ITEM + " TEXT)";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,178 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather.dbfiles;
|
||||||
|
|
||||||
|
import android.content.ContentProvider;
|
||||||
|
import android.content.ContentUris;
|
||||||
|
import android.content.ContentValues;
|
||||||
|
import android.content.UriMatcher;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.appttude.h_mal.atlas_weather.dbfiles.ForecastContract.ForecastEntry;
|
||||||
|
|
||||||
|
public class ForecastProvider extends ContentProvider {
|
||||||
|
|
||||||
|
public static final String LOG_TAG = ForecastProvider.class.getSimpleName();
|
||||||
|
|
||||||
|
private static final int FORECASTS = 100;
|
||||||
|
private static final int FORECAST_ID = 101;
|
||||||
|
|
||||||
|
private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
|
||||||
|
|
||||||
|
static {
|
||||||
|
|
||||||
|
sUriMatcher.addURI(ForecastContract.CONTENT_AUTHORITY, ForecastContract.PATH_FORECASTS, FORECASTS);
|
||||||
|
|
||||||
|
sUriMatcher.addURI(ForecastContract.CONTENT_AUTHORITY, ForecastContract.PATH_FORECASTS + "/#", FORECAST_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
ForecastDBHelper mDbHelper;
|
||||||
|
private SQLiteDatabase database;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCreate() {
|
||||||
|
mDbHelper = new ForecastDBHelper(getContext());
|
||||||
|
database = mDbHelper.getReadableDatabase();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Cursor query(Uri uri, String[] projection, String selection,
|
||||||
|
String[] selectionArgs, String sortOrder) {
|
||||||
|
|
||||||
|
Cursor cursor;
|
||||||
|
|
||||||
|
int match = sUriMatcher.match(uri);
|
||||||
|
switch (match) {
|
||||||
|
case FORECASTS:
|
||||||
|
|
||||||
|
cursor = database.query(ForecastEntry.TABLE_NAME, projection, selection, selectionArgs,
|
||||||
|
null, null, sortOrder);
|
||||||
|
break;
|
||||||
|
case FORECAST_ID:
|
||||||
|
|
||||||
|
selection = ForecastEntry._ID + "=?";
|
||||||
|
selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };
|
||||||
|
cursor = database.query(ForecastEntry.TABLE_NAME, projection, selection, selectionArgs,
|
||||||
|
null, null, sortOrder);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Cannot query " + uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor.setNotificationUri(getContext().getContentResolver(), uri);
|
||||||
|
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getType(@NonNull Uri uri) {
|
||||||
|
final int match = sUriMatcher.match(uri);
|
||||||
|
switch (match) {
|
||||||
|
case FORECASTS:
|
||||||
|
return ForecastEntry.CONTENT_LIST_TYPE;
|
||||||
|
case FORECAST_ID:
|
||||||
|
return ForecastEntry.CONTENT_ITEM_TYPE;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Unknown URI " + uri + " with match " + match);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
|
||||||
|
|
||||||
|
final int match = sUriMatcher.match(uri);
|
||||||
|
switch (match) {
|
||||||
|
case FORECASTS:
|
||||||
|
String name = values.getAsString(ForecastEntry.COLUMN_FORECAST_NAME);
|
||||||
|
if (name == null) {
|
||||||
|
throw new IllegalArgumentException("name required");
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLiteDatabase database = mDbHelper.getWritableDatabase();
|
||||||
|
|
||||||
|
long id = database.insert(ForecastEntry.TABLE_NAME, null, values);
|
||||||
|
if (id == -1) {
|
||||||
|
Log.e(LOG_TAG, "row failed " + uri);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
getContext().getContentResolver().notifyChange(uri, null);
|
||||||
|
return ContentUris.withAppendedId(uri, id);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Insertion is not supported for " + uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
|
||||||
|
SQLiteDatabase database = mDbHelper.getWritableDatabase();
|
||||||
|
|
||||||
|
int rowsDeleted;
|
||||||
|
|
||||||
|
final int match = sUriMatcher.match(uri);
|
||||||
|
switch (match) {
|
||||||
|
case FORECASTS:
|
||||||
|
rowsDeleted = database.delete(ForecastEntry.TABLE_NAME, selection, selectionArgs);
|
||||||
|
break;
|
||||||
|
case FORECAST_ID:
|
||||||
|
selection = ForecastEntry._ID + "=?";
|
||||||
|
selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };
|
||||||
|
rowsDeleted = database.delete(ForecastEntry.TABLE_NAME, selection, selectionArgs);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Deletion is not supported for " + uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rowsDeleted != 0) {
|
||||||
|
getContext().getContentResolver().notifyChange(uri, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rowsDeleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String selection, @Nullable String[] selectionArgs) {
|
||||||
|
final int match = sUriMatcher.match(uri);
|
||||||
|
switch (match) {
|
||||||
|
case FORECASTS:
|
||||||
|
return updateProduct(uri, contentValues, selection, selectionArgs);
|
||||||
|
case FORECAST_ID:
|
||||||
|
|
||||||
|
selection = ForecastEntry._ID + "=?";
|
||||||
|
selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };
|
||||||
|
return updateProduct(uri, contentValues, selection, selectionArgs);
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Update is not supported for " + uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int updateProduct(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
|
||||||
|
|
||||||
|
if (values.containsKey(ForecastEntry.COLUMN_FORECAST_NAME)) {
|
||||||
|
String name = values.getAsString(ForecastEntry.COLUMN_FORECAST_NAME);
|
||||||
|
if (name == null) {
|
||||||
|
throw new IllegalArgumentException("Name required");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (values.size() == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SQLiteDatabase database = mDbHelper.getWritableDatabase();
|
||||||
|
int rowsUpdated = database.update(ForecastEntry.TABLE_NAME, values, selection, selectionArgs);
|
||||||
|
if (rowsUpdated != 0) {
|
||||||
|
getContext().getContentResolver().notifyChange(uri, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rowsUpdated;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.location.Location;
|
||||||
|
import android.location.LocationManager;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.google.android.gms.location.FusedLocationProviderClient;
|
||||||
|
import com.google.android.gms.location.LocationServices;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by h_mal on 05/05/2018.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class getLatLong{
|
||||||
|
static Location location;
|
||||||
|
public static Double longitude;
|
||||||
|
public static Double latitude;
|
||||||
|
|
||||||
|
private static String TAG = getLatLong.class.getSimpleName();
|
||||||
|
|
||||||
|
public getLatLong(){
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void configLatLong(Context context) {
|
||||||
|
|
||||||
|
LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
||||||
|
FusedLocationProviderClient mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context);
|
||||||
|
if(ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
|
||||||
|
!=PackageManager.PERMISSION_GRANTED) {
|
||||||
|
Toast.makeText(context, "Location permission denied", Toast.LENGTH_SHORT).show();
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
|
||||||
|
}catch (Exception e){
|
||||||
|
Log.e("latlong error", "configLatLong: ", e);
|
||||||
|
}finally {
|
||||||
|
if (location == null){
|
||||||
|
Log.i(TAG, "configLatLong: location initially was null");
|
||||||
|
try{
|
||||||
|
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
||||||
|
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
|
||||||
|
}catch (Exception e){
|
||||||
|
Log.e(TAG, "configLatLong: ", e);
|
||||||
|
}finally {
|
||||||
|
if (location != null){
|
||||||
|
latitude = location.getLatitude();
|
||||||
|
longitude = location.getLongitude();
|
||||||
|
|
||||||
|
Log.i(TAG, "onSuccess: Latitude:" + location.getLatitude()
|
||||||
|
+ "\n longitude: " + location.getLongitude());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
latitude = location.getLatitude();
|
||||||
|
longitude = location.getLongitude();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class infopageItem {
|
||||||
|
|
||||||
|
private int icon;
|
||||||
|
private String firstLine;
|
||||||
|
private String authorUrl;
|
||||||
|
private String authorName;
|
||||||
|
private String siteUrl;
|
||||||
|
private String siteName;
|
||||||
|
|
||||||
|
public infopageItem(int icon, @Nullable String firstLine, @Nullable String authorUrl, @Nullable String authorName,
|
||||||
|
@Nullable String siteUrl, @Nullable String siteName) {
|
||||||
|
this.icon = icon;
|
||||||
|
this.firstLine = firstLine;
|
||||||
|
this.authorUrl = authorUrl;
|
||||||
|
this.authorName = authorName;
|
||||||
|
this.siteUrl = siteUrl;
|
||||||
|
this.siteName = siteName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInfoIcon() {
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstLine() {
|
||||||
|
return firstLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthorUrl() {
|
||||||
|
return authorUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthorName() {
|
||||||
|
return authorName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSiteUrl() {
|
||||||
|
return siteUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSiteName() {
|
||||||
|
return siteName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class infoPageAdapter extends ArrayAdapter<infopageItem>{
|
||||||
|
|
||||||
|
public infoPageAdapter(@NonNull Context context, @NonNull List<infopageItem> objects) {
|
||||||
|
super(context, 0, objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
|
||||||
|
View listItemView = convertView;
|
||||||
|
|
||||||
|
if (listItemView == null) {
|
||||||
|
listItemView = LayoutInflater.from(getContext()).inflate(R.layout.info_dialog_item, parent,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
infopageItem inf = getItem(position);
|
||||||
|
|
||||||
|
ImageView imageView = listItemView.findViewById(R.id.infopage_icon);
|
||||||
|
TextView firstLineTextView = listItemView.findViewById(R.id.first_part_text);
|
||||||
|
TextView authorLinkTextView = listItemView.findViewById(R.id.author_link);
|
||||||
|
TextView thirdLine = listItemView.findViewById(R.id.third_text);
|
||||||
|
TextView companyWebsiteTextView = listItemView.findViewById(R.id.company_website);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(position == 0){
|
||||||
|
imageView.setImageResource(inf.getInfoIcon());
|
||||||
|
firstLineTextView.setText(inf.getFirstLine());
|
||||||
|
authorLinkTextView.setVisibility(View.GONE);
|
||||||
|
thirdLine.setText("");
|
||||||
|
SetUrlHyperlink(companyWebsiteTextView,inf.getSiteName(),inf.getSiteUrl());
|
||||||
|
}else{
|
||||||
|
imageView.setImageResource(inf.getInfoIcon());
|
||||||
|
firstLineTextView.setText(inf.getFirstLine());
|
||||||
|
authorLinkTextView.setVisibility(View.VISIBLE);
|
||||||
|
thirdLine.setText("From ");
|
||||||
|
SetUrlHyperlink(authorLinkTextView,inf.getAuthorName(), inf.getAuthorUrl());
|
||||||
|
SetUrlHyperlink(companyWebsiteTextView,"www.flaticon.com ","www.flaticon.com" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return listItemView;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetUrlHyperlink(TextView textView, String textString, final String url){
|
||||||
|
textView.setText(textString);
|
||||||
|
textView.setTextColor(getContext().getColor(android.R.color.holo_blue_dark));
|
||||||
|
textView.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||||
|
getContext().startActivity(myIntent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
app/src/main/res/drawable-nodpi/example_appwidget_preview.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
app/src/main/res/drawable-v24/calendar.png
Normal file
|
After Width: | Height: | Size: 762 B |
10
app/src/main/res/drawable-v24/gradient.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<gradient
|
||||||
|
android:startColor="@color/colour_two"
|
||||||
|
android:centerColor="@color/colour_three"
|
||||||
|
android:endColor="@color/colour_four"
|
||||||
|
android:type="linear"
|
||||||
|
android:angle="45"/>
|
||||||
|
</shape>
|
||||||
34
app/src/main/res/drawable-v24/ic_launcher_foreground.xml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportHeight="108"
|
||||||
|
android:viewportWidth="108">
|
||||||
|
<path
|
||||||
|
android:fillType="evenOdd"
|
||||||
|
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
||||||
|
android:strokeColor="#00000000"
|
||||||
|
android:strokeWidth="1">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:endX="78.5885"
|
||||||
|
android:endY="90.9159"
|
||||||
|
android:startX="48.7653"
|
||||||
|
android:startY="61.0927"
|
||||||
|
android:type="linear">
|
||||||
|
<item
|
||||||
|
android:color="#44000000"
|
||||||
|
android:offset="0.0" />
|
||||||
|
<item
|
||||||
|
android:color="#00000000"
|
||||||
|
android:offset="1.0" />
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
||||||
|
android:strokeColor="#00000000"
|
||||||
|
android:strokeWidth="1" />
|
||||||
|
</vector>
|
||||||
BIN
app/src/main/res/drawable-v24/info.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/drawable/breeze.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
24
app/src/main/res/drawable/button_layout.xml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
<item android:state_pressed="true" >
|
||||||
|
<shape android:shape="rectangle" >
|
||||||
|
<corners android:radius="@dimen/button_radius" />
|
||||||
|
<stroke android:width="@dimen/button_outline" android:color="#5e7974" />
|
||||||
|
<solid android:color="@color/colour_one"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item android:state_focused="true">
|
||||||
|
<shape android:shape="rectangle" >
|
||||||
|
<corners android:radius="@dimen/button_radius" />
|
||||||
|
<stroke android:width="@dimen/button_outline" android:color="#5e7974" />
|
||||||
|
<solid android:color="#58857e"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item >
|
||||||
|
<shape android:shape="rectangle" >
|
||||||
|
<corners android:radius="@dimen/button_radius" />
|
||||||
|
<stroke android:width="@dimen/button_outline" android:color="#5e7974" />
|
||||||
|
<solid android:color="@color/colour_one"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
BIN
app/src/main/res/drawable/calendar.png
Normal file
|
After Width: | Height: | Size: 762 B |
BIN
app/src/main/res/drawable/cloud_symbol.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
app/src/main/res/drawable/day_113.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/drawable/day_116.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
app/src/main/res/drawable/day_119.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/drawable/day_122.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
app/src/main/res/drawable/day_143.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/drawable/day_176.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
app/src/main/res/drawable/day_179.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/drawable/day_182.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/drawable/day_185.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/drawable/day_200.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/drawable/day_227.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/drawable/day_230.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/drawable/day_248.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/drawable/day_260.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/main/res/drawable/day_263.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/drawable/day_266.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/drawable/day_281.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/drawable/day_284.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/drawable/day_293.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
app/src/main/res/drawable/day_296.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/drawable/day_299.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
app/src/main/res/drawable/day_302.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/drawable/day_305.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
app/src/main/res/drawable/day_308.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/drawable/day_311.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/main/res/drawable/day_314.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/main/res/drawable/day_317.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/drawable/day_320.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/drawable/day_323.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/drawable/day_326.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/main/res/drawable/day_329.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/drawable/day_332.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/main/res/drawable/day_335.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/drawable/day_338.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/main/res/drawable/day_350.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/drawable/day_353.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
app/src/main/res/drawable/day_356.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
app/src/main/res/drawable/day_359.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
app/src/main/res/drawable/day_362.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/drawable/day_365.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
app/src/main/res/drawable/day_368.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/drawable/day_371.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/drawable/day_374.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
app/src/main/res/drawable/day_377.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
app/src/main/res/drawable/day_386.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/drawable/day_389.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
app/src/main/res/drawable/day_392.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
app/src/main/res/drawable/day_395.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |