Java tutorial
/** * Newtifry for Android. * * Copyright 2011 Daniel Foote * * 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. */ package com.newtifry.android; import java.util.ArrayList; import java.util.List; import com.newtifry.android.database.NewtifryAccount; import com.newtifry.android.database.NewtifryMessage; import com.newtifry.android.database.NewtifrySource; import com.newtifry.android.R; import static com.newtifry.android.CommonUtilities.TAG; import android.annotation.SuppressLint; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Build; import android.os.IBinder; import android.support.v4.app.NotificationCompat; import android.util.Log; public class NewtificationService2 extends Service { private NotificationManager mNotificationManager = null; private static int NOTIFICATION_ID = 0xdeadbeef; private Bitmap bigNotificationIcon; @Override public IBinder onBind(Intent arg0) { return null; } @SuppressLint("InlinedApi") public void onCreate() { super.onCreate(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { int height = (int) this.getResources().getDimension(android.R.dimen.notification_large_icon_height); int width = (int) this.getResources().getDimension(android.R.dimen.notification_large_icon_width); this.bigNotificationIcon = Bitmap.createScaledBitmap( BitmapFactory.decodeResource(this.getResources(), R.drawable.big_icon_notification), width, height, false); } mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); } /* public boolean globalOrOverrideBoolean( int setting, SharedPreferences preferences, NewtifrySource source, boolean defaultValue ) { if( source.getUseGlobalNotification() ) { // Use the global setting for this notification. return preferences.getBoolean(getString(setting), defaultValue); } else { // Determine the setting, and then return the appropriate setting. if( R.string.playRingtone == setting ) { return source.getRingtone(); } else if( R.string.useNotifierPro == setting ) { return source.getNotifierPro(); } else if( R.string.notification == setting ) { return source.getNotification(); } else if( R.string.vibrateNotify == setting ) { return source.getVibrate(); } else if( R.string.ledFlash == setting ) { return source.getLedFlash(); } else if( R.string.speakMessage == setting ) { return source.getSpeakMessage(); } } return defaultValue; } */ /* public String globalOrOverrideString( int setting, SharedPreferences preferences, NewtifrySource source, String defaultValue ) { if( source.getUseGlobalNotification() ) { // Use the global setting for this notification. return preferences.getString(getString(setting), defaultValue); } else { // Determine the setting, and then return the appropriate setting. if( R.string.choosenNotification == setting ) { return source.getCustomRingtone(); } } return defaultValue; } */ public void onStart(Intent intent, int startId) { super.onStart(intent, startId); // On null intent, give up. if (intent == null) { return; } if (Preferences.getMasterEnable(this) == false) { Log.d(TAG, "Master enable is off, so not doing anything."); return; } int unreadMessages = 0; int unreadSources = 0; NewtifrySource uniqueUnreadSource = null; List<NewtifryAccount> accounts = NewtifryAccount.FACTORY.listAll(this); List<String> inboxStyleStringArray = new ArrayList<String>(); for (NewtifryAccount account : accounts) { List<NewtifrySource> sources = NewtifrySource.FACTORY.listAll(this, account.getAccountName()); for (NewtifrySource source : sources) { int unread = NewtifryMessage.FACTORY.countUnread(this, source); unreadMessages += unread; if (unread != 0) { unreadSources++; uniqueUnreadSource = source; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { String bigContentText = source.getTitle() + " : " + String.format(getString(R.string.notificationFormat), unread); inboxStyleStringArray.add(bigContentText); //inboxStyle.addLine(bigContentText); } } } } // try to read account less (aka serverless) unred messages // get Newtifry source long newtifrySourceId = Preferences.getNewtifrySource(this); if (newtifrySourceId != 0L) { NewtifrySource newtifrySource = NewtifrySource.FACTORY.getByServerId(this, newtifrySourceId); int unread = NewtifryMessage.FACTORY.countUnread(this, newtifrySource); unreadMessages += unread; if (unread != 0) { unreadSources++; uniqueUnreadSource = newtifrySource; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { String bigContentText = newtifrySource.getTitle() + " : " + String.format(getString(R.string.notificationFormat), unread); inboxStyleStringArray.add(bigContentText); //inboxStyle.addLine(bigContentText); } } } if (unreadMessages == 0) { // clear notification mNotificationManager.cancel(NOTIFICATION_ID); return; } Long messageId = intent.getLongExtra("messageId", 0); NewtifryMessage message = NewtifryMessage.FACTORY.get(this, messageId); // If the message is NULL, then we've been passed an invalid message - return. if (message == null) { Log.d(TAG, "Message " + messageId + " not found, so not doing anything."); return; } // NEW : always update : update or create new notification NewtifyDecision decision = NewtifyDecision.shouldNotify(this, message); if (decision.getShouldNotify()) { // if( globalOrOverrideBoolean(R.string.useNotifierPro, settings, message.getSource(), false) ) { if (Preferences.getUseNotifierPro(message.getSource(), this)) { // for notifierPro Intent notifierProIntent = new Intent("com.productigeeky.NOTIFICATION"); notifierProIntent.putExtra("title", message.getTitle()); notifierProIntent.putExtra("subtitle", message.getMessage()); notifierProIntent.putExtra("action", "com.newtifry.android.MessageList"); getBaseContext().sendBroadcast(notifierProIntent); return; // that's all } NotificationCompat.Builder notification = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.icon_statusbar).setOnlyAlertOnce(true) .setWhen(System.currentTimeMillis()).setAutoCancel(true); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { notification.setLargeIcon(bigNotificationIcon); } /* // Creates an explicit intent for an Activity in your app Intent resultIntent = new Intent(this, MessageList.class); // TODO : add extra to show if App is visible or not // TODO : add info to indicate that the messageList is called from notification resultIntent.putExtra("app_visible", NewtifryApp.isAppVisible()); resultIntent.putExtra("from_notification", true); // The stack builder object will contain an artificial back stack for the // started Activity. // This ensures that navigating backward from the Activity leads out of // your application to the Home screen. TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); // Adds the back stack for the Intent (but not the Intent itself) stackBuilder.addParentStack(Newtifry.class); // Adds the Intent that starts the Activity to the top of the stack stackBuilder.addNextIntent(resultIntent); PendingIntent resultPendingIntent = stackBuilder.getPendingIntent( 0, PendingIntent.FLAG_UPDATE_CURRENT ); */ Intent notificationIntent = new Intent(this, MessageList.class); notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); notificationIntent.putExtra("from_notification", true); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); notification.setContentIntent(contentIntent); // if( globalOrOverrideBoolean(R.string.vibrateNotify, settings, message.getSource(), true) ) { if (Preferences.getVibrateNotify(message.getSource(), this)) { long[] vibratePattern = { 0, 500, 250, 500 }; notification.setVibrate(vibratePattern); } // if( globalOrOverrideBoolean(R.string.ledFlash, settings, message.getSource(), true) ) { if (Preferences.getLedFlash(this)) { // if( settings.getBoolean(getString(R.string.fastLedFlash), false) ) { if (Preferences.getFastLedFlash(this)) { // Special "fast flash" mode for phones with poor notification LEDs. // Ie, my G2 that flashes very slowly so it's hard to notice. notification.setLights(0xff00ff00, 300, 300); } else { // Use the default device flash notifications. notification.setLights(0xff00ff00, 300, 1000); // notification.defaults |= Notification.DEFAULT_LIGHTS; } } // If we're speaking, dispatch the message to the speaking service. // if( globalOrOverrideBoolean(R.string.speakMessage, settings, message.getSource(), true) ) if (Preferences.getSpeakMessage(message.getSource(), this)) { Intent intentData = new Intent(getBaseContext(), SpeakService.class); Log.d(TAG, "Speaking text: " + decision.getOutputMessage()); intentData.putExtra("text", decision.getOutputMessage()); startService(intentData); } else { String tone = Preferences.getRingtone(message.getSource(), this); Log.d(TAG, "Notification selected by user: " + tone); if (tone != null) { notification.setSound(Uri.parse(tone)); } } // now build text // for each source // get unread messages // add text for this source NotificationCompat.InboxStyle inboxStyle = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { inboxStyle = new NotificationCompat.InboxStyle(); inboxStyle.setBigContentTitle(getString(R.string.app_name)); // Moves the big view style object into the notification object. for (String str : inboxStyleStringArray) { inboxStyle.addLine(str); } notification.setStyle(inboxStyle); } if (unreadMessages == 1 || unreadSources == 1) { notification.setContentTitle(getString(R.string.app_name) + " : " + uniqueUnreadSource.getTitle()); notification.setContentText(String.format(getString(R.string.notificationFormat), unreadMessages)); } else { notification.setContentTitle(getString(R.string.app_name)); notification.setContentText(String.format(getString(R.string.notificationFormat), unreadMessages)); } notification.setNumber(unreadMessages); mNotificationManager.notify(NOTIFICATION_ID, notification.build()); } /* NotificationCompat.Builder b = new NotificationCompat.Builder(c); b.setNumber(g_push.Counter) .setLargeIcon(BitmapFactory.decodeResource(c.getResources(), R.drawable.list_avatar)) .setSmallIcon(R.drawable.ic_stat_example) .setAutoCancel(true) .setContentTitle(pushCount > 1 ? c.getString(R.string.stat_messages_title) + pushCount : title) .setContentText(pushCount > 1 ? push.ProfileID : mess) .setWhen(g_push.Timestamp) .setContentIntent(PendingIntent.getActivity(c, 0, it, PendingIntent.FLAG_UPDATE_CURRENT)) .setDeleteIntent(PendingIntent.getBroadcast(c, 0, new Intent(ACTION_CLEAR_NOTIFICATION), PendingIntent.FLAG_CANCEL_CURRENT)) .setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE) .setSound(Uri.parse(prefs.getString( SharedPreferencesID.PREFERENCE_ID_PUSH_SOUND_URI, "android.resource://ru.mail.mailapp/raw/new_message_bells"))); */ /* // Determine our action. String operation = intent.getStringExtra("operation"); if( operation.equals("newtifry") ) { // Ok, let's start notifying! Notification notification = this.setLatestEventInfo(message.getSource(), message); // Now, other notification methods. if( globalOrOverrideBoolean(R.string.vibrateNotify, settings, message.getSource(), true) ) { notification.defaults |= Notification.DEFAULT_VIBRATE; } if( globalOrOverrideBoolean(R.string.ledFlash, settings, message.getSource(), true) ) { if( settings.getBoolean(getString(R.string.fastLedFlash), false) ) { // Special "fast flash" mode for phones with poor notification LEDs. // Ie, my G2 that flashes very slowly so it's hard to notice. notification.ledARGB = 0xff00ff00; notification.ledOnMS = 300; notification.ledOffMS = 1000; notification.flags |= Notification.FLAG_SHOW_LIGHTS; } else { // Use the default device flash notifications. notification.defaults |= Notification.DEFAULT_LIGHTS; } } // If we're speaking, dispatch the message to the speaking service. if( globalOrOverrideBoolean(R.string.speakMessage, settings, message.getSource(), true) ) { Intent intentData = new Intent(getBaseContext(), SpeakService.class); Log.d(TAG, "Speaking text: " + decision.getOutputMessage()); intentData.putExtra("text", decision.getOutputMessage()); startService(intentData); } else { if( globalOrOverrideBoolean(R.string.playRingtone, settings, message.getSource(), true) ) { String tone = globalOrOverrideString(R.string.choosenNotification, settings, message.getSource(), ""); Log.d(TAG, "Notification selected by user: " + tone); if( tone.equals("") ) { // Set the default notification tone. notification.defaults |= Notification.DEFAULT_SOUND; } else { // Load the notification and add it. notification.sound = Uri.parse(tone); } } } // Put the notification in the tray. Use the source's local ID to identify it. this.notificationManager.notify(message.getSource().getNotificationId(), notification); } } else if( operation.equals("update") ) { // Clear the notifications for a given source - if there are no unread messages. NewtifrySource source = NewtifrySource.FACTORY.get(this, intent.getLongExtra("sourceId", 0)); if( source != null ) { this.updateNotificationFor(source); } else { // Do it for all sources. List<NewtifryAccount> accounts = NewtifryAccount.FACTORY.listAll(this); for( NewtifryAccount account: accounts ) { List<NewtifrySource> sources = NewtifrySource.FACTORY.listAll(this, account.getAccountName()); for( NewtifrySource thisSource: sources ) { this.updateNotificationFor(thisSource); } } } } */ return; } }