Prima versione usabile

This commit is contained in:
gine 2015-04-09 20:31:32 +02:00
parent c0e928c872
commit 52b4f99512
51 changed files with 9554 additions and 1 deletions

38
AndroidManifest.xml Normal file
View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.indivia.hacklabbo.statusreader"
android:versionCode="1"
android:versionName="1.0" >
<!-- check per la rete -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<!-- accedere alla rete -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- scrivere su sd (download) -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="22" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<service android:name=".Downloader" />
<service android:name=".CheckUpdate" />
<service android:name=".StatusUpdate" />
<activity
android:name="net.indivia.hacklabbo.statusreader.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="net.indivia.hacklabbo.statusreader.PrefScreen" />
</application>
</manifest>

View file

@ -1,4 +1,14 @@
StatusReader
============
Aggiorna lo stato dell'Activity leggendo un file in formato JSON.
Aggiorna lo stato dell'Activity leggendo un file in formato JSON da una pagina web con il seguente formato:
<pre>
{"open":true,"date":"2015-04-03T00:43:18+02:00"}
</pre>
Sono settabili:
- Da quale url deve essere preso il file JSON
- Se l'applicazione deve aggiornare lo stato in background
- Ogni quanto tempo il servizio in background deve verificare il cambiamento di stato
- Se l'applicazione deve informare all'avvio che ci sono degli aggiornamenti di se stessa

38
bin/AndroidManifest.xml Normal file
View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.indivia.hacklabbo.statusreader"
android:versionCode="1"
android:versionName="1.0" >
<!-- check per la rete -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<!-- accedere alla rete -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- scrivere su sd (download) -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="22" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<service android:name=".Downloader" />
<service android:name=".CheckUpdate" />
<service android:name=".StatusUpdate" />
<activity
android:name="net.indivia.hacklabbo.statusreader.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="net.indivia.hacklabbo.statusreader.PrefScreen" />
</application>
</manifest>

1020
bin/R.txt Normal file

File diff suppressed because it is too large Load diff

BIN
bin/StatusReader.apk Normal file

Binary file not shown.

BIN
bin/classes.dex Normal file

Binary file not shown.

5
bin/jarlist.cache Normal file
View file

@ -0,0 +1,5 @@
# cache for current jar dependency. DO NOT EDIT.
# format is <lastModified> <length> <SHA-1> <path>
# Encoding is UTF-8
1427838941000 1074044 33b27a8d2a5b87e6eb6c60e87a5374ffbfeacc3a /weight/Code/appcompat_v7/libs/android-support-v4.jar
1427839433000 1074044 33b27a8d2a5b87e6eb6c60e87a5374ffbfeacc3a /weight/Code/StatusReader/libs/android-support-v4.jar

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
bin/resources.ap_ Normal file

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,6 @@
/** Automatically generated file. DO NOT MODIFY */
package net.indivia.hacklabbo.statusreader;
public final class BuildConfig {
public final static boolean DEBUG = true;
}

File diff suppressed because it is too large Load diff

BIN
ic_launcher-web.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

20
proguard-project.txt Normal file
View file

@ -0,0 +1,20 @@
# To enable ProGuard in your project, edit project.properties
# to define the proguard.config property as described in that file.
#
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in ${sdk.dir}/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

15
project.properties Normal file
View file

@ -0,0 +1,15 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-22
android.library.reference.1=../appcompat_v7

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
res/drawable-hdpi/software.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View file

@ -0,0 +1,98 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical" >
<ImageButton
android:id="@+id/status_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="#ffffff"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:longClickable="false"
android:paddingTop="5dp"
android:scaleType="center"
android:src="@drawable/red_btn" />
<TextView
android:id="@+id/server_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingTop="2dp"
android:text="Server:"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="italic" />
<TextView
android:id="@+id/server_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:text="http://isopen.hacklabbo.indivia.net/hacklabbo/state.json"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/status_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingTop="2dp"
android:text="Status:"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="italic" />
<TextView
android:id="@+id/status_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:text="@string/close"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/last_status_change_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingTop="2dp"
android:text="Last Change:"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="italic" />
<TextView
android:id="@+id/last_status_change_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:text="@string/mai"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/last_refresh_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingTop="2dp"
android:text="Last Refresh:"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textStyle="italic" />
<TextView
android:id="@+id/last_refresh_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:text="@string/mai"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>

