kod usługi ale można użyć dowolnej konstrukcji z własnym kontekstem ale usługa jest tu najbardziej na miejscu
public class Tajniak extends Service {
public static String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
private final Messenger mMessenger = new Messenger(new reciveHandler());
private final Handler handler = new Handler();
private Observer mObserver;
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
@Override
public void onCreate() {
super.onCreate();
mObserver = new Observer(handler, getApplicationContext());
mObserver.loadList(/*tu lista w postaci String[]*/);
getApplicationContext().registerReceiver(Broadcast, getBroadcastFilter());
}
@Override
public void onDestroy() {
super.onDestroy();
try {
getApplicationContext().unregisterReceiver(Broadcast);
} catch (IllegalArgumentException e) {
Log.w("Service", "Unregister receiver");
}
if (mObserver.isRegister()) {
getApplicationContext().getContentResolver().unregisterContentObserver(mObserver);
Log.w("Service", "Register observer found");
}
}
private IntentFilter getBroadcastFilter() {
final IntentFilter filter = new IntentFilter();
filter.addAction(SMS_RECEIVED);
return filter;
}
private final BroadcastReceiver Broadcast = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(SMS_RECEIVED)) {
final Bundle bundle = intent.getExtras();
if (bundle != null) {
final Object[] pdusObj = (Object[]) bundle.get("pdus");
for (int i = 0; i < pdusObj.length; i++) {
mObserver.addAdress(SmsMessage.createFromPdu((byte[]) pdusObj[i]).getOriginatingAddress());
}
}
}
}
};
private class reciveHandler extends Handler {
@Override
public void handleMessage(Message message) {
}
}
}
oraz klasa pełniąca funkcje mózgu całej operacji, do poprawnego działania konieczne jest załadowany listy blokowanych adresów korzystając z funkcji loadList();
public class Observer extends ContentObserver {
public static final String CONTENT_URI = "content://sms/";
public static final String CONTENT_WHERE = "address = '%s' and read = 0";
private final List<String> adress = new ArrayList<String>();
private final Uri uri = Uri.parse(CONTENT_URI);
private Context context;
private String[] blockList;
private boolean register = false;
public Observer(Handler handler, Context context) {
super(handler);
this.context = context;
}
public boolean isRegister() {
return register;
}
public void loadList(String[] list) {
blockList = list;
Arrays.sort(blockList);
}
public void addAdress(String input) {
if (Arrays.binarySearch(blockList, input) >= 0) {
if (adress.isEmpty()) {
context.getContentResolver().registerContentObserver(uri, true, this);
register = true;
}
adress.add(input);
}
}
@Override
public void onChange(boolean arg0) {
super.onChange(arg0);
if (!adress.isEmpty()) {
for (int i = (adress.size() - 1); i >= 0; i--) {
if (context.getContentResolver().delete(uri, String.format(CONTENT_WHERE, adress.get(i)), null) != 0) {
adress.remove(i);
}
}
if (adress.isEmpty()) {
context.getContentResolver().unregisterContentObserver(this);
register = false;
}
}
}
}
dobrze jest dodać do manifestu usługi:
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
nie jest to konieczne do działania ale dzięki temu odfiltrowanie Intent-ów przesłanych przez BroadcastReceiver nie będzie wymagało budzenia procesu
zapomniał bym o startForeground, ale to naprawdę nie jest konieczne, jak by jednak ktoś bardzo chciał to wygląda to tak:
włącza
private void startFirst() {
final Notification mNotification = new Notification(R.drawable.service_icon, getText(R.string.service_ticker), System.currentTimeMillis());
mNotification.setLatestEventInfo(Tajniak.this, getText(R.string.service_label), getText(R.string.service_text), PendingIntent.getActivity(Tajniak.this, 0, new Intent(this, myActivity.class), 0));
mNotification.flags = Notification.FLAG_FOREGROUND_SERVICE;
startForeground(R.string.service_id, mNotification);
}
wyłącza
private void stopFirst() {
stopForeground(true);
}
konieczne jest zdefiniowanie zasobów:
service_ticker
service_label
service_text
oraz dodanie ikony:
service_icon
oraz identyfikatora powiadomienia jako zasobu:
service_id
oraz akcje w momencie kliknięcia powiadomienia w tym przypadku uruchamianie myActivity.class (jakaś istniejąca aplikacji aktywność)