Java tutorial
package de.mangelow.throughput; /*** * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; import org.apache.http.conn.util.InetAddressUtils; import android.app.Notification; import android.app.ActivityManager.RunningAppProcessInfo; import android.app.Notification.Builder; import android.app.ActivityManager; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.TrafficStats; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.ResultReceiver; import android.provider.Settings; import android.telephony.NeighboringCellInfo; import android.telephony.PhoneStateListener; import android.telephony.SignalStrength; import android.telephony.TelephonyManager; import android.util.Log; public class NotificationService extends Service { private final String TAG = "TP"; private final boolean D = false; private Context context; private Resources res; private Handler handler; private Builder nb; public static int NOTIFICATION_ID = 347893278; private TelephonyManager tmanager; private WifiManager wmanager; private ActivityManager amanager; private PackageManager pmanager; private String last_connection = null; private int signalstrength = -1; private long last_rx = TrafficStats.getTotalRxBytes(); private long last_tx = TrafficStats.getTotalTxBytes(); private HashMap<String, Long> hm_app_last_rx = new HashMap<String, Long>(); private HashMap<String, Long> hm_app_last_tx = new HashMap<String, Long>(); private boolean screenOff = false; private int MAX_CHAR = 18; private ResultReceiver mResultReceiver; @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent != null) mResultReceiver = intent.getParcelableExtra("receiver"); return START_STICKY; } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); if (D) Log.d(TAG, "Service started"); context = getApplicationContext(); res = context.getResources(); if (tmanager == null) { tmanager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); tmanager.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); } IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_SCREEN_OFF); registerReceiver(mBroadcastReceiver, filter); int[] refresh_values = res.getIntArray(R.array.refresh_values); long refresh = (long) refresh_values[MainActivity.loadIntPref(context, MainActivity.REFRESH, MainActivity.REFRESH_DEFAULT)]; modifyNotification(R.drawable.ic_stat_zero, null, "", "", new Intent()); if (handler == null) { handler = new Handler(); handler.postDelayed(mRunnable, refresh); } } @Override public void onDestroy() { if (D) Log.d(TAG, "Service stopped"); if (tmanager != null) { tmanager.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_NONE); tmanager = null; } if (handler != null) handler = null; if (mBroadcastReceiver != null) { unregisterReceiver(mBroadcastReceiver); mBroadcastReceiver = null; } removeNotification(); } private final Runnable mRunnable = new Runnable() { public void run() { int drawable = R.drawable.ic_stat_zero; String ticker = null; String title = ""; String subtitle = ""; Intent i = new Intent(); // int procent = -1; String quality_string = ""; String subtype = ""; String ipaddress = ""; // boolean enabled = MainActivity.loadBooleanPref(context, MainActivity.ENABLED, MainActivity.ENABLED_DEFAULT); boolean showipaddress = MainActivity.loadBooleanPref(context, MainActivity.SHOWIPADDRESS, MainActivity.SHOWIPADDRESS_DEFAULT); boolean showssidsubtype = MainActivity.loadBooleanPref(context, MainActivity.SHOWSSIDSUBTYPE, MainActivity.SHOWSSIDSUBTYPE_DEFAULT); boolean showcells = MainActivity.loadBooleanPref(context, MainActivity.SHOWCELLS, MainActivity.SHOWCELLS_DEFAULT); boolean showwifilinkspeed = MainActivity.loadBooleanPref(context, MainActivity.SHOWWIFILINKSPEED, MainActivity.SHOWWIFILINKSPEED_DEFAULT); boolean showsignalstrength = MainActivity.loadBooleanPref(context, MainActivity.SHOWSIGNALSTRENGTH, MainActivity.SHOWSIGNALSTRENGTH_DEFAULT); boolean showonairplanemode = MainActivity.loadBooleanPref(context, MainActivity.SHOWONAIRPLANEMODE, MainActivity.SHOWONAIRPLANEMODE_DEFAULT); boolean showappname = MainActivity.loadBooleanPref(context, MainActivity.SHOWAPPNAME, MainActivity.SHOWAPPNAME_DEFAULT); int[] refresh_values = res.getIntArray(R.array.refresh_values); long refresh = (long) refresh_values[MainActivity.loadIntPref(context, MainActivity.REFRESH, MainActivity.REFRESH_DEFAULT)]; int ontap = MainActivity.loadIntPref(context, MainActivity.ONTAP, MainActivity.ONTAP_DEFAULT); int[] threshold_values = res.getIntArray(R.array.threshold_values); int threshold = MainActivity.loadIntPref(context, MainActivity.THRESHOLD, MainActivity.THRESHOLD_DEFAULT); if (ontap == 1) i = new Intent(context, MainActivity.class); try { if (getNetworkState(ConnectivityManager.TYPE_MOBILE)) { if (ontap == 0) { i = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS); ComponentName cName = new ComponentName("com.android.phone", "com.android.phone.Settings"); i.setComponent(cName); } List<NeighboringCellInfo> l_ncells = tmanager.getNeighboringCellInfo(); int ncells = l_ncells.size(); subtype = getNetworkSubType(); if (showipaddress) ipaddress = getIPAddress(); if (signalstrength > -1) { if (signalstrength == 99) procent = -1; final int MIN_RSSI = 0; final int MAX_RSSI = 31; int range = MAX_RSSI - MIN_RSSI; procent = 100 - ((MAX_RSSI - signalstrength) * 100 / range); if (procent > 99) procent = 100; if (procent > -1) { if (showcells) quality_string = res.getQuantityString(R.plurals.cells, ncells, ncells); if (showsignalstrength) { if (quality_string.length() > 0) quality_string += " | "; quality_string += procent + "%"; } if (showipaddress) { if (quality_string.length() > 0) quality_string += " | "; quality_string += ipaddress; } } } if (last_connection == null || !last_connection.equals(subtype)) { last_connection = subtype; if (showssidsubtype) ticker = subtype + " | "; if (quality_string.length() > 0) ticker += quality_string; } if (showssidsubtype) subtitle = subtype + " | "; if (quality_string.length() > 0) subtitle += quality_string; } else if (getNetworkState(ConnectivityManager.TYPE_WIFI)) { if (ontap == 0) i = new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK); if (wmanager == null) wmanager = (WifiManager) getSystemService(Context.WIFI_SERVICE); WifiInfo winfo = wmanager.getConnectionInfo(); subtype = winfo.getSSID(); if (subtype != null && subtype.length() > MAX_CHAR) subtype = subtype.substring(0, MAX_CHAR - 1); if (showipaddress) ipaddress = getIPAddress(); // int linkspeed = winfo.getLinkSpeed(); int rssi = wmanager.getConnectionInfo().getRssi(); final int MIN = -100; final int MAX = -55; int range = MAX - MIN; procent = 100 - ((MAX - rssi) * 100 / range); if (procent > 99) procent = 100; if (procent > -1) { if (showwifilinkspeed) quality_string = linkspeed + "Mbit"; if (showsignalstrength) { if (quality_string.length() > 0) quality_string += " | "; quality_string += procent + "%"; } if (showipaddress) { if (quality_string.length() > 0) quality_string += " | "; quality_string += ipaddress; } } // if (last_connection == null || !last_connection.equals(subtype)) { last_connection = subtype; if (showssidsubtype) ticker = subtype + " | "; if (quality_string.length() > 0) ticker += quality_string; } if (showssidsubtype) subtitle = subtype + " | "; if (quality_string.length() > 0) subtitle += quality_string; } else if (showonairplanemode && isAirplaneModeOn(context)) { drawable = R.drawable.ic_stat_apmode; title = res.getString(R.string.airplane_mode); if (ontap == 0) i = new Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS); if (last_connection == null || !last_connection.equals(subtype)) { last_connection = title; ticker = title; } } else { last_connection = null; removeNotification(); } if (last_connection != null) { long mStartRX = TrafficStats.getTotalRxBytes(); long mStartTX = TrafficStats.getTotalTxBytes(); if (mStartRX != TrafficStats.UNSUPPORTED || mStartTX != TrafficStats.UNSUPPORTED) { if (!last_connection.equals(res.getString(R.string.airplane_mode))) { boolean showbitsorbytes = MainActivity.loadBooleanPref(context, MainActivity.SHOWBITSORBYTES, MainActivity.SHOWBITSORBYTES_DEFAULT); long rxBytes = mStartRX - last_rx; last_rx = TrafficStats.getTotalRxBytes(); long in = 0; if (rxBytes < 0) in = 0; float divide = (float) refresh / 1000; try { in = (long) (rxBytes / divide); } catch (Exception e) { if (D) e.printStackTrace(); } if (in < threshold_values[threshold]) in = 0; String per = refresh + "ms"; if (divide % 1 == 0) { per = (int) divide + "s"; if (divide == 1.0f) per = "s"; } String humanreadable = humanReadableByteCount(in, showbitsorbytes); if (humanreadable.contains("-")) humanreadable = "0.0"; title = humanreadable + "/" + per + " " + res.getString(R.string.in); long txBytes = mStartTX - last_tx; last_tx = TrafficStats.getTotalTxBytes(); long out = 0; if (txBytes < 0) out = 0; divide = (float) refresh / 1000; try { out = (long) (txBytes / divide); } catch (Exception e) { if (D) e.printStackTrace(); } if (out < threshold_values[threshold]) out = 0; humanreadable = humanReadableByteCount(out, showbitsorbytes); if (humanreadable.contains("-")) humanreadable = "0.0"; title += " | " + humanreadable + "/" + per + " " + res.getString(R.string.out); if (in == 0 && out > 0) drawable = R.drawable.ic_stat_out; if (out == 0 && in > 0) drawable = R.drawable.ic_stat_in; if (in > 0 && out > 0) drawable = R.drawable.ic_stat_inout; if (in == 0 && out == 0) drawable = R.drawable.ic_stat_zero; if (showappname && in > threshold_values[threshold] || out > threshold_values[threshold]) { if (amanager == null) amanager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); if (pmanager == null) pmanager = getPackageManager(); List<RunningAppProcessInfo> runningProcesses = amanager.getRunningAppProcesses(); if (runningProcesses != null) { String appnames_string = ""; String name_in = ""; long in_last = 0; int in_count = 0; String name_out = ""; long out_last = 0; int out_count = 0; for (int j = 0; j < runningProcesses.size(); j++) { RunningAppProcessInfo ra_pi = runningProcesses.get(j); int uid = ra_pi.uid; String processname = ra_pi.processName; // if (processname.equals(context.getPackageName())) continue; if (processname.equals("android.process.acore")) continue; if (processname.equals("com.android.phone")) continue; if (processname.equals("system")) continue; if (processname.equals("com.android.settings")) continue; if (processname.equals("com.android.systemui")) continue; if (processname.equals("com.cyanogenmod.cmparts")) continue; if (processname.equals("com.google.android.gms")) continue; // long app_in = TrafficStats.getUidRxBytes(uid); long app_out = TrafficStats.getUidTxBytes(uid); String name = ""; if (app_in > 0 || app_out > 0) { try { String[] pn = processname.split("\\."); name = pn[pn.length - 1]; PackageInfo pinfo = pmanager.getPackageInfo(processname, 0); ApplicationInfo ai = pmanager.getApplicationInfo(pinfo.packageName, 0); //if((ai.flags & ApplicationInfo.FLAG_SYSTEM)!=0)continue; name = String.valueOf(pmanager.getApplicationLabel(ai)); if (name.length() > MAX_CHAR) name = name.substring(0, MAX_CHAR - 1) + "[...]"; } catch (Exception e) { //if(D)e.printStackTrace(); } } if (app_in > 0) { long app_last_rx = app_in; try { app_last_rx = hm_app_last_rx.get(processname); } catch (Exception e) { } long app_rxBytes = app_in - app_last_rx; if (app_rxBytes > threshold_values[threshold]) { in_count++; if (app_rxBytes > in_last) { name_in = name; if (D) Log.d(TAG, "in - " + processname + " - " + humanReadableByteCount(app_rxBytes, showbitsorbytes)); } } } hm_app_last_rx.put(processname, app_in); // if (app_out > 0) { long app_last_tx = app_out; try { app_last_tx = hm_app_last_tx.get(processname); } catch (Exception e) { } long app_txBytes = app_out - app_last_tx; if (app_txBytes > threshold_values[threshold]) { out_count++; if (app_txBytes > out_last) { name_out = name; if (D) Log.d(TAG, "out - " + processname + " - " + humanReadableByteCount(app_txBytes, showbitsorbytes)); } } } hm_app_last_tx.put(processname, app_out); } if (name_in.length() > 0 && name_out.length() > 0 && name_in.equals(name_out)) { appnames_string = "" + name_in; int total_count = in_count + out_count; if (total_count > 2) appnames_string += " +" + (total_count - 2); } else { if (name_in.length() > 0) { appnames_string = "" + name_in; if (in_count > 1) appnames_string += " +" + (in_count - 1); } if (name_out.length() > 0) { if (name_in.length() > 0) appnames_string += " "; appnames_string += "" + name_out; if (out_count > 1) appnames_string += " +" + (out_count - 1); } } String divider = " | "; if (subtitle.length() == 0 || appnames_string.length() == 0) divider = ""; subtitle = appnames_string + divider + subtitle; } } } } else { title = res.getString(R.string.traffic_unsupported); } if (enabled) { modifyNotification(drawable, ticker, title, subtitle, i); } else { removeNotification(); } } // if (handler != null && !screenOff && enabled) handler.postDelayed(mRunnable, refresh); } catch (Exception e) { if (D) e.printStackTrace(); stopSelf(); } } }; private class MyPhoneStateListener extends PhoneStateListener { @Override public void onSignalStrengthsChanged(SignalStrength signalStrength) { super.onSignalStrengthsChanged(signalStrength); signalstrength = signalStrength.getGsmSignalStrength(); } }; private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { if (D) Log.d(TAG, "ACTION_SCREEN_OFF"); screenOff = true; } if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { if (D) Log.d(TAG, "ACTION_SCREEN_ON"); screenOff = false; int[] refresh_values = res.getIntArray(R.array.refresh_values); long refresh = (long) refresh_values[MainActivity.loadIntPref(context, MainActivity.REFRESH, MainActivity.REFRESH_DEFAULT)]; if (handler != null) handler.postDelayed(mRunnable, refresh); } } }; // @SuppressWarnings("deprecation") private void modifyNotification(int drawable, String ticker, String title, String subtitle, Intent i) { boolean showticker = MainActivity.loadBooleanPref(context, MainActivity.SHOWTICKER, MainActivity.SHOWTICKER_DEFAULT); if (!showticker) ticker = null; NotificationManager nmanager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); PendingIntent pi = PendingIntent.getActivity(this, 0, i, NOTIFICATION_ID); Notification n = null; if (Build.VERSION.SDK_INT < 11) { n = new Notification(drawable, ticker, System.currentTimeMillis()); n.flags |= Notification.FLAG_NO_CLEAR; n.setLatestEventInfo(this, title, subtitle, pi); } else { if (nb == null) { nb = new Notification.Builder(context); nb.setPriority(Notification.PRIORITY_LOW); nb.setAutoCancel(true); } nb.setSmallIcon(drawable); if (ticker != null) nb.setTicker(ticker); nb.setContentTitle(title); nb.setContentText(subtitle); nb.setContentIntent(pi); n = nb.build(); n.flags = Notification.FLAG_NO_CLEAR; } nmanager.notify(NOTIFICATION_ID, n); // if (mResultReceiver != null) { Bundle bundle = new Bundle(); bundle.putInt("drawable", drawable); bundle.putString("title", title); bundle.putString("subtitle", subtitle); mResultReceiver.send(0, bundle); } } private void removeNotification() { NotificationManager nmanager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); nmanager.cancel(NOTIFICATION_ID); if (mResultReceiver != null) { Bundle bundle = new Bundle(); bundle.putInt("drawable", R.drawable.ic_stat_zero); bundle.putString("title", ""); bundle.putString("subtitle", ""); mResultReceiver.send(0, bundle); } } // @SuppressWarnings("deprecation") private boolean isAirplaneModeOn(Context context) { if (Build.VERSION.SDK_INT < 17) { return Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) != 0; } else { return Settings.Global.getInt(context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0) != 0; } } private boolean getNetworkState(int type) { ConnectivityManager connect = null; connect = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (connect != null) { NetworkInfo result = connect.getNetworkInfo(type); if (result != null && result.isConnected()) { return true; } else { return false; } } else return false; } private String getIPAddress() { try { String ipv4; List<NetworkInterface> nilist = Collections.list(NetworkInterface.getNetworkInterfaces()); if (nilist.size() > 0) { for (NetworkInterface ni : nilist) { List<InetAddress> ialist = Collections.list(ni.getInetAddresses()); if (ialist.size() > 0) { for (InetAddress address : ialist) { if (!address.isLoopbackAddress() && InetAddressUtils.isIPv4Address(ipv4 = address.getHostAddress())) { return ipv4; } } } } } } catch (SocketException ex) { if (D) ex.printStackTrace(); } return ""; } private String getNetworkSubType() { String subtype = null; int networkType = tmanager.getNetworkType(); switch (networkType) { case 7: subtype = "1xRTT"; break; case 4: subtype = "CDMA"; break; case 2: subtype = "EDGE"; break; case 14: subtype = "eHRPD"; break; case 5: subtype = "EVDO rev. 0"; break; case 6: subtype = "EVDO rev. A"; break; case 12: subtype = "EVDO rev. B"; break; case 1: subtype = "GPRS"; break; case 8: subtype = "HSDPA"; break; case 10: subtype = "HSPA"; break; case 15: subtype = "HSPA+"; break; case 9: subtype = "HSUPA"; break; case 11: subtype = "iDen"; break; case 13: subtype = "LTE"; break; case 3: subtype = "UMTS"; break; case 0: subtype = "Unknown"; break; } return subtype; } private String humanReadableByteCount(long bytes, boolean si) { int unit = si ? 1000 : 1024; if (bytes < unit) return bytes + " B"; int exp = (int) (Math.log(bytes) / Math.log(unit)); String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (si ? "" : "i"); return String.format(Locale.US, "%.1f %sB", bytes / Math.pow(unit, exp), pre); } }