19
res/menu/main.xml Normal file
View file

@ -0,0 +1,19 @@
<menu 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"
tools:context="net.indivia.hacklabbo.statusreader.MainActivity" >
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="@string/menu_action_settings"
android:icon="@drawable/ic_menu_settings"
app:showAsAction="never"/>
<item
android:id="@+id/action_refresh"
android:orderInCategory="99"
android:icon="@drawable/ic_menu_refresh"
android:title="@string/menu_action_refresh"
app:showAsAction="never"/>
</menu>

11
res/values-v11/styles.xml Normal file
View file

@ -0,0 +1,11 @@
<resources>
<!--
Base application theme for API 11+. This theme completely replaces
AppBaseTheme from res/values/styles.xml on API 11+ devices.
-->
<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
<!-- API 11 theme customizations can go here. -->
</style>
</resources>

12
res/values-v14/styles.xml Normal file
View file

@ -0,0 +1,12 @@
<resources>
<!--
Base application theme for API 14+. This theme completely replaces
AppBaseTheme from BOTH res/values/styles.xml and
res/values-v11/styles.xml on API 14+ devices.
-->
<style name="AppBaseTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- API 14 theme customizations can go here. -->
</style>
</resources>

View file

@ -0,0 +1,10 @@
<resources>
<!--
Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively).
-->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>

7
res/values/dimens.xml Normal file
View file

@ -0,0 +1,7 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>

12
res/values/keys.xml Normal file
View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="key_refresh_service">service</string>
<string name="key_refresh_status_time">refresh_time</string>
<string name="key_server_name">server_name</string>
<string name="key_states">states</string>
<string name="key_status">status</string>
<string name="key_last_refresh">last_refresh</string>
<string name="key_status_changed">status_changed</string>
<string name="key_update_service">update</string>
</resources>

21
res/values/prefs.xml Executable file
View file

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="prefs_refresh_category">Refresh</string>
<string name="prefs_refresh_service_title">Refresh automatico</string>
<string name="prefs_refresh_service_summary">Aggiornamento dello status mediante service in background</string>
<string name="prefs_refresh_status_time_title">Refresh time</string>
<string name="prefs_refresh_status_time_dialogTitle">Scegli un intervallo:</string>
<string name="prefs_refresh_status_time_summary">Tempo di attesa per il refresh dello status</string>
<string name="prefs_app_category">Applicazione</string>
<string name="prefs_server_name_title">Server Name</string>
<string name="prefs_server_name_summary">Url dal quale fare il GET dello status</string>
<string name="prefs_update_title">Update Service</string>
<string name="prefs_update_summary">All\'avvio vengono verificati se ci sono aggiornamenti per l\'applicazione</string>
</resources>

17
res/values/prefs_arrays.xml Executable file
View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="prefs_refresh_time">
<item>3 minuti</item>
<item>5 minuti</item>
<item>10 minuti</item>
<item>15 minuti</item>
<item>30 minuti</item>
</string-array>
<string-array name="prefs_refresh_time_value">
<item>180</item>
<item>300</item>
<item>600</item>
<item>900</item>
<item>2400</item>
</string-array>
</resources>

11
res/values/strings.xml Normal file
View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">StatusReader</string>
<string name="open">Open</string>
<string name="close">Close</string>
<string name="mai">Mai</string>
<string name="menu_action_settings">Settings</string>
<string name="menu_action_refresh">Refresh</string>
<string name="app_update_notify_title">Aggiornamento</string>
<string name="app_update_new_version">Nuova versione di StatusReader</string>
</resources>

