android Activity and a service with sms contentobserver - android

My app requirements
The application will have an activity and a service.
The service has a sms contentobserver.
After application installation the Service should run all the time irrespective of
application active or not
The registration and unregistration of contentobserver inside the service should
be controlled from the activity.
On uninstallation of the application the service should be destroyed.
I tried some code. In oncreate of the service i have done resgitartion of content observer
and ondestroy i unregistered it. I have used start and stop service from the activity.
But even after stop service the onchange method of the content observer is still getting called.
please let me know some sample code and the manifest definition of this service.
public class MyActivity extends ListActivity implements OnInitListener {
#Override
protected void onDestroy() {
super.onDestroy(); // let it be here as per the android TTS samples
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent sintent = new Intent(MyActivity.this,MyService.class);
MyActivity.this.startService(sintent);
}
private boolean SSMyservice() {
// TODO Auto-generated method stub
//stop service
Intent sintent = new Intent(MyActivity.this,MyService.class);
MyActivity.this.stopService(sintent);
//do some work
//start service again
MyActivity.this.startService(sintent); //start service again
return true;
} //importdata
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.TTSread:
return true;
case R.id.SSS:
SSMyservice();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Log.v(TAG,"option menu created");
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.layout.omenu, menu);
return true;
}
}
------------end MyActivity---------------------
----------------------------------
public class MyService extends Service {
protected SmsObserver smsSentObserver=null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate()
{
registersmsevent();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
super.onStartCommand(intent, flags, startId);
return Service.START_STICKY;
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unregistersmsevent();
}
public void registersmsevent() {
// TODO Auto-generated method stub
if(smsSentObserver == null)
{
final Uri SMS_STATUS_URI = Uri.parse("content://sms");
smsSentObserver = new SmsObserver(new Handler());
MyService.this.getContentResolver().registerContentObserver(SMS_STATUS_URI, true, smsSentObserver);
}
}
public void unregistersmsevent() {
if(smsSentObserver != null)
{
MyService.this.getContentResolver().unregisterContentObserver(smsSentObserver);
smsSentObserver = null;
}
}
public class SmsObserver extends ContentObserver {
Handler handler;
public SmsObserver(Handler handler) {
super(handler);
// TODO Auto-generated constructor stub
this.handler = handler;
}
#Override
public boolean deliverSelfNotifications() {
return true;
}
#Override
public void onChange(boolean selfChange) {
//my code........
super.onChange(selfChange);
}
}//End of class SmsObserver
}//end of service

I could fix the issue. This was a timing issue. Stopping service takes sometime.

Related

How to know when the services has ended

I want know when the service has ended, so I use BroadcastReceiver.
My service name is CheckNuevosAvisosIntentServices and I launch it in main.java (onCreate method) as:
Intent msgIntent = new Intent(Main.this, CheckNuevosAvisosIntentService.class);
msgIntent.putExtra("iteraciones", 1);
startService(msgIntent);
My manifest inside application tag.
<!-- Services -->
<service android:name="com.kirolm.instalacionesdep.services.CheckNuevosAvisosIntentService" />
In another fragment (HomeFragment) I use isMyServiceRunning method and BroadcastReceiver class:
private boolean isMyServiceRunning() {
ActivityManager manager = (ActivityManager) getActivity().getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (CheckNuevosAvisosIntentService.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
My Broadcast code is this:
public class ProgressReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(CheckNuevosAvisosIntentService.ACTION_PROGRESO)) {
Log.e("Testing", "The service is running...");
}
else if(intent.getAction().equals(CheckNuevosAvisosIntentService.ACTION_FIN) && isAdded()) {
Log.e("Testing", "The service has been ended");
}
}
}
and in creathe method (HomeFragment) I implements this:
if(!isMyServiceRunning()){
Log.e("Testing", "HomeFragment: The service is running");
}else{
Log.e("Testing", "HomeFragment: The servie stop");
}
CheckNuevosAvisosIntentServicescode:
public class CheckNuevosAvisosIntentService extends IntentService{
public static final String ACTION_PROGRESO = "com.kirolm.instalacionesdep.services.action.PROGRESO";
public static final String ACTION_FIN = "com.kirolm.instalacionesdep.services.action.FIN";
public CheckNuevosAvisosIntentService() {
super("CheckNuevosAvisosIntentService");
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
int iter = intent.getIntExtra("iteraciones", 0);
for(int i=1; i<=iter; i++) {
Intent bcIntent = new Intent();
bcIntent.setAction(ACTION_PROGRESO);
bcIntent.putExtra("progreso", i*10);
sendBroadcast(bcIntent);
}
buscaNuevasNoticasRss();
Intent bcIntent = new Intent();
bcIntent.setAction(ACTION_FIN);
sendBroadcast(bcIntent);
}
private void buscaNuevasNoticasRss() {
// TODO Auto-generated method stub
//This method checks. When this method finish I want finish my services.
}
}
When buscaNuevasNoticiasRssfinish, I want finish my services.
I receive when the service is running but I don't receive when the service stop.
Edited: HomeFragment (onCreat method)
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
ProgressReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.e("Testing", "HomeFragment. BoradcastReceiver. Dentro de onReceive");
if(intent.getAction().equals(CheckNuevosAvisosIntentService.ACTION_PROGRESO)) {
Log.e("Testing", "HomeFragment. BoradcastReceiver. The service is running...");
}
else if(intent.getAction().equals(CheckNuevosAvisosIntentService.ACTION_FIN) && isAdded()) {
Log.e("Testing", "HomeFragment. BoradcastReceiver. The service has been ended");
}
}
};
}
Override the onDestroy() method of your IntentService and send a broadcast to your receiver saying the service is destryed.
public class CheckNuevosAvisosIntentService extends IntentService{
//Your code
.......
.......
#Override
public void onDestroy() {
super.onDestroy();
sendBroadcast(new Intent(CheckNuevosAvisosIntentService.ACTION_FIN));
}
}
And create a BroadcastReceiver as an inner class of HomeFragment.
private class HomeFramgnet extends Fragment {
private ProgressReceiver progressReceiver;
Override
public void onCreate(Bundle savedInstanceState) {
progressReceiver = new ProgressReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(CheckNuevosAvisosIntentService.ACTION_PROGRESO);
intentFilter.addAction(CheckNuevosAvisosIntentService.ACTION_FIN);
registerReceiver(progressReceiver, intentFilter);
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(progressReceiver);;
}
class ProgressReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.e("Testing", "HomeFragment. BoradcastReceiver. Dentro de onReceive");
if (intent.getAction().equals(CheckNuevosAvisosIntentService.ACTION_PROGRESO)) {
Log.e("Testing", "HomeFragment. BoradcastReceiver. The service is running...");
} else if (intent.getAction().equals(CheckNuevosAvisosIntentService.ACTION_FIN) && isAdded()) {
Log.e("Testing", "HomeFragment. BoradcastReceiver. The service has been ended");
}
}
}
}

