Commit ff465c6b authored by Giacomo Lavermicocca's avatar Giacomo Lavermicocca

Kotlin conversion and activity settings added

parent eae8f13f
<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>
\ No newline at end of file
......@@ -5,21 +5,24 @@
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="4">
<list size="6">
<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" />
<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" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="4">
<list size="5">
<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" />
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
</list>
</value>
</option>
......
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="" vcs="Git" />
</component>
</project>
\ No newline at end of file
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 27
......@@ -9,6 +11,7 @@ android {
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
......@@ -22,4 +25,12 @@ dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:support-vector-drawable:27.1.1'
}
repositories {
mavenCentral()
}
......@@ -2,6 +2,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.lavermicocca.giacomo.beautifulnotification">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
......@@ -16,7 +19,32 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="MainActivity$switchButtonListener" />
<receiver android:name=".MainActivity$switchButtonListener" />
<service
android:name=".services.NotificationService"
android:enabled="true"
android:exported="true" />
<receiver
android:name=".receivers.BootCompletedReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<!-- For HTC devices -->
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
<activity
android:name=".SettingsActivity"
android:label="@string/title_activity_settings"></activity>
</application>
</manifest>
\ No newline at end of file
package it.lavermicocca.giacomo.beautifulnotification
import android.content.res.Configuration
import android.os.Bundle
import android.preference.PreferenceActivity
import android.support.annotation.LayoutRes
import android.support.v7.app.ActionBar
import android.support.v7.app.AppCompatDelegate
import android.support.v7.widget.Toolbar
import android.view.MenuInflater
import android.view.View
import android.view.ViewGroup
/**
* A [android.preference.PreferenceActivity] which implements and proxies the necessary calls
* to be used with AppCompat.
*/
abstract class AppCompatPreferenceActivity : PreferenceActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
delegate.installViewFactory()
delegate.onCreate(savedInstanceState)
super.onCreate(savedInstanceState)
}
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
delegate.onPostCreate(savedInstanceState)
}
val supportActionBar: ActionBar?
get() = delegate.supportActionBar
fun setSupportActionBar(toolbar: Toolbar?) {
delegate.setSupportActionBar(toolbar)
}
override fun getMenuInflater(): MenuInflater {
return delegate.menuInflater
}
override fun setContentView(@LayoutRes layoutResID: Int) {
delegate.setContentView(layoutResID)
}
override fun setContentView(view: View) {
delegate.setContentView(view)
}
override fun setContentView(view: View, params: ViewGroup.LayoutParams) {
delegate.setContentView(view, params)
}
override fun addContentView(view: View, params: ViewGroup.LayoutParams) {
delegate.addContentView(view, params)
}
override fun onPostResume() {
super.onPostResume()
delegate.onPostResume()
}
override fun onTitleChanged(title: CharSequence, color: Int) {
super.onTitleChanged(title, color)
delegate.setTitle(title)
}
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
delegate.onConfigurationChanged(newConfig)
}
override fun onStop() {
super.onStop()
delegate.onStop()
}
override fun onDestroy() {
super.onDestroy()
delegate.onDestroy()
}
override fun invalidateOptionsMenu() {
delegate.invalidateOptionsMenu()
}
private val delegate: AppCompatDelegate by lazy {
AppCompatDelegate.create(this, null)
}
}
package it.lavermicocca.giacomo.beautifulnotification
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.Toast
import it.lavermicocca.giacomo.beautifulnotification.services.Helper
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Response
import java.io.IOException
class MainActivity : AppCompatActivity() {
class switchButtonListener : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
Log.d("Here", "I am here")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Helper.StartForegroundServiceNotification(applicationContext)
findViewById<Button>(R.id.start_notification).setOnClickListener(View.OnClickListener {
Helper.StartForegroundServiceNotification(applicationContext)
SendGet(13)
})
findViewById<Button>(R.id.start_settings).setOnClickListener(View.OnClickListener {
val intent = Intent(this, SettingsActivity::class.java).apply {
//putExtra(EXTRA_MESSAGE, message)
}
startActivity(intent)
})
}
//-------------------- HTTP WAY -------------------------
private fun SendGet(pin: Int) {
val prf = getApplicationContext().getSharedPreferences("myPref", Context.MODE_PRIVATE)
val ipServer = prf.getString("ip_server", "192.168.5.6")
val url = "http://" + ipServer + "/pin/check" // /pin$pin"
val client = OkHttpClient()
val request = okhttp3.Request.Builder()
.url(url)
.get()
//.addHeader("Content-Type", "application/json")
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
}
@Throws(IOException::class)
override fun onResponse(call: Call, response: Response) {
val networkResp = response.body()!!.string()
this@MainActivity.runOnUiThread { Toast.makeText(this@MainActivity, networkResp, Toast.LENGTH_LONG).show() }
}
})
}
}
package it.lavermicocca.giacomo.beautifulnotification
import android.annotation.TargetApi
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.media.RingtoneManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.preference.ListPreference
import android.preference.Preference
import android.preference.PreferenceActivity
import android.preference.PreferenceFragment
import android.preference.PreferenceManager
import android.preference.RingtonePreference
import android.text.TextUtils
import android.view.MenuItem
/**
* A [PreferenceActivity] that presents a set of application settings. On
* handset devices, settings are presented as a single list. On tablets,
* settings are split by category, with category headers shown to the left of
* the list of settings.
*
* See [Android Design: Settings](http://developer.android.com/design/patterns/settings.html)
* for design guidelines and the [Settings API Guide](http://developer.android.com/guide/topics/ui/settings.html)
* for more information on developing a Settings UI.
*/
class SettingsActivity : AppCompatPreferenceActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setupActionBar()
}
/**
* Set up the [android.app.ActionBar], if the API is available.
*/
private fun setupActionBar() {
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
/**
* {@inheritDoc}
*/
override fun onIsMultiPane(): Boolean {
return isXLargeTablet(this)
}
/**
* {@inheritDoc}
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
override fun onBuildHeaders(target: List<PreferenceActivity.Header>) {
loadHeadersFromResource(R.xml.pref_headers, target)
}
/**
* This method stops fragment injection in malicious applications.
* Make sure to deny any unknown fragments here.
*/
override fun isValidFragment(fragmentName: String): Boolean {
return PreferenceFragment::class.java.name == fragmentName
|| GeneralPreferenceFragment::class.java.name == fragmentName
|| DataSyncPreferenceFragment::class.java.name == fragmentName
|| NotificationPreferenceFragment::class.java.name == fragmentName
}
/**
* This fragment shows general preferences only. It is used when the
* activity is showing a two-pane settings UI.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
class GeneralPreferenceFragment : PreferenceFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
getPreferenceManager().setSharedPreferencesName("myPref")
addPreferencesFromResource(R.xml.pref_general)
setHasOptionsMenu(true)
// Bind the summaries of EditText/List/Dialog/Ringtone preferences
// to their values. When their values change, their summaries are
// updated to reflect the new value, per the Android Design
// guidelines.
bindPreferenceSummaryToValue(findPreference("ip_server"))
bindPreferenceSummaryToValue(findPreference("example_list"))
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId
if (id == android.R.id.home) {
startActivity(Intent(activity, SettingsActivity::class.java))
return true
}
return super.onOptionsItemSelected(item)
}
}
/**
* This fragment shows notification preferences only. It is used when the
* activity is showing a two-pane settings UI.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
class NotificationPreferenceFragment : PreferenceFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
getPreferenceManager().setSharedPreferencesName("myPref");
addPreferencesFromResource(R.xml.pref_notification)
setHasOptionsMenu(true)
// Bind the summaries of EditText/List/Dialog/Ringtone preferences
// to their values. When their values change, their summaries are
// updated to reflect the new value, per the Android Design
// guidelines.
bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone"))
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId
if (id == android.R.id.home) {
startActivity(Intent(activity, SettingsActivity::class.java))
return true
}
return super.onOptionsItemSelected(item)
}
}
/**
* This fragment shows data and sync preferences only. It is used when the
* activity is showing a two-pane settings UI.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
class DataSyncPreferenceFragment : PreferenceFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
getPreferenceManager().setSharedPreferencesName("myPref");
addPreferencesFromResource(R.xml.pref_data_sync)
setHasOptionsMenu(true)
// Bind the summaries of EditText/List/Dialog/Ringtone preferences
// to their values. When their values change, their summaries are
// updated to reflect the new value, per the Android Design
// guidelines.
bindPreferenceSummaryToValue(findPreference("sync_frequency"))
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId
if (id == android.R.id.home) {
startActivity(Intent(activity, SettingsActivity::class.java))
return true
}
return super.onOptionsItemSelected(item)
}
}
companion object {
/**
* A preference value change listener that updates the preference's summary
* to reflect its new value.
*/
private val sBindPreferenceSummaryToValueListener = Preference.OnPreferenceChangeListener { preference, value ->
val stringValue = value.toString()
if (preference is ListPreference) {
// For list preferences, look up the correct display value in
// the preference's 'entries' list.
val listPreference = preference
val index = listPreference.findIndexOfValue(stringValue)
// Set the summary to reflect the new value.
preference.setSummary(
if (index >= 0)
listPreference.entries[index]
else
null)
} else if (preference is RingtonePreference) {
// For ringtone preferences, look up the correct display value
// using RingtoneManager.
if (TextUtils.isEmpty(stringValue)) {
// Empty values correspond to 'silent' (no ringtone).
preference.setSummary(R.string.pref_ringtone_silent)
} else {
val ringtone = RingtoneManager.getRingtone(
preference.getContext(), Uri.parse(stringValue))
if (ringtone == null) {
// Clear the summary if there was a lookup error.
preference.setSummary(null)
} else {
// Set the summary to reflect the new ringtone display
// name.
val name = ringtone.getTitle(preference.getContext())
preference.setSummary(name)
}
}
} else {
// For all other preferences, set the summary to the value's
// simple string representation.
preference.summary = stringValue
}
true
}
/**
* Helper method to determine if the device has an extra-large screen. For
* example, 10" tablets are extra-large.
*/
private fun isXLargeTablet(context: Context): Boolean {
return context.resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK >= Configuration.SCREENLAYOUT_SIZE_XLARGE
}
/**
* Binds a preference's summary to its value. More specifically, when the
* preference's value is changed, its summary (line of text below the
* preference title) is updated to reflect the value. The summary is also
* immediately updated upon calling this method. The exact display format is
* dependent on the type of preference.
* @see .sBindPreferenceSummaryToValueListener
*/
private fun bindPreferenceSummaryToValue(preference: Preference) {
// Set the listener to watch for value changes.
preference.onPreferenceChangeListener = sBindPreferenceSummaryToValueListener
// Trigger the listener immediately with the preference's
// current value.
sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
PreferenceManager
.getDefaultSharedPreferences(preference.context)
.getString(preference.key, ""))
}
}
}
package it.lavermicocca.giacomo.beautifulnotification;
package it.lavermicocca.giacomo.beautifulnotification.notifications;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.RemoteViews;
public class MainActivity extends AppCompatActivity {
import it.lavermicocca.giacomo.beautifulnotification.MainActivity;
import it.lavermicocca.giacomo.beautifulnotification.R;
/**
* Created by giacomo on 12/05/18.
*/
public class GenericNotification {
private static final String CHANNEL_ID = "media_playback_channel";
private void startNotification(){
public static void startNotification(Service service){
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager notificationManager = (NotificationManager) getSystemService(ns);
NotificationManager notificationManager = (NotificationManager) service.getSystemService(ns);
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID)
NotificationCompat.Builder builder = new NotificationCompat.Builder(service.getApplicationContext(), CHANNEL_ID)
.setContentTitle("TITLE")
.setContentText("BODY")
.setSmallIcon(R.drawable.ic_stat_notification)
......@@ -30,12 +34,12 @@ public class MainActivity extends AppCompatActivity {
.setTicker("Ticker TEXT");
Notification notification = builder.build();
RemoteViews notificationView = new RemoteViews(getPackageName(),
RemoteViews notificationView = new RemoteViews(service.getPackageName(),
R.layout.mynotification);
//the intent that is started when the notification is clicked (works)
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(this, 0,
Intent notificationIntent = new Intent(service, MainActivity.class);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(service, 0,
notificationIntent, 0);
notification.contentView = notificationView;
......@@ -45,8 +49,8 @@ public class MainActivity extends AppCompatActivity {
//this is the intent that is supposed to be called when the
//button is clicked
Intent switchIntent = new Intent(this, switchButtonListener.class);
PendingIntent pendingSwitchIntent = PendingIntent.getBroadcast(this, 0, switchIntent, 0);
Intent switchIntent = new Intent(service, MainActivity.switchButtonListener.class);
PendingIntent pendingSwitchIntent = PendingIntent.getBroadcast(service, 0, switchIntent, 0);
// Intent intent = new Intent(getApplicationContext(), MainActivity.class);
// PendingIntent pendingSwitchIntent = PendingIntent.getActivity(this, 0, intent, 0);
......@@ -60,24 +64,6 @@ public class MainActivity extends AppCompatActivity {
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(1, notification);
}
public static class switchButtonListener extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("Here", "I am here");
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startNotification();
service.startForeground(1, notification);
}
}
package com.example.android.customnotifications.receivers;
package it.lavermicocca.giacomo.beautifulnotification.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
......@@ -7,7 +7,7 @@ import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;
import com.example.android.customnotifications.services.Helper;
import it.lavermicocca.giacomo.beautifulnotification.services.Helper;
/**
* Created by giacomo on 12/05/18.
......
package com.example.android.customnotifications.services;
package it.lavermicocca.giacomo.beautifulnotification.services;
import android.content.Context;
import android.content.Intent;
......
package com.example.android.customnotifications.services;
package it.lavermicocca.giacomo.beautifulnotification.services;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import it.lavermicocca.giacomo.beautifulnotification.notifications.GenericNotification;
/**
* Created by giacomo on 12/05/18.
*/
......@@ -29,6 +31,7 @@ public class NotificationService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
GenericNotification.startNotification(this);
return START_STICKY;