20
res/values/styles.xml Normal file
View file

@ -0,0 +1,20 @@
<resources>
<!--
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
</resources>

38
res/xml/prefs.xml Executable file
View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/prefs_refresh_category">
<CheckBoxPreference
android:title="@string/prefs_refresh_service_title"
android:key="@string/key_refresh_service"
android:persistent="true"
android:summary="@string/prefs_refresh_service_summary"
/>
<ListPreference
android:entryValues="@array/prefs_refresh_time_value"
android:persistent="true"
android:entries="@array/prefs_refresh_time"
android:title="@string/prefs_refresh_status_time_title"
android:dialogTitle="@string/prefs_refresh_status_time_dialogTitle"
android:key="@string/key_refresh_status_time"
android:summary="@string/prefs_refresh_status_time_summary"
android:dependency="service"
android:defaultValue="600"
/>
</PreferenceCategory>
<PreferenceCategory android:title="@string/prefs_app_category">
<EditTextPreference
android:title="@string/prefs_server_name_title"
android:summary="@string/prefs_server_name_summary"
android:key="@string/key_server_name"
android:persistent="true"
android:defaultValue="isopen.hacklabbo.indivia.net/hacklabbo/state.json"
/>
<CheckBoxPreference
android:title="@string/prefs_update_title"
android:key="@string/key_update_service"
android:persistent="true"
android:summary="@string/prefs_update_summary"
/>
</PreferenceCategory>
</PreferenceScreen>

View file

