First Commit
9
.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
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>
|
89
.idea/misc.xml
generated
Normal file
@ -0,0 +1,89 @@
|
||||
<?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="4">
|
||||
<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="edu.umd.cs.findbugs.annotations.Nullable" />
|
||||
<item index="3" 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="ProjectInspectionProfilesVisibleTreeState">
|
||||
<entry key="Project Default">
|
||||
<profile-state>
|
||||
<expanded-state>
|
||||
<State>
|
||||
<id />
|
||||
</State>
|
||||
<State>
|
||||
<id>Android > Lint > Correctness</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Android > Lint > Performance</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Class structureJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Cloning issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Groovy</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Inheritance issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Internationalization issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Java</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Numeric issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Performance issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Potentially confusing code constructsGroovy</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Probable bugsJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Security issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Serialization issuesJava</id>
|
||||
</State>
|
||||
<State>
|
||||
<id>Threading issuesJava</id>
|
||||
</State>
|
||||
</expanded-state>
|
||||
</profile-state>
|
||||
</entry>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" 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$/another-widget.iml" filepath="$PROJECT_DIR$/another-widget.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>
|
1
app/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/build
|
41
app/build.gradle
Normal file
@ -0,0 +1,41 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
|
||||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
android {
|
||||
compileSdkVersion 26
|
||||
buildToolsVersion "26.0.2"
|
||||
defaultConfig {
|
||||
applicationId "com.tommasoberlose.anotherwidget"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 26
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
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.constraint:constraint-layout:1.0.2'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation('com.android.support.test.espresso:espresso-core:3.0.1', {
|
||||
exclude group: 'com.android.support', module: 'support-annotations'
|
||||
})
|
||||
implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
|
||||
compile 'com.survivingwithandroid:weatherlib:1.6.0'
|
||||
compile 'com.survivingwithandroid:weatherlib_volleyclient:1.6.0'
|
||||
compile 'com.mcxiaoke.volley:library:1.0.6@aar'
|
||||
compile 'com.android.support:customtabs: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
|
@ -0,0 +1,24 @@
|
||||
package com.tommasoberlose.anotherwidget
|
||||
|
||||
import android.support.test.InstrumentationRegistry
|
||||
import android.support.test.runner.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getTargetContext()
|
||||
assertEquals("com.tommasoberlose.anotherwidget", appContext.packageName)
|
||||
}
|
||||
}
|
65
app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.tommasoberlose.anotherwidget">
|
||||
|
||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".ui.activity.MainActivity"
|
||||
android:launchMode="singleInstance">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<receiver android:name=".ui.widget.TheWidget">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/the_widget_info" />
|
||||
</receiver>
|
||||
<receiver
|
||||
android:name=".util.NewCalendarEventReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.PROVIDER_CHANGED" />
|
||||
|
||||
<data android:scheme="content" />
|
||||
<data android:host="com.android.calendar" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver
|
||||
android:name=".util.UpdatesReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver
|
||||
android:name=".util.WeatherReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</application>
|
||||
|
||||
</manifest>
|
BIN
app/src/main/ic_launcher-web.png
Normal file
After Width: | Height: | Size: 45 KiB |
@ -0,0 +1,22 @@
|
||||
package com.tommasoberlose.anotherwidget.`object`
|
||||
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by tommaso on 05/10/17.
|
||||
*/
|
||||
|
||||
object Constants {
|
||||
val CALENDAR_REQUEST_CODE = 1
|
||||
val LOCATION_REQUEST_CODE = 2
|
||||
|
||||
val PREF_WEATHER_ICON = "PREF_WEATHER_ICON"
|
||||
val PREF_WEATHER_TEMP = "PREF_WEATHER_TEMP"
|
||||
|
||||
val dateFormat = SimpleDateFormat("EEEE, MMM d", Locale.getDefault())
|
||||
val hourFormat = SimpleDateFormat("HH:mm", Locale.getDefault())
|
||||
|
||||
val ACTION_TIME_UPDATE = "com.tommasoberlose.anotherwidget.action.ACTION_TIME_UPDATE"
|
||||
val ACTION_WEATHER_UPDATE = "com.tommasoberlose.anotherwidget.action.ACTION_WEATHER_UPDATE"
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.tommasoberlose.anotherwidget.`object`
|
||||
|
||||
import android.database.Cursor
|
||||
|
||||
import java.util.Date
|
||||
|
||||
/**
|
||||
* Created by tommaso on 05/10/17.
|
||||
*/
|
||||
|
||||
class Event(eventCursor: Cursor, instanceCursor: Cursor) {
|
||||
var id: Int = 0
|
||||
var title: String? = null
|
||||
var startDate: Long = 0
|
||||
var endDate: Long = 0
|
||||
|
||||
init {
|
||||
id = instanceCursor.getInt(0)
|
||||
startDate = instanceCursor.getLong(1)
|
||||
endDate = instanceCursor.getLong(2)
|
||||
|
||||
title = eventCursor.getString(0)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "Event:\nID" + id + "\nTITLE: " + title + "\nSTART DATE: " + Date(startDate) + "\nEND DATE: " + Date(endDate)
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.activity
|
||||
|
||||
import android.Manifest
|
||||
import android.content.pm.PackageManager
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.support.v4.app.ActivityCompat
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.Intent
|
||||
import android.content.ComponentName
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import com.tommasoberlose.anotherwidget.`object`.Constants
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.util.Util
|
||||
import com.tommasoberlose.anotherwidget.ui.widget.TheWidget
|
||||
import com.tommasoberlose.anotherwidget.util.UpdatesReceiver
|
||||
import com.tommasoberlose.anotherwidget.util.WeatherReceiver
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
|
||||
|
||||
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
action_support.setOnClickListener(object: View.OnClickListener {
|
||||
override fun onClick(p0: View?) {
|
||||
Util.openURI(this@MainActivity, "https://paypal.me/tommasoberlose")
|
||||
}
|
||||
})
|
||||
|
||||
action_rate.setOnClickListener(object: View.OnClickListener {
|
||||
override fun onClick(p0: View?) {
|
||||
Util.openURI(this@MainActivity, "")
|
||||
}
|
||||
})
|
||||
|
||||
action_share.setOnClickListener(object: View.OnClickListener {
|
||||
override fun onClick(p0: View?) {
|
||||
Util.share(this@MainActivity)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
updateUI()
|
||||
Util.updateWidget(this)
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
|
||||
grantResults: IntArray) {
|
||||
when (requestCode) {
|
||||
Constants.CALENDAR_REQUEST_CODE -> if (permissions.size != 1 || grantResults.size != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
|
||||
UpdatesReceiver().removeUpdates(this)
|
||||
} else {
|
||||
UpdatesReceiver().setUpdates(this)
|
||||
}
|
||||
Constants.LOCATION_REQUEST_CODE -> if (permissions.size != 1 || grantResults.size != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
|
||||
WeatherReceiver().removeUpdates(this)
|
||||
} else {
|
||||
WeatherReceiver().setUpdates(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateUI() {
|
||||
no_calendar_permission_container.visibility= View.GONE
|
||||
no_location_permission_container.visibility= View.GONE
|
||||
|
||||
if (!Util.checkGrantedPermission(this, Manifest.permission.READ_CALENDAR)) {
|
||||
no_calendar_permission_container.visibility = View.VISIBLE
|
||||
request_calendar.setOnClickListener(object: View.OnClickListener {
|
||||
override fun onClick(view: View?) {
|
||||
ActivityCompat.requestPermissions(this@MainActivity, arrayOf(Manifest.permission.READ_CALENDAR), Constants.CALENDAR_REQUEST_CODE)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if (!Util.checkGrantedPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
|
||||
no_location_permission_container.visibility = View.VISIBLE
|
||||
request_location.setOnClickListener(object: View.OnClickListener {
|
||||
override fun onClick(view: View?) {
|
||||
ActivityCompat.requestPermissions(this@MainActivity, arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION), Constants.LOCATION_REQUEST_CODE)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,224 @@
|
||||
package com.tommasoberlose.anotherwidget.ui.widget
|
||||
|
||||
import android.Manifest
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.appwidget.AppWidgetProvider
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.preference.PreferenceManager
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.RemoteViews
|
||||
|
||||
import com.tommasoberlose.anotherwidget.`object`.Constants
|
||||
import com.tommasoberlose.anotherwidget.`object`.Event
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.ui.activity.MainActivity
|
||||
import com.tommasoberlose.anotherwidget.util.UpdatesReceiver
|
||||
import com.tommasoberlose.anotherwidget.util.Util
|
||||
import com.tommasoberlose.anotherwidget.util.WeatherReceiver
|
||||
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.TimeUnit
|
||||
import android.app.PendingIntent
|
||||
import android.net.Uri
|
||||
import android.provider.CalendarContract
|
||||
import android.content.ContentUris
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of App Widget functionality.
|
||||
*/
|
||||
class TheWidget : AppWidgetProvider() {
|
||||
|
||||
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
|
||||
for (appWidgetId in appWidgetIds) {
|
||||
updateAppWidget(context, appWidgetManager, appWidgetId)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onEnabled(context: Context) {
|
||||
UpdatesReceiver().setUpdates(context)
|
||||
WeatherReceiver().setUpdates(context)
|
||||
Util.showNotification(context)
|
||||
}
|
||||
|
||||
override fun onDisabled(context: Context) {
|
||||
UpdatesReceiver().removeUpdates(context)
|
||||
WeatherReceiver().removeUpdates(context)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
internal fun updateAppWidget(context: Context, appWidgetManager: AppWidgetManager,
|
||||
appWidgetId: Int) {
|
||||
|
||||
var views = RemoteViews(context.packageName, R.layout.the_widget)
|
||||
|
||||
views = updateCalendarView(context, views, appWidgetId)
|
||||
|
||||
views = updateLocationView(context, views)
|
||||
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views)
|
||||
}
|
||||
|
||||
fun updateCalendarView(context: Context, views: RemoteViews, widgetID: Int): RemoteViews {
|
||||
val now = Calendar.getInstance()
|
||||
val calendarLayout = Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR)
|
||||
|
||||
views.setViewVisibility(R.id.empty_layout, View.VISIBLE)
|
||||
views.setViewVisibility(R.id.calendar_layout, View.GONE)
|
||||
views.setTextViewText(R.id.empty_date, Constants.dateFormat.format(now.time))
|
||||
|
||||
val calIntent = Intent(Intent.ACTION_MAIN)
|
||||
calIntent.addCategory(Intent.CATEGORY_APP_CALENDAR)
|
||||
val calPIntent = PendingIntent.getActivity(context, widgetID, calIntent, 0)
|
||||
views.setOnClickPendingIntent(R.id.main_layout, calPIntent)
|
||||
|
||||
|
||||
if (calendarLayout) {
|
||||
val eventList = Util.getNextEvent(context)
|
||||
|
||||
if (eventList.isNotEmpty()) {
|
||||
val difference = eventList[0].startDate - now.timeInMillis
|
||||
|
||||
if (difference > 1000 * 60) {
|
||||
var time = ""
|
||||
val hour = TimeUnit.MILLISECONDS.toHours(difference)
|
||||
if (hour > 0) {
|
||||
time = hour.toString() + "h"
|
||||
}
|
||||
val minutes = TimeUnit.MILLISECONDS.toMinutes(difference - hour * 3600 * 1000)
|
||||
if (minutes > 0) {
|
||||
time += " " + minutes + "min"
|
||||
}
|
||||
|
||||
views.setTextViewText(R.id.next_event, String.format("%s in %s", eventList[0].title, time))
|
||||
} else {
|
||||
views.setTextViewText(R.id.next_event, String.format("%s", eventList[0].title))
|
||||
}
|
||||
views.setTextViewText(R.id.next_event_date, String.format("%s - %s", Constants.hourFormat.format(eventList[0].startDate), Constants.hourFormat.format(eventList[0].endDate)))
|
||||
|
||||
views.setViewVisibility(R.id.empty_layout, View.GONE)
|
||||
views.setViewVisibility(R.id.calendar_layout, View.VISIBLE)
|
||||
|
||||
val builder = CalendarContract.CONTENT_URI.buildUpon()
|
||||
builder.appendPath("time")
|
||||
ContentUris.appendId(builder, eventList[0].startDate)
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
.setData(builder.build())
|
||||
val pIntent = PendingIntent.getActivity(context, widgetID, intent, 0)
|
||||
views.setOnClickPendingIntent(R.id.main_layout, pIntent)
|
||||
}
|
||||
}
|
||||
|
||||
return views
|
||||
}
|
||||
|
||||
fun updateLocationView(context: Context, views: RemoteViews): RemoteViews {
|
||||
val locationLayout = Util.checkGrantedPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
|
||||
|
||||
val SP = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
if (locationLayout && SP.contains(Constants.PREF_WEATHER_TEMP) && SP.contains(Constants.PREF_WEATHER_ICON)) {
|
||||
views.setViewVisibility(R.id.weather, View.VISIBLE)
|
||||
views.setViewVisibility(R.id.calendar_weather, View.VISIBLE)
|
||||
val temp = String.format(Locale.getDefault(), "%.0f °C", SP.getFloat(Constants.PREF_WEATHER_TEMP, 0f))
|
||||
|
||||
|
||||
views.setViewVisibility(R.id.weather_icon, View.VISIBLE)
|
||||
views.setViewVisibility(R.id.empty_weather_icon, View.VISIBLE)
|
||||
when (SP.getString(Constants.PREF_WEATHER_ICON, "")) {
|
||||
"01d" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.clear_day)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.clear_day)
|
||||
}
|
||||
"02d" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.partly_cloudy)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.partly_cloudy)
|
||||
}
|
||||
"03d" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.mostly_cloudy)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.mostly_cloudy)
|
||||
}
|
||||
"04d" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.cloudy_weather)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.cloudy_weather)
|
||||
}
|
||||
"09d" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.storm_weather_day)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.storm_weather_day)
|
||||
}
|
||||
"10d" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.rainy_day)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.rainy_day)
|
||||
}
|
||||
"11d" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.thunder_day)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.thunder_day)
|
||||
}
|
||||
"13d" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.snow_day)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.snow_day)
|
||||
}
|
||||
"50d" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.haze_day)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.haze_day)
|
||||
}
|
||||
"01n" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.clear_night)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.clear_night)
|
||||
}
|
||||
"02n" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.partly_cloudy_night)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.partly_cloudy_night)
|
||||
}
|
||||
"03n" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.mostly_cloudy_night)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.mostly_cloudy_night)
|
||||
}
|
||||
"04n" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.cloudy_weather)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.cloudy_weather)
|
||||
}
|
||||
"09n" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.storm_weather_night)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.storm_weather_night)
|
||||
}
|
||||
"10n" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.rainy_night)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.rainy_night)
|
||||
}
|
||||
"11n" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.thunder_night)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.thunder_night)
|
||||
}
|
||||
"13n" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.snow_night)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.snow_night)
|
||||
}
|
||||
"50n" -> {
|
||||
views.setImageViewResource(R.id.weather_icon, R.drawable.haze_night)
|
||||
views.setImageViewResource(R.id.empty_weather_icon, R.drawable.haze_night)
|
||||
}
|
||||
else -> {
|
||||
views.setViewVisibility(R.id.weather_icon, View.GONE)
|
||||
views.setViewVisibility(R.id.empty_weather_icon, View.GONE)
|
||||
}
|
||||
}
|
||||
|
||||
views.setTextViewText(R.id.temp, temp)
|
||||
views.setTextViewText(R.id.calendar_temp, temp)
|
||||
} else {
|
||||
views.setViewVisibility(R.id.weather, View.GONE)
|
||||
views.setViewVisibility(R.id.calendar_weather, View.GONE)
|
||||
}
|
||||
return views
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
package com.tommasoberlose.anotherwidget.util
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
|
||||
class NewCalendarEventReceiver : BroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
Util.updateWidget(context)
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.tommasoberlose.anotherwidget.util
|
||||
|
||||
import android.Manifest
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.R.string.cancel
|
||||
import android.app.AlarmManager
|
||||
import android.app.PendingIntent
|
||||
import android.util.Log
|
||||
import com.tommasoberlose.anotherwidget.`object`.Constants
|
||||
|
||||
|
||||
class UpdatesReceiver : BroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (intent.action.equals(Intent.ACTION_BOOT_COMPLETED) || intent.action.equals(Intent.ACTION_INSTALL_PACKAGE) || intent.action.equals(Constants.ACTION_TIME_UPDATE)) {
|
||||
Util.updateWidget(context)
|
||||
}
|
||||
}
|
||||
|
||||
fun setUpdates(context: Context) {
|
||||
removeUpdates(context)
|
||||
|
||||
if (Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR)) {
|
||||
Util.updateWidget(context)
|
||||
|
||||
val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
val i = Intent(context, UpdatesReceiver::class.java)
|
||||
i.action = Constants.ACTION_TIME_UPDATE
|
||||
val pi = PendingIntent.getBroadcast(context, 0, i, 0)
|
||||
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), (1000 * 60).toLong(), pi)
|
||||
}
|
||||
}
|
||||
|
||||
fun removeUpdates(context: Context) {
|
||||
val intent = Intent(context, UpdatesReceiver::class.java)
|
||||
val sender = PendingIntent.getBroadcast(context, 0, intent, 0)
|
||||
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
alarmManager.cancel(sender)
|
||||
}
|
||||
}
|
238
app/src/main/java/com/tommasoberlose/anotherwidget/util/Util.kt
Normal file
@ -0,0 +1,238 @@
|
||||
package com.tommasoberlose.anotherwidget.util
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Notification
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.content.*
|
||||
import android.content.pm.PackageManager
|
||||
import android.database.Cursor
|
||||
import android.location.Location
|
||||
import android.location.LocationListener
|
||||
import android.location.LocationManager
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.preference.PreferenceManager
|
||||
import android.provider.CalendarContract
|
||||
import android.support.customtabs.CustomTabsIntent
|
||||
import android.support.v4.app.NotificationCompat
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.util.Log
|
||||
import com.survivingwithandroid.weather.lib.WeatherClient
|
||||
import com.survivingwithandroid.weather.lib.WeatherConfig
|
||||
import com.survivingwithandroid.weather.lib.exception.LocationProviderNotFoundException
|
||||
import com.survivingwithandroid.weather.lib.exception.WeatherLibException
|
||||
import com.survivingwithandroid.weather.lib.model.City
|
||||
import com.survivingwithandroid.weather.lib.model.CurrentWeather
|
||||
import com.survivingwithandroid.weather.lib.provider.forecastio.ForecastIOProviderType
|
||||
import com.survivingwithandroid.weather.lib.provider.forecastio.ForecastIOWeatherProvider
|
||||
import com.survivingwithandroid.weather.lib.provider.openweathermap.OpenweathermapProviderType
|
||||
import com.survivingwithandroid.weather.lib.provider.yahooweather.YahooProviderType
|
||||
import com.survivingwithandroid.weather.lib.request.WeatherRequest
|
||||
import com.tommasoberlose.anotherwidget.R
|
||||
import com.tommasoberlose.anotherwidget.`object`.Constants
|
||||
|
||||
import com.tommasoberlose.anotherwidget.`object`.Event
|
||||
import com.tommasoberlose.anotherwidget.ui.activity.MainActivity
|
||||
import com.tommasoberlose.anotherwidget.ui.widget.TheWidget
|
||||
|
||||
import java.util.ArrayList
|
||||
import java.util.Calendar
|
||||
|
||||
/**
|
||||
* Created by tommaso on 05/10/17.
|
||||
*/
|
||||
|
||||
object Util {
|
||||
|
||||
|
||||
fun checkGrantedPermission(context: Context, permission: String): Boolean {
|
||||
return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
|
||||
fun getNextEvent(context: Context): List<Event> {
|
||||
val eventList = ArrayList<Event>()
|
||||
|
||||
val now = Calendar.getInstance()
|
||||
val hourLimit = Calendar.getInstance()
|
||||
hourLimit.add(Calendar.HOUR, 6)
|
||||
|
||||
val builder = CalendarContract.Instances.CONTENT_URI.buildUpon()
|
||||
ContentUris.appendId(builder, now.timeInMillis)
|
||||
ContentUris.appendId(builder, hourLimit.timeInMillis)
|
||||
|
||||
if (!checkGrantedPermission(context, Manifest.permission.READ_CALENDAR)) {
|
||||
return eventList
|
||||
}
|
||||
|
||||
val instanceCursor = context.contentResolver.query(builder.build(), arrayOf(CalendarContract.Instances.EVENT_ID, CalendarContract.Instances.BEGIN, CalendarContract.Instances.END), null, null, null) ?: return eventList
|
||||
instanceCursor.moveToFirst()
|
||||
|
||||
for (i in 0 until instanceCursor.count) {
|
||||
val ID = instanceCursor.getInt(0)
|
||||
|
||||
val eventCursor = context.contentResolver.query(CalendarContract.Events.CONTENT_URI, arrayOf(CalendarContract.Events.TITLE),
|
||||
CalendarContract.Events._ID + " is ?",
|
||||
arrayOf(Integer.toString(ID)), null) ?: return eventList
|
||||
eventCursor.moveToFirst()
|
||||
|
||||
for (j in 0 until eventCursor.count) {
|
||||
val e = Event(eventCursor, instanceCursor)
|
||||
if (e.endDate - now.timeInMillis > 1000 * 60 * 60) {
|
||||
eventList.add(e)
|
||||
}
|
||||
eventCursor.moveToNext()
|
||||
}
|
||||
|
||||
eventCursor.close()
|
||||
|
||||
instanceCursor.moveToNext()
|
||||
}
|
||||
|
||||
instanceCursor.close()
|
||||
return eventList
|
||||
}
|
||||
|
||||
fun updateWidget(context: Context) {
|
||||
val widgetManager = AppWidgetManager.getInstance(context)
|
||||
val widgetComponent = ComponentName(context, TheWidget::class.java)
|
||||
val widgetIds = widgetManager.getAppWidgetIds(widgetComponent)
|
||||
val update = Intent()
|
||||
update.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, widgetIds)
|
||||
update.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||
context.sendBroadcast(update)
|
||||
}
|
||||
|
||||
fun getWeather(context: Context) {
|
||||
if (!checkGrantedPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)) {
|
||||
return
|
||||
}
|
||||
val SP: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
|
||||
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||
getCurrentWeather(context, locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER))
|
||||
|
||||
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0f, object: LocationListener {
|
||||
override fun onLocationChanged(location: Location) {
|
||||
locationManager.removeUpdates(this)
|
||||
getCurrentWeather(context, location)
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
override fun onProviderDisabled(p0: String?) {
|
||||
SP.edit()
|
||||
.remove(Constants.PREF_WEATHER_TEMP)
|
||||
.remove(Constants.PREF_WEATHER_ICON)
|
||||
.commit()
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
override fun onProviderEnabled(p0: String?) {
|
||||
SP.edit()
|
||||
.remove(Constants.PREF_WEATHER_TEMP)
|
||||
.remove(Constants.PREF_WEATHER_ICON)
|
||||
.commit()
|
||||
}
|
||||
|
||||
override fun onStatusChanged(p0: String?, p1: Int, p2: Bundle?) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
fun getCurrentWeather(context: Context, location: Location) {
|
||||
val SP: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
|
||||
try {
|
||||
val config = WeatherConfig()
|
||||
config.unitSystem = WeatherConfig.UNIT_SYSTEM.M
|
||||
config.lang = "en" // If you want to use english
|
||||
config.maxResult = 1 // Max number of cities retrieved
|
||||
config.numDays = 1 // Max num of days in the forecast
|
||||
config.ApiKey = "43e744ad8ff91b09ea62dbc7d0e7c1dd";
|
||||
|
||||
val client = WeatherClient.ClientBuilder().attach(context)
|
||||
.httpClient(com.survivingwithandroid.weather.lib.client.volley.WeatherClientDefault::class.java)
|
||||
.provider(OpenweathermapProviderType())
|
||||
.config(config)
|
||||
.build()
|
||||
|
||||
client.getCurrentCondition(WeatherRequest(location.longitude, location.latitude), object : WeatherClient.WeatherEventListener {
|
||||
@SuppressLint("ApplySharedPref")
|
||||
override fun onWeatherRetrieved(currentWeather: CurrentWeather) {
|
||||
Log.d("AW", "TEMP:" + currentWeather.weather.currentCondition.icon);
|
||||
SP.edit()
|
||||
.putFloat(Constants.PREF_WEATHER_TEMP, currentWeather.weather.temperature.temp)
|
||||
.putString(Constants.PREF_WEATHER_ICON, currentWeather.weather.currentCondition.icon)
|
||||
.commit()
|
||||
updateWidget(context)
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
override fun onWeatherError(e: WeatherLibException?) {
|
||||
SP.edit()
|
||||
.remove(Constants.PREF_WEATHER_TEMP)
|
||||
.remove(Constants.PREF_WEATHER_ICON)
|
||||
.commit()
|
||||
}
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
override fun onConnectionError(throwable: Throwable?) {
|
||||
SP.edit()
|
||||
.remove(Constants.PREF_WEATHER_TEMP)
|
||||
.remove(Constants.PREF_WEATHER_ICON)
|
||||
.commit()
|
||||
}
|
||||
})
|
||||
} catch (t: Exception) {
|
||||
SP.edit()
|
||||
.remove(Constants.PREF_WEATHER_TEMP)
|
||||
.remove(Constants.PREF_WEATHER_ICON)
|
||||
.commit()
|
||||
}
|
||||
}
|
||||
|
||||
fun showNotification(context: Context) {
|
||||
val mNotificationManager: NotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager;
|
||||
|
||||
if (!Util.checkGrantedPermission(context, Manifest.permission.READ_CALENDAR)) {
|
||||
val mBuilder: NotificationCompat.Builder = NotificationCompat.Builder(context, "Settings")
|
||||
.setSmallIcon(R.drawable.ic_stat_name)
|
||||
.setPriority(Notification.PRIORITY_MIN)
|
||||
.setColor(ContextCompat.getColor(context, R.color.colorPrimary))
|
||||
.setContentTitle(context.getString(R.string.notification_title))
|
||||
.setContentText(context.getString(R.string.notification_subtitle))
|
||||
.setAutoCancel(true);
|
||||
|
||||
val intent: Intent = Intent(context, MainActivity::class.java);
|
||||
val pi: PendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
mBuilder.setContentIntent(pi);
|
||||
mNotificationManager.notify(0, mBuilder.build());
|
||||
} else {
|
||||
mNotificationManager.cancel(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun openURI(context: Context, url: String) {
|
||||
try {
|
||||
val builder: CustomTabsIntent.Builder = CustomTabsIntent.Builder();
|
||||
builder.setToolbarColor(ContextCompat.getColor(context, R.color.colorPrimary));
|
||||
val customTabsIntent: CustomTabsIntent = builder.build();
|
||||
customTabsIntent.launchUrl(context, Uri.parse(url));
|
||||
} catch (e: Exception) {
|
||||
val legalIntent = Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
context.startActivity(legalIntent);
|
||||
}
|
||||
}
|
||||
|
||||
fun share(context: Context) {
|
||||
val sendIntent = Intent(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT,
|
||||
"Yep, just another cool widget: https://play.google.com/store/apps/details?id=com.tommasoberlose.anotherwidget");
|
||||
sendIntent.setType("text/plain");
|
||||
context.startActivity(Intent.createChooser(sendIntent, context.getString(R.string.action_share)));
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.tommasoberlose.anotherwidget.util
|
||||
|
||||
import android.Manifest
|
||||
import android.app.AlarmManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.tommasoberlose.anotherwidget.`object`.Constants
|
||||
|
||||
class WeatherReceiver : BroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (intent.action.equals(Intent.ACTION_BOOT_COMPLETED) || intent.action.equals(Intent.ACTION_INSTALL_PACKAGE) || intent.action.equals(Constants.ACTION_WEATHER_UPDATE)) {
|
||||
Util.getWeather(context)
|
||||
}
|
||||
}
|
||||
|
||||
fun setUpdates(context: Context) {
|
||||
removeUpdates(context)
|
||||
|
||||
if (Util.checkGrantedPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)) {
|
||||
Util.getWeather(context)
|
||||
|
||||
val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
val i = Intent(context, WeatherReceiver::class.java)
|
||||
i.action = Constants.ACTION_WEATHER_UPDATE
|
||||
val pi = PendingIntent.getBroadcast(context, 1, i, 0)
|
||||
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), (1000 * 60 * 60 * 2).toLong(), pi) // 2 hour
|
||||
}
|
||||
}
|
||||
|
||||
fun removeUpdates(context: Context) {
|
||||
val intent = Intent(context, WeatherReceiver::class.java)
|
||||
val sender = PendingIntent.getBroadcast(context, 1, intent, 0)
|
||||
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
alarmManager.cancel(sender)
|
||||
}
|
||||
}
|
BIN
app/src/main/res/drawable-hdpi/ic_action_calendar.png
Normal file
After Width: | Height: | Size: 306 B |
BIN
app/src/main/res/drawable-hdpi/ic_action_feedback.png
Normal file
After Width: | Height: | Size: 282 B |
BIN
app/src/main/res/drawable-hdpi/ic_action_gift.png
Normal file
After Width: | Height: | Size: 643 B |
BIN
app/src/main/res/drawable-hdpi/ic_action_location.png
Normal file
After Width: | Height: | Size: 624 B |
BIN
app/src/main/res/drawable-hdpi/ic_action_rate.png
Normal file
After Width: | Height: | Size: 861 B |
BIN
app/src/main/res/drawable-hdpi/ic_action_share.png
Normal file
After Width: | Height: | Size: 608 B |
BIN
app/src/main/res/drawable-hdpi/ic_stat_name.png
Normal file
After Width: | Height: | Size: 316 B |
BIN
app/src/main/res/drawable-mdpi/ic_action_calendar.png
Normal file
After Width: | Height: | Size: 221 B |
BIN
app/src/main/res/drawable-mdpi/ic_action_feedback.png
Normal file
After Width: | Height: | Size: 202 B |
BIN
app/src/main/res/drawable-mdpi/ic_action_gift.png
Normal file
After Width: | Height: | Size: 425 B |
BIN
app/src/main/res/drawable-mdpi/ic_action_location.png
Normal file
After Width: | Height: | Size: 410 B |
BIN
app/src/main/res/drawable-mdpi/ic_action_rate.png
Normal file
After Width: | Height: | Size: 543 B |
BIN
app/src/main/res/drawable-mdpi/ic_action_share.png
Normal file
After Width: | Height: | Size: 436 B |
BIN
app/src/main/res/drawable-mdpi/ic_stat_name.png
Normal file
After Width: | Height: | Size: 227 B |
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-xhdpi/ic_action_calendar.png
Normal file
After Width: | Height: | Size: 337 B |
BIN
app/src/main/res/drawable-xhdpi/ic_action_feedback.png
Normal file
After Width: | Height: | Size: 329 B |
BIN
app/src/main/res/drawable-xhdpi/ic_action_gift.png
Normal file
After Width: | Height: | Size: 787 B |
BIN
app/src/main/res/drawable-xhdpi/ic_action_location.png
Normal file
After Width: | Height: | Size: 794 B |
BIN
app/src/main/res/drawable-xhdpi/ic_action_rate.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_action_share.png
Normal file
After Width: | Height: | Size: 828 B |
BIN
app/src/main/res/drawable-xhdpi/ic_stat_name.png
Normal file
After Width: | Height: | Size: 432 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_action_calendar.png
Normal file
After Width: | Height: | Size: 572 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_action_feedback.png
Normal file
After Width: | Height: | Size: 507 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_action_gift.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/main/res/drawable-xxhdpi/ic_action_location.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/drawable-xxhdpi/ic_action_rate.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/drawable-xxhdpi/ic_action_share.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/drawable-xxhdpi/ic_stat_name.png
Normal file
After Width: | Height: | Size: 640 B |
12
app/src/main/res/drawable/card_background.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<corners
|
||||
android:radius="3dp" />
|
||||
<stroke
|
||||
android:color="@android:color/white"
|
||||
android:width="2dp"/>
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
9
app/src/main/res/drawable/circle_background.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:shape="oval">
|
||||
<solid
|
||||
android:color="@color/black_30" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
BIN
app/src/main/res/drawable/clear_day.png
Executable file
After Width: | Height: | Size: 11 KiB |
BIN
app/src/main/res/drawable/clear_night.png
Executable file
After Width: | Height: | Size: 10 KiB |
BIN
app/src/main/res/drawable/cloudy_weather.png
Executable file
After Width: | Height: | Size: 10 KiB |
11
app/src/main/res/drawable/dark_card_background.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<corners
|
||||
android:radius="3dp" />
|
||||
<solid
|
||||
android:color="@color/black_30"/>
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
12
app/src/main/res/drawable/gradient_background.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape>
|
||||
<gradient
|
||||
android:angle="90"
|
||||
android:startColor="@color/colorNightDark"
|
||||
android:endColor="@color/colorPrimary"
|
||||
android:type="linear" />
|
||||
</shape>
|
||||
</item>
|
||||
</selector>
|
BIN
app/src/main/res/drawable/haze_day.png
Executable file
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/drawable/haze_night.png
Executable file
After Width: | Height: | Size: 15 KiB |
BIN
app/src/main/res/drawable/haze_weather.png
Executable file
After Width: | Height: | Size: 12 KiB |
113
app/src/main/res/drawable/ic_launcher_background.xml
Normal file
@ -0,0 +1,113 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="108.0"
|
||||
android:viewportWidth="108.0">
|
||||
<path
|
||||
android:fillColor="#26A69A"
|
||||
android:pathData="M0,0h108v108h-108z"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeColor="#66FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
</vector>
|
||||
|
BIN
app/src/main/res/drawable/mostly_cloudy.png
Executable file
After Width: | Height: | Size: 19 KiB |
BIN
app/src/main/res/drawable/mostly_cloudy_night.png
Executable file
After Width: | Height: | Size: 17 KiB |
BIN
app/src/main/res/drawable/partly_cloudy.png
Executable file
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/drawable/partly_cloudy_night.png
Executable file
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/drawable/rain_snow.png
Executable file
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/drawable/rain_snow_day.png
Executable file
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/drawable/rain_snow_night.png
Executable file
After Width: | Height: | Size: 17 KiB |
BIN
app/src/main/res/drawable/rainy_day.png
Executable file
After Width: | Height: | Size: 15 KiB |
BIN
app/src/main/res/drawable/rainy_night.png
Executable file
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/drawable/rainy_weather.png
Executable file
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/drawable/showcase.png
Executable file
After Width: | Height: | Size: 48 KiB |
BIN
app/src/main/res/drawable/snow_day.png
Executable file
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/drawable/snow_night.png
Executable file
After Width: | Height: | Size: 17 KiB |
BIN
app/src/main/res/drawable/snow_weather.png
Executable file
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/drawable/storm_weather.png
Executable file
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/drawable/storm_weather_day.png
Executable file
After Width: | Height: | Size: 15 KiB |
BIN
app/src/main/res/drawable/storm_weather_night.png
Executable file
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/drawable/thunder_day.png
Executable file
After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/drawable/thunder_night.png
Executable file
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/drawable/thunder_weather.png
Executable file
After Width: | Height: | Size: 12 KiB |
BIN
app/src/main/res/drawable/unknown.png
Executable file
After Width: | Height: | Size: 20 KiB |
BIN
app/src/main/res/drawable/windy_day.png
Executable file
After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/drawable/windy_night.png
Executable file
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/drawable/windy_weather.png
Executable file
After Width: | Height: | Size: 12 KiB |
233
app/src/main/res/layout/activity_main.xml
Normal file
@ -0,0 +1,233 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/gradient_background"
|
||||
android:orientation="vertical"
|
||||
tools:context="com.tommasoberlose.anotherwidget.ui.activity.MainActivity">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="48dp"
|
||||
android:layout_marginLeft="48dp"
|
||||
android:layout_marginRight="48dp"
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:gravity="center_vertical">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/main_pre_title"
|
||||
android:alpha="0.6"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:gravity="center_vertical"
|
||||
style="@style/AnotherWidget.Main.Subtitle"
|
||||
android:textAllCaps="true"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/app_name"
|
||||
android:gravity="center_vertical"
|
||||
style="@style/AnotherWidget.Main.Title"
|
||||
android:textAllCaps="true"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="24dp"
|
||||
android:layout_below="@+id/toolbar"
|
||||
android:gravity="center"
|
||||
android:layout_above="@+id/menu_container"
|
||||
android:id="@+id/all_set_container">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AnotherWidget.Main.Title"
|
||||
android:gravity="start"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/all_set_title"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AnotherWidget.Main.Description"
|
||||
android:alpha="0.9"
|
||||
android:fontFamily="sans-serif"
|
||||
android:text="@string/all_set_subtitle"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AnotherWidget.Main.Button.Dark"
|
||||
android:id="@+id/action_github"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/all_set_btn"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/no_calendar_permission_container"
|
||||
android:orientation="vertical">
|
||||
<ImageView
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:padding="14dp"
|
||||
android:tint="@android:color/white"
|
||||
android:background="@drawable/circle_background"
|
||||
android:src="@drawable/ic_action_calendar"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AnotherWidget.Main.Title"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingRight="32dp"
|
||||
android:paddingLeft="32dp"
|
||||
android:text="@string/title_permission_calendar"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AnotherWidget.Main.Description"
|
||||
android:paddingBottom="32dp"
|
||||
android:paddingRight="32dp"
|
||||
android:paddingLeft="32dp"
|
||||
android:text="@string/description_permission_calendar"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AnotherWidget.Main.Button"
|
||||
android:id="@+id/request_calendar"
|
||||
android:text="@string/button_request_permission"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:id="@+id/no_location_permission_container"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
<ImageView
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:padding="14dp"
|
||||
android:tint="@android:color/white"
|
||||
android:background="@drawable/circle_background"
|
||||
android:src="@drawable/ic_action_location"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AnotherWidget.Main.Title"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingRight="32dp"
|
||||
android:paddingLeft="32dp"
|
||||
android:text="@string/title_permission_location"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AnotherWidget.Main.Description"
|
||||
android:paddingBottom="32dp"
|
||||
android:paddingRight="32dp"
|
||||
android:paddingLeft="32dp"
|
||||
android:text="@string/description_permission_location"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AnotherWidget.Main.Button"
|
||||
android:id="@+id/request_location"
|
||||
android:text="@string/button_request_permission"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:baselineAligned="false"
|
||||
android:id="@+id/menu_container"
|
||||
android:background="@color/black_10"
|
||||
android:layout_alignParentBottom="true">
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="3"
|
||||
android:gravity="center"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingTop="8dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:id="@+id/action_share"
|
||||
android:orientation="vertical">
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:padding="2dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:src="@drawable/ic_action_share"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/action_share"
|
||||
style="@style/AnotherWidget.Main.Button.TabBar"
|
||||
android:background="@android:color/transparent"/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="3"
|
||||
android:gravity="center"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingTop="8dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:id="@+id/action_rate"
|
||||
android:orientation="vertical">
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:padding="2dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:src="@drawable/ic_action_rate"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/action_rate"
|
||||
style="@style/AnotherWidget.Main.Button.TabBar"
|
||||
android:background="@android:color/transparent"/>
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="3"
|
||||
android:gravity="center"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingTop="8dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:id="@+id/action_support"
|
||||
android:orientation="vertical">
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:padding="2dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:src="@drawable/ic_action_gift"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/action_support"
|
||||
style="@style/AnotherWidget.Main.Button.TabBar"
|
||||
android:background="@android:color/transparent"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
106
app/src/main/res/layout/the_widget.xml
Normal file
@ -0,0 +1,106 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/main_layout">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/empty_layout">
|
||||
<TextView
|
||||
android:id="@+id/empty_date"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="5"
|
||||
style="@style/AnotherWidget.Title" />
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:id="@+id/weather"
|
||||
android:visibility="gone">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="@string/divider"
|
||||
style="@style/AnotherWidget.Subtitle"/>
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:id="@+id/empty_weather_icon"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:src="@drawable/clear_night"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AnotherWidget.Date.Big"
|
||||
android:id="@+id/temp"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/calendar_layout"
|
||||
android:gravity="center">
|
||||
<TextView
|
||||
android:id="@+id/next_event"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AnotherWidget.Title" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center">
|
||||
<ImageView
|
||||
android:layout_width="14dp"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginTop="1dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:src="@drawable/ic_action_calendar"/>
|
||||
<TextView
|
||||
android:id="@+id/next_event_date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AnotherWidget.Subtitle" />
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:id="@+id/calendar_weather">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="@string/divider"
|
||||
style="@style/AnotherWidget.Subtitle"/>
|
||||
<ImageView
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:id="@+id/weather_icon"
|
||||
android:src="@drawable/clear_night"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AnotherWidget.Date"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:id="@+id/calendar_temp"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
18
app/src/main/res/layout/weather_layout.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="|"
|
||||
style="@style/AnotherWidget.Subtitle"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/AnotherWidget.Date"
|
||||
android:id="@+id/temp"/>
|
||||
</LinearLayout>
|
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/gradient_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
5
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/gradient_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Normal file
After Width: | Height: | Size: 8.8 KiB |