How to know if contact / phonebook list or database is updated android?

I have implemented a sync adapter which sends all my contacts over the server.
But now I am faced with the issue that how the system can respond if it contact list has been updated.
I used the content observer to find out but it seems to be limited to activity lifecycle.
This is my code:
class MyObserver extends ContentObserver {
public MyObserver(Handler handler) {
super(handler);
}
#Override
public void onChange(boolean selfChange) {
this.onChange(selfChange, null);
}
#Override
public void onChange(boolean selfChange, Uri uri) {
Log.e("change ", "contact");
}
}
To register it:
context.getContentResolver().registerContentObserver(
Contacts.CONTENT_URI, false, new MyObserver(new Handler()));
Isn't there any broadcast to notify about it.
Or I have to make a service for it.
For that you have to run a service as follows
public class ContactService extends Service {
MyObserver observer;
#Override
public void onDestroy() {
// TODO Auto-generated method stub
getContentResolver().unregisterContentObserver(observer);
super.onDestroy();
}
#Override
public void onCreate() {
System.out.println("service created");
observer=new MyObserver(new Handler());
// TODO Auto-generated method stub
getContentResolver().registerContentObserver(Contacts.CONTENT_URI, false, observer);
super.onCreate();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Then you will notify when ever contact data is changed.

How to pass context var when I use IntentService in BroadcastReceiver?

I need to use Context object in the function killCall, but I don't know how to pass the Context object to KillCall, could you help me? Thanks!
public class ReceiverCall extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Intent msgIntent = new Intent(context, InternetServerCall.class);
context.startService(msgIntent);
}
}
public class InternetServerCall extends IntentService{
public InternetServerCall(String name) {
super("InternetServerCall");
// TODO Auto-generated constructor stub
}
#Override
protected void onHandleIntent(Intent intent) {
HandleCall.killCall(context); //Need context
}
}
public class HandleCall {
public static boolean killCall(Context context) {
try {
....
Toast.makeText(context, "PhoneStateReceiver kill incoming call Ok",Toast.LENGTH_SHORT).show();
} catch (Exception ex) { // Many things can go wrong with reflection calls
return false;
}
return true;
}
}
You can get Context into InternetServerCall by doing InternetServerCall.this. And this is because all Android Components overrides Context class, on of them is IntentService.
You can also use getApplicationContext() into IntentService to get context. You can read my another similar answer Pass a Context an IntentService.
But you can not display Toast from IntentService directly, because it needs UI thread but IntentService runs into background thread. You need to use Handler to show Toast, like below example
public class TestService extends IntentService {
private Handler handler;
public TestService(String name) {
super(name);
// TODO Auto-generated constructor stub
}
public TestService () {
super("TestService");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler = new Handler();
return super.onStartCommand(intent, flags, startId);
}
#Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Handling Intent..", Toast.LENGTH_LONG).show();
}
});
}
}
An IntentService is subclass of Context so you can pass in this:
#Override
protected void onHandleIntent(Intent intent) {
HandleCall.killCall(this);
}