@ -0,0 +1,145 @@
package net.indivia.hacklabbo.statusreader;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Build;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
@SuppressLint("NewApi")
public class CheckUpdate extends Service {
/*private final static String app_site = "http://isopen.hacklabbo.indivia.net/";*/
private final static String LOG_TAG = "CheckUpdate";
private final static String app_apk = "net.indivia.hacklabbo.statusreader";
private final static String app_site = "http://ginex.indivia.net/";
private final static String app_www_current_apk = "latest.apk";
private final static String app_www_current_version = "update.json";
//DEBUG:
private final static String app_www_current_version_fail = "update-fail.json";
private final static String app_www_current_version_true = "update-true.json";
public final static int NOTIFY_APP_UPDATE = 2;
private BgThread bgThread;
private NotificationManager notificationManager;
private Notification notification;
private PendingIntent pIntent;
private int notificationNumber;
private Resources res;
@Override
public void onCreate() {
super.onCreate();
res = getResources();
bgThread = new BgThread();
bgThread.start();
Intent intent = new Intent(this, Downloader.class);
String app_uri = app_site + app_www_current_apk;
intent.putExtra("checkUpdate", NOTIFY_APP_UPDATE);
intent.setData(Uri.parse(app_uri));
intent.putExtra("urlpath", app_uri);
pIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT );
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
notifyBuilder();
else
getNotify();
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
Log.i(LOG_TAG, "Service Created");
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void notifyBuilder(){
notification = new Notification.Builder(this)
.setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
.setContentTitle(getString(R.string.app_update_notify_title))
.setContentText(getString(R.string.app_update_new_version))
.setLights(0xFFFF0000, 500, 500)
.setSmallIcon(R.drawable.software)
.setContentIntent(pIntent)
.build();
}
@SuppressWarnings("deprecation")
public void getNotify(){
notification = new Notification(
R.drawable.software,
getString(R.string.app_update_notify_title),
System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
}
@SuppressWarnings("deprecation")
public void sendNotification(int newVersion) {
notification.number=++notificationNumber;
notification.setLatestEventInfo (this,
res.getString(R.string.app_update_notify_title),
res.getString(R.string.app_update_new_version),
pIntent);
notificationManager.notify(NOTIFY_APP_UPDATE, notification);
}
private final class BgThread extends Thread {
public void run() {
try {
//String json = SNetwork.GET(app_site + app_www_current_version);
String json = SNetwork.GET(app_site + app_www_current_version_true);
JSONObject jObject = new JSONObject(json);
int newVersion = jObject.getInt("version");
int curVersion = getPackageManager().getPackageInfo(app_apk, 0).versionCode;
//Log.d(LOG_TAG,"cur:"+curVersion+" new:"+newVersion);
if (newVersion > curVersion){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
notificationManager.notify(0, notification);
else
sendNotification(newVersion);
}
} catch (Exception e) {
e.printStackTrace();
}
stopSelf();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(LOG_TAG, "Service Started");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(LOG_TAG, "Service Destroyed");
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}

View file

@ -0,0 +1,97 @@
package net.indivia.hacklabbo.statusreader;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.app.IntentService;
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Message;
import android.os.Messenger;
import android.util.Log;
public class Downloader extends IntentService {
private static final String LOG_TAG = "Downloader";
public static final int UPDATE_PROGRESS = 8344;
private int resultDownload = Activity.RESULT_CANCELED;
private File file;
public ProgressDialog mProgressDialog;
public Downloader() {
super(LOG_TAG);
}
public void sendNotification(Intent i) {
Bundle extras = i.getExtras();
if (extras != null) {
Messenger messenger = (Messenger) extras.get("messenger");
Message msg = Message.obtain();
msg.arg1 = resultDownload;
msg.obj = file.getAbsolutePath();
try {
messenger.send(msg);
} catch (android.os.RemoteException e1) {
Log.w(getClass().getName(), "Exception sending message", e1);
}
}
}
@Override
protected void onHandleIntent(Intent intent) {
try {
Log.d(LOG_TAG, "onHandIntent");
int cu = intent.getIntExtra("checkUpdate", 0);
String urlfile = intent.getStringExtra("urlpath");
URL url = new URL(urlfile);
file = SUtility.getFile(urlfile,"");
if (cu != CheckUpdate.NOTIFY_APP_UPDATE){
Log.d(LOG_TAG,"file exist & cu != 2 - STOP");
resultDownload = Activity.RESULT_FIRST_USER;
sendNotification(intent);
} else {
if (file.exists()) {
file.delete();
}
URLConnection c = (HttpURLConnection) url.openConnection();
c.connect();
InputStream input = new BufferedInputStream(c.getInputStream());
OutputStream output = new FileOutputStream(file);
byte data[] = new byte[1024];
int count;
while ((count = input.read(data)) != -1) {
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
Intent i = new Intent(Intent.ACTION_VIEW);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
startActivity(i);
}
} catch (IOException e) {
e.getStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(LOG_TAG, "Service Destroyed");
}
}

View file

@ -0,0 +1,130 @@
package net.indivia.hacklabbo.statusreader;
import android.support.v7.app.ActionBarActivity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageButton;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity {
private static final String LOG_TAG = "MainActivity";
private SharedPreferences prefs;
public final static int
MENU_SETTINGS_ID = 10,
MENU_REFRESH_ID = 11;
private static ImageButton ibStatusBtn;
private static TextView
tvStatusValue,tvServerValue,tvLastRefreshValue,tvLastStatusValue;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
ibStatusBtn = (ImageButton) findViewById(R.id.status_btn);
tvStatusValue = (TextView) findViewById(R.id.status_value);
tvServerValue = (TextView) findViewById(R.id.server_value);
tvLastRefreshValue = (TextView) findViewById(R.id.last_refresh_value);
tvLastStatusValue = (TextView) findViewById(R.id.last_status_change_value);
}
@Override
protected void onResume(){
super.onResume();
LoadPreferences();
}
private void LoadPreferences(){
//le preferenze relative ai servizi
Boolean refresh_service =prefs.getBoolean(getString(R.string.key_refresh_service), false);
Boolean update_service = prefs.getBoolean("update", false);
//setto il display
setDisplay(null,null,null);
//avvio il service che verifica se ci sono update del software
if (update_service)
startService(new Intent(this, CheckUpdate.class));
//avvio il service che verifica se ci sono update dello stato
//TODO: se il service è già avviato?
if (refresh_service)
startService(setUpdateStatusIntent(true));
}
public Intent setUpdateStatusIntent(Boolean isCicleService){
Intent intent = new Intent(this, StatusUpdate.class);
String serverName = prefs.getString(getString(R.string.key_server_name), StatusUpdate.DEF_SITE);
int refresh_time = Integer.parseInt(prefs.getString(getString(R.string.key_refresh_status_time), "600"));
intent.putExtra("serverName", serverName);
SharedPreferences states = getApplicationContext().getSharedPreferences(getString(R.string.key_states), 0);
Boolean oldStatus = states.getBoolean(getString(R.string.key_status), false);
intent.putExtra("oldStatus", oldStatus);
intent.putExtra("isCicleService", isCicleService);
if(isCicleService)
intent.putExtra("refreshTime", refresh_time);
return intent;
}
public void setDisplay(Boolean status, String last_refresh, String status_changed){
String serverName = prefs.getString(getString(R.string.key_server_name), StatusUpdate.DEF_SITE);
SharedPreferences states = getApplicationContext().getSharedPreferences(getString(R.string.key_states), 0);
String mai = getString(R.string.key_status_changed);
if(status == null)
status = states.getBoolean(getString(R.string.key_status), false);
if(last_refresh == null)
last_refresh = states.getString(getString(R.string.key_last_refresh), mai);
if(status_changed == null)
status_changed = states.getString(getString(R.string.key_status_changed), mai);
int statusImg = R.drawable.red_btn,
statusValue = R.string.close;
if(status){
statusImg = R.drawable.green_btn;
statusValue = R.string.open;
}
ibStatusBtn.setImageResource(statusImg);
tvStatusValue.setText(statusValue);
tvLastRefreshValue.setText(last_refresh);
tvLastStatusValue.setText(status_changed);
tvServerValue.setText(serverName);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
startActivity(new Intent(this, PrefScreen.class));
} else if( id== R.id.action_refresh){
startService(setUpdateStatusIntent(false));
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onStop() {
super.onStop();
}
}

View file

@ -0,0 +1,67 @@
package net.indivia.hacklabbo.statusreader;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.net.Uri;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
public class PrefScreen extends PreferenceActivity {
private static final String LOG_TAG = "PreferenceScreenActivity";
private static String
SPREF_KEY_SERV,
SPREF_KEY_REFRESH,
SPREF_KEY_UPDATE;
private static Context ctx;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
extracted();
ctx = getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
prefs.registerOnSharedPreferenceChangeListener(mListener);
/*SPREF_KEY_SERV = getString(R.string.key_refresh_service);
SPREF_KEY_REFRESH = getString(R.string.key_refresh_time);
SPREF_KEY_UPDATE = getString(R.string.key_update_service);*/
}
private void extracted() {
addPreferencesFromResource(R.xml.prefs);
}
public OnSharedPreferenceChangeListener mListener = new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
boolean preference;
Log.d(LOG_TAG, "onSharedPrefCh(): "+key);
/*if (key.equalsIgnoreCase(SPREF_KEY_SERV)){
preference = sharedPreferences.getBoolean(SPREF_KEY_SERV, false);
if(preference){
startService(ATab.feedBurnI);
} else {
stopService(ATab.feedBurnI);
}
} else if (key.equalsIgnoreCase(SPREF_KEY_REFRESH)) {
stopService(ATab.feedBurnI);
startService(ATab.feedBurnI);
}*/
/*preference = sharedPreferences.getBoolean(SPREF_KEY_UPDATE, true);
if (preference){
Intent iUpdate = new Intent(ctx,CheckUpdate.class);
startService(iUpdate);
}*/
}
};
}

View file

@ -0,0 +1,99 @@
package net.indivia.hacklabbo.statusreader;
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.ProtocolException;
import java.net.URL;
import android.annotation.TargetApi;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.StrictMode;
import android.util.Log;
public class SNetwork {
public static final String LOG_TAG = "SNetwork";
public static boolean isConnected(ConnectivityManager cm) {
boolean connected = false;
if (cm != null) {
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
for (NetworkInfo ni : netInfo) {
Log.d(LOG_TAG, "type:"+ni.getTypeName()+" conn:"+ni.isConnected()
+" avv:"+ni.isAvailable() );
if ((ni.getTypeName().equalsIgnoreCase("WIFI") ||
ni.getTypeName().equalsIgnoreCase("MOBILE"))
&& ni.isConnected() && ni.isAvailable()){
connected = true;
break;
}
}
}
return connected;
}
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public static String GET(String uri){
String result = "";
HttpURLConnection con;
try {
con = (HttpURLConnection) ( new URL(uri)).openConnection();
try {
con.setRequestMethod("GET");
con.setDoOutput(false);
try {
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
con.connect();
InputStream is = con.getInputStream();
if(is != null)
result = convertInputStreamToString(is);
else
result = "Did not work!";
con.disconnect();
} catch (IOException e) {
Log.d(LOG_TAG,"no json");
result = "Il file json non esiste";
e.printStackTrace();
}
} catch (ProtocolException e1) {
Log.d(LOG_TAG,"protocoll");
e1.printStackTrace();
}
} catch (MalformedURLException e2) {
Log.d(LOG_TAG,"mal url");
result = "Manca il protocollo";
e2.printStackTrace();
} catch (IOException e2) {
Log.d(LOG_TAG,"IO 2");
e2.printStackTrace();
}
return result;
}
private static String convertInputStreamToString(InputStream inputStream) throws IOException{
String line = "", result = "";
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream));
while((line = bufferedReader.readLine()) != null)
result += line;
inputStream.close();
return result;
}
}