android iIllegal argument exception service not registered on unbind

Ok I have looked at a lot of questions but unable to find a solution...
Keep getting the "java.lang.IllegalArgumentException: Service not registered:"
Note that the "onServiceConnected" method of ServiceConnection is NOT being called....
This is what I have (ignore all the Log.e's.. I dont really know anyother way to find out which functions are called without debugging):
How service is declared in manifest:
<service android:name="com.example.servicestry.MyService" android:enabled="true"/>
My activity
public class MainActivity extends Activity {
MyService mBoundService=null;
public ServiceConnection mConnection;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mConnection=new ServiceConnection(){
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
Log.e("onserviceconnected","");
mBoundService = ((MyService.LocalBinder)service).getService();
Toast.makeText(getApplicationContext(), "local service connected",Toast.LENGTH_SHORT).show();
}
#Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
Log.e("onservicedisconnected","");
mBoundService=null;
Toast.makeText(getApplicationContext(), "local service disconnected",Toast.LENGTH_SHORT).show();
}
};
this.doBindService();
Timer timer=new Timer();
timer.schedule(new RemindTask(), 3000);
}
public void doUnbindService(){
Log.e("doUnbindService","");
unbindService(mConnection);
}
public void doBindService(){
boolean b=bindService(new Intent(this,MyService.class),mConnection, Context.BIND_AUTO_CREATE);
if(b){
Toast.makeText(this, "binding service", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(this, "binding service FAILED", Toast.LENGTH_SHORT).show();
}
this.doUnbindService();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public class RemindTask extends TimerTask{
#Override
public void run() {
// TODO Auto-generated method stub
//Toast.makeText(getApplicationContext(), "this is runner", Toast.LENGTH_SHORT).show();
Log.e("runner run","r");
doUnbindService();
}
}
}
My service class
package com.example.servicestry;
public class MyService extends Service{
LocalBinder mBinder= new LocalBinder();;
#Override
public void onCreate(){
super.onCreate();
Log.e("binder create","ASDF");
}
#Override
public int onStartCommand(Intent i,int flag, int startId){
Log.e("on start command","D");
return super.onStartCommand(i, flag, startId);
}
#Override
public void onDestroy(){
super.onDestroy();
Log.e("DEST","");
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.e("onbind","ASDF");
return mBinder;
}
public class LocalBinder extends Binder {
MyService getService() {
return MyService.this;
}
}
}

what happens when a service is started multiple times

I have created a simple service which will increment a counter and log it.
public class AudioService extends Service {
int i=0;
private final IAudioInterface.Stub mBinder = new IAudioInterface.Stub() {
public int getI()
{
return i;
}
};
#Override
public IBinder onBind(Intent intent) {
Log.d("onBind from service","****");
return mBinder;
}
#Override
public void onCreate() {
super.onCreate();
Log.d("onCreate from service","***");
Log.d("i=","="+i);
i=i+1;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("OnDestroy Called from service","***");
}
public void onStartCommand(Intent intent, int startId) {
super.onStart(intent, startId);
Log.d("onStartCommand from service","***");
}
#Override
public boolean onUnbind(Intent intent) {
Log.d("onUnbind from service","***");
return super.onUnbind(intent);
}
i am incrementing the i value in the oncreate method of he service.
The Client Activity is as shown below
public class AidlInterfaceServiceActivity extends Activity implements OnClickListener {
/** Called when the activity is first created. */
private static final String TAG = "Audio:Service";
IAudioInterface mService = null;
boolean connected = false;
ServiceConnection mConnection = new ServiceConnection(){
public void onServiceConnected(ComponentName arg0, IBinder service) {
// TODO Auto-generated method stub
connected = true;
Log.d("Service connected","**");
mService = IAudioInterface.Stub.asInterface(service);
try {
Log.d("i from client","="+mService.getI());
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
Log.i(TAG, "Service disConnected");
connected = false;
mService= null;
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d("on created ","**********");
Intent music = new Intent();
music.setClass(this,AudioService.class);
startService(music);
bindService(music, mConnection, Context.BIND_AUTO_CREATE);
}
The AIDL file is as below
interface IAudioInterface
{
int getI();
}
The problem is when i run the client activity every time the value of i is "0".
i value is not getting incremented.
I have these queries.
1.what happens when the service is started multiple time.
2.what happens when the service is bounded multiple times.
3.what happens to the data members inside the service class when it is started multiple times.Does those data members get reinitialized.
I am really confused ..Any one please help.
Does it help if you declare your counter variable as static?

Categories

Resources