View file

@ -0,0 +1,54 @@
package net.indivia.hacklabbo.statusreader;
import java.io.File;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
public class SUtility {
public static final String LOG_TAG = "SUtility";
@SuppressLint("NewApi")
public static void saveState(Context ctx, Boolean status, String last_refresh, String status_change){
Resources res = ctx.getResources();
//storing
SharedPreferences states = ctx.getApplicationContext().getSharedPreferences(res.getString(R.string.key_states), 0);
SharedPreferences.Editor editor = states.edit();
editor.putBoolean(res.getString(R.string.key_status), status);
editor.putString(res.getString(R.string.key_last_refresh), last_refresh);
editor.putString(res.getString(R.string.key_status_changed), status_change);
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO)
editor.apply();
else
commitShared(editor);
}
@TargetApi(Build.VERSION_CODES.FROYO)
private static void commitShared(SharedPreferences.Editor editor){
editor.commit();
}
public static File getFile(String url, String reldir) {
final String ADIR = "/StatusReader/" ;
File file, apath;
String[] fileUrlParts = url.split("/");
apath = new File(Environment.getExternalStorageDirectory()+ ADIR + reldir);
if (! apath.exists()){
apath.mkdirs();
}
file = new File(apath.toString()+ "/" + fileUrlParts[fileUrlParts.length-1]);
Log.d(LOG_TAG,"external storage state:"+Environment.getExternalStorageState());
return file;
}
}

View file

@ -0,0 +1,184 @@
package net.indivia.hacklabbo.statusreader;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import org.json.JSONException;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Build;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Log;
@SuppressLint("NewApi")
public class StatusUpdate extends Service {
// private final static String app_site =
// "http://isopen.hacklabbo.indivia.net/";
private final static String app_site = "http://ginex.indivia.net/";
private final static String LOG_TAG = "StatusUpdate";
// public final static String DEF_SITE =
// "http://isopen.hacklabbo.indivia.net/hacklabbo/state.json";
public final static String DEF_SITE = "http://ginex.indivia.net/state.json";
private final static String app_www_current_apk = "latest.apk";
public final static int NOTIFY_APP_UPDATE = 2;
private BgThread bgThread;
private NotificationManager notificationManager;
private Notification notification;
private PendingIntent pIntent;
private int notificationNumber;
private Resources res;
private static String serverName;
private static Boolean oldStatus, isCicleService;
private static int refreshTime;
private ConnectivityManager cm;
@Override
public void onCreate() {
super.onCreate();
res = getResources();
cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
bgThread = new BgThread();
bgThread.start();
String app_uri = app_site + app_www_current_apk;
Intent i = new Intent(this, MainActivity.class);
i.putExtra("checkUpdate", NOTIFY_APP_UPDATE);
i.setData(Uri.parse(app_uri));
i.putExtra("urlpath", app_uri);
pIntent = PendingIntent.getActivity(this, 0, i,
PendingIntent.FLAG_UPDATE_CURRENT);
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Log.i(LOG_TAG, "Service Created");
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void notifyBuilder(String status) {
notification = new Notification.Builder(this)
.setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
// .setContentTitle(getString(R.string.app_update_notify_title))
.setContentTitle("StatusReader: cambio di stato")
.setContentText("Stato cambiato a: " + status)
.setLights(0xFFFF0000, 500, 500)
// TODO: cambiare l'icona
.setSmallIcon(R.drawable.software).setContentIntent(pIntent)
.setAutoCancel(true).build();
}
// TODO: cambiare titolo icone
@SuppressWarnings("deprecation")
public void getNotify() {
notification = new Notification(R.drawable.software,
getString(R.string.app_update_notify_title),
System.currentTimeMillis());
notification.flags |= Notification.FLAG_AUTO_CANCEL;
}
@SuppressWarnings("deprecation")
public void sendNotification(int newVersion) {
notification.number = ++notificationNumber;
notification.setLatestEventInfo(this,
res.getString(R.string.app_update_notify_title),
res.getString(R.string.app_update_new_version), pIntent);
notificationManager.notify(NOTIFY_APP_UPDATE, notification);
}
private final class BgThread extends Thread {
public void run() {
do {
if (SNetwork.isConnected(cm)) {
Log.i(LOG_TAG, "Service Cicle");
String json = SNetwork.GET(serverName);
try {
JSONObject jObject = new JSONObject(json);
boolean newStatus = jObject.getBoolean("open");
String statusChange = jObject.getString("date");
Calendar c = Calendar.getInstance();
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ssZZZZZ", Locale.ITALY);
String last_refresh = dateFormat.format(c.getTime());
if (newStatus != oldStatus) {
String status = res.getString(R.string.close);
if (newStatus)
status = res.getString(R.string.open);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
notifyBuilder(status);
notificationManager.notify(0, notification);
} else {
getNotify();
sendNotification(1);
}
}
SUtility.saveState(getApplicationContext(), newStatus,
last_refresh, statusChange);
if (!isCicleService) {
stopSelf();
Log.i(LOG_TAG, "Service stop");
// setDisplay(newStatus, last_refresh, statusChange);
}
try {
Thread.sleep(refreshTime);
} catch (InterruptedException ie) {
Log.d(LOG_TAG,
"Qualcosa è andato storto con il timer.\n"
+ ie.toString());
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.d(LOG_TAG, "Non c'è connessione");
}
} while (isCicleService);
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
isCicleService = intent.getBooleanExtra("isCicleService", false);
if (isCicleService)
refreshTime = intent.getIntExtra("refreshTime", 0);
serverName = intent.getStringExtra("serverName");
oldStatus = intent.getBooleanExtra("oldStatus", false);
Log.i(LOG_TAG, "Service Started");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(LOG_TAG, "Service Destroyed